c11 safe string handling support
[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->sw_if_index = ntohl (mp->sw_if_index);
2148       vam->result_ready = 1;
2149     }
2150   vam->regenerate_interface_table = 1;
2151 }
2152
2153 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2154   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   vat_json_node_t node;
2158
2159   vat_json_init_object (&node);
2160   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2161   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2162                             ntohl (mp->sw_if_index));
2163
2164   vat_json_print (vam->ofp, &node);
2165   vat_json_free (&node);
2166
2167   vam->retval = ntohl (mp->retval);
2168   vam->result_ready = 1;
2169 }
2170
2171 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2172   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2173 {
2174   vat_main_t *vam = &vat_main;
2175   i32 retval = ntohl (mp->retval);
2176   if (vam->async_mode)
2177     {
2178       vam->async_errors += (retval < 0);
2179     }
2180   else
2181     {
2182       vam->retval = retval;
2183       vam->sw_if_index = ntohl (mp->sw_if_index);
2184       vam->result_ready = 1;
2185     }
2186 }
2187
2188 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2189   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   vat_json_node_t node;
2193
2194   vat_json_init_object (&node);
2195   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2196   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2197
2198   vat_json_print (vam->ofp, &node);
2199   vat_json_free (&node);
2200
2201   vam->retval = ntohl (mp->retval);
2202   vam->result_ready = 1;
2203 }
2204
2205 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2206   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   i32 retval = ntohl (mp->retval);
2210   if (vam->async_mode)
2211     {
2212       vam->async_errors += (retval < 0);
2213     }
2214   else
2215     {
2216       vam->retval = retval;
2217       vam->result_ready = 1;
2218     }
2219 }
2220
2221 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2222   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   vat_json_node_t node;
2226
2227   vat_json_init_object (&node);
2228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2229   vat_json_object_add_uint (&node, "fwd_entry_index",
2230                             clib_net_to_host_u32 (mp->fwd_entry_index));
2231
2232   vat_json_print (vam->ofp, &node);
2233   vat_json_free (&node);
2234
2235   vam->retval = ntohl (mp->retval);
2236   vam->result_ready = 1;
2237 }
2238
2239 u8 *
2240 format_lisp_transport_protocol (u8 * s, va_list * args)
2241 {
2242   u32 proto = va_arg (*args, u32);
2243
2244   switch (proto)
2245     {
2246     case 1:
2247       return format (s, "udp");
2248     case 2:
2249       return format (s, "api");
2250     default:
2251       return 0;
2252     }
2253   return 0;
2254 }
2255
2256 static void vl_api_one_get_transport_protocol_reply_t_handler
2257   (vl_api_one_get_transport_protocol_reply_t * mp)
2258 {
2259   vat_main_t *vam = &vat_main;
2260   i32 retval = ntohl (mp->retval);
2261   if (vam->async_mode)
2262     {
2263       vam->async_errors += (retval < 0);
2264     }
2265   else
2266     {
2267       u32 proto = mp->protocol;
2268       print (vam->ofp, "Transport protocol: %U",
2269              format_lisp_transport_protocol, proto);
2270       vam->retval = retval;
2271       vam->result_ready = 1;
2272     }
2273 }
2274
2275 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2276   (vl_api_one_get_transport_protocol_reply_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   vat_json_node_t node;
2280   u8 *s;
2281
2282   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2283   vec_add1 (s, 0);
2284
2285   vat_json_init_object (&node);
2286   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2287   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2288
2289   vec_free (s);
2290   vat_json_print (vam->ofp, &node);
2291   vat_json_free (&node);
2292
2293   vam->retval = ntohl (mp->retval);
2294   vam->result_ready = 1;
2295 }
2296
2297 static void vl_api_one_add_del_locator_set_reply_t_handler
2298   (vl_api_one_add_del_locator_set_reply_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   i32 retval = ntohl (mp->retval);
2302   if (vam->async_mode)
2303     {
2304       vam->async_errors += (retval < 0);
2305     }
2306   else
2307     {
2308       vam->retval = retval;
2309       vam->result_ready = 1;
2310     }
2311 }
2312
2313 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2314   (vl_api_one_add_del_locator_set_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vat_json_node_t node;
2318
2319   vat_json_init_object (&node);
2320   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2321   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2322
2323   vat_json_print (vam->ofp, &node);
2324   vat_json_free (&node);
2325
2326   vam->retval = ntohl (mp->retval);
2327   vam->result_ready = 1;
2328 }
2329
2330 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2331   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   i32 retval = ntohl (mp->retval);
2335   if (vam->async_mode)
2336     {
2337       vam->async_errors += (retval < 0);
2338     }
2339   else
2340     {
2341       vam->retval = retval;
2342       vam->sw_if_index = ntohl (mp->sw_if_index);
2343       vam->result_ready = 1;
2344     }
2345   vam->regenerate_interface_table = 1;
2346 }
2347
2348 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2349   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   vat_json_node_t node;
2353
2354   vat_json_init_object (&node);
2355   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2356   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2357
2358   vat_json_print (vam->ofp, &node);
2359   vat_json_free (&node);
2360
2361   vam->retval = ntohl (mp->retval);
2362   vam->result_ready = 1;
2363 }
2364
2365 static void vl_api_vxlan_offload_rx_reply_t_handler
2366   (vl_api_vxlan_offload_rx_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   i32 retval = ntohl (mp->retval);
2370   if (vam->async_mode)
2371     {
2372       vam->async_errors += (retval < 0);
2373     }
2374   else
2375     {
2376       vam->retval = retval;
2377       vam->result_ready = 1;
2378     }
2379 }
2380
2381 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2382   (vl_api_vxlan_offload_rx_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t node;
2386
2387   vat_json_init_object (&node);
2388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389
2390   vat_json_print (vam->ofp, &node);
2391   vat_json_free (&node);
2392
2393   vam->retval = ntohl (mp->retval);
2394   vam->result_ready = 1;
2395 }
2396
2397 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2398   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   i32 retval = ntohl (mp->retval);
2402   if (vam->async_mode)
2403     {
2404       vam->async_errors += (retval < 0);
2405     }
2406   else
2407     {
2408       vam->retval = retval;
2409       vam->sw_if_index = ntohl (mp->sw_if_index);
2410       vam->result_ready = 1;
2411     }
2412 }
2413
2414 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2415   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t node;
2419
2420   vat_json_init_object (&node);
2421   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2422   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2423
2424   vat_json_print (vam->ofp, &node);
2425   vat_json_free (&node);
2426
2427   vam->retval = ntohl (mp->retval);
2428   vam->result_ready = 1;
2429 }
2430
2431 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2432   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   i32 retval = ntohl (mp->retval);
2436   if (vam->async_mode)
2437     {
2438       vam->async_errors += (retval < 0);
2439     }
2440   else
2441     {
2442       vam->retval = retval;
2443       vam->sw_if_index = ntohl (mp->sw_if_index);
2444       vam->result_ready = 1;
2445     }
2446   vam->regenerate_interface_table = 1;
2447 }
2448
2449 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2450   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t node;
2454
2455   vat_json_init_object (&node);
2456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2457   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2458
2459   vat_json_print (vam->ofp, &node);
2460   vat_json_free (&node);
2461
2462   vam->retval = ntohl (mp->retval);
2463   vam->result_ready = 1;
2464 }
2465
2466 static void vl_api_gre_add_del_tunnel_reply_t_handler
2467   (vl_api_gre_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   i32 retval = ntohl (mp->retval);
2471   if (vam->async_mode)
2472     {
2473       vam->async_errors += (retval < 0);
2474     }
2475   else
2476     {
2477       vam->retval = retval;
2478       vam->sw_if_index = ntohl (mp->sw_if_index);
2479       vam->result_ready = 1;
2480     }
2481 }
2482
2483 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2484   (vl_api_gre_add_del_tunnel_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   vat_json_node_t node;
2488
2489   vat_json_init_object (&node);
2490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2491   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2492
2493   vat_json_print (vam->ofp, &node);
2494   vat_json_free (&node);
2495
2496   vam->retval = ntohl (mp->retval);
2497   vam->result_ready = 1;
2498 }
2499
2500 static void vl_api_create_vhost_user_if_reply_t_handler
2501   (vl_api_create_vhost_user_if_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   i32 retval = ntohl (mp->retval);
2505   if (vam->async_mode)
2506     {
2507       vam->async_errors += (retval < 0);
2508     }
2509   else
2510     {
2511       vam->retval = retval;
2512       vam->sw_if_index = ntohl (mp->sw_if_index);
2513       vam->result_ready = 1;
2514     }
2515   vam->regenerate_interface_table = 1;
2516 }
2517
2518 static void vl_api_create_vhost_user_if_reply_t_handler_json
2519   (vl_api_create_vhost_user_if_reply_t * mp)
2520 {
2521   vat_main_t *vam = &vat_main;
2522   vat_json_node_t node;
2523
2524   vat_json_init_object (&node);
2525   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2526   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2527
2528   vat_json_print (vam->ofp, &node);
2529   vat_json_free (&node);
2530
2531   vam->retval = ntohl (mp->retval);
2532   vam->result_ready = 1;
2533 }
2534
2535 static void vl_api_dns_resolve_name_reply_t_handler
2536   (vl_api_dns_resolve_name_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   i32 retval = ntohl (mp->retval);
2540   if (vam->async_mode)
2541     {
2542       vam->async_errors += (retval < 0);
2543     }
2544   else
2545     {
2546       vam->retval = retval;
2547       vam->result_ready = 1;
2548
2549       if (retval == 0)
2550         {
2551           if (mp->ip4_set)
2552             clib_warning ("ip4 address %U", format_ip4_address,
2553                           (ip4_address_t *) mp->ip4_address);
2554           if (mp->ip6_set)
2555             clib_warning ("ip6 address %U", format_ip6_address,
2556                           (ip6_address_t *) mp->ip6_address);
2557         }
2558       else
2559         clib_warning ("retval %d", retval);
2560     }
2561 }
2562
2563 static void vl_api_dns_resolve_name_reply_t_handler_json
2564   (vl_api_dns_resolve_name_reply_t * mp)
2565 {
2566   clib_warning ("not implemented");
2567 }
2568
2569 static void vl_api_dns_resolve_ip_reply_t_handler
2570   (vl_api_dns_resolve_ip_reply_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   i32 retval = ntohl (mp->retval);
2574   if (vam->async_mode)
2575     {
2576       vam->async_errors += (retval < 0);
2577     }
2578   else
2579     {
2580       vam->retval = retval;
2581       vam->result_ready = 1;
2582
2583       if (retval == 0)
2584         {
2585           clib_warning ("canonical name %s", mp->name);
2586         }
2587       else
2588         clib_warning ("retval %d", retval);
2589     }
2590 }
2591
2592 static void vl_api_dns_resolve_ip_reply_t_handler_json
2593   (vl_api_dns_resolve_ip_reply_t * mp)
2594 {
2595   clib_warning ("not implemented");
2596 }
2597
2598
2599 static void vl_api_ip_address_details_t_handler
2600   (vl_api_ip_address_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   static ip_address_details_t empty_ip_address_details = { {0} };
2604   ip_address_details_t *address = NULL;
2605   ip_details_t *current_ip_details = NULL;
2606   ip_details_t *details = NULL;
2607
2608   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2609
2610   if (!details || vam->current_sw_if_index >= vec_len (details)
2611       || !details[vam->current_sw_if_index].present)
2612     {
2613       errmsg ("ip address details arrived but not stored");
2614       errmsg ("ip_dump should be called first");
2615       return;
2616     }
2617
2618   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2619
2620 #define addresses (current_ip_details->addr)
2621
2622   vec_validate_init_empty (addresses, vec_len (addresses),
2623                            empty_ip_address_details);
2624
2625   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2626
2627   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2628   address->prefix_length = mp->prefix_length;
2629 #undef addresses
2630 }
2631
2632 static void vl_api_ip_address_details_t_handler_json
2633   (vl_api_ip_address_details_t * mp)
2634 {
2635   vat_main_t *vam = &vat_main;
2636   vat_json_node_t *node = NULL;
2637   struct in6_addr ip6;
2638   struct in_addr ip4;
2639
2640   if (VAT_JSON_ARRAY != vam->json_tree.type)
2641     {
2642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2643       vat_json_init_array (&vam->json_tree);
2644     }
2645   node = vat_json_array_add (&vam->json_tree);
2646
2647   vat_json_init_object (node);
2648   if (vam->is_ipv6)
2649     {
2650       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2651       vat_json_object_add_ip6 (node, "ip", ip6);
2652     }
2653   else
2654     {
2655       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2656       vat_json_object_add_ip4 (node, "ip", ip4);
2657     }
2658   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2659 }
2660
2661 static void
2662 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2663 {
2664   vat_main_t *vam = &vat_main;
2665   static ip_details_t empty_ip_details = { 0 };
2666   ip_details_t *ip = NULL;
2667   u32 sw_if_index = ~0;
2668
2669   sw_if_index = ntohl (mp->sw_if_index);
2670
2671   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2672                            sw_if_index, empty_ip_details);
2673
2674   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2675                          sw_if_index);
2676
2677   ip->present = 1;
2678 }
2679
2680 static void
2681 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2682 {
2683   vat_main_t *vam = &vat_main;
2684
2685   if (VAT_JSON_ARRAY != vam->json_tree.type)
2686     {
2687       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2688       vat_json_init_array (&vam->json_tree);
2689     }
2690   vat_json_array_add_uint (&vam->json_tree,
2691                            clib_net_to_host_u32 (mp->sw_if_index));
2692 }
2693
2694 static void
2695 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2696 {
2697   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2698           "router_addr %U host_mac %U",
2699           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2700           mp->lease.hostname,
2701           format_ip4_address, &mp->lease.host_address,
2702           format_ip4_address, &mp->lease.router_address,
2703           format_ethernet_address, mp->lease.host_mac);
2704 }
2705
2706 static void vl_api_dhcp_compl_event_t_handler_json
2707   (vl_api_dhcp_compl_event_t * mp)
2708 {
2709   /* JSON output not supported */
2710 }
2711
2712 static void
2713 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2714                               u32 counter)
2715 {
2716   vat_main_t *vam = &vat_main;
2717   static u64 default_counter = 0;
2718
2719   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2720                            NULL);
2721   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2722                            sw_if_index, default_counter);
2723   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2724 }
2725
2726 static void
2727 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2728                                 interface_counter_t counter)
2729 {
2730   vat_main_t *vam = &vat_main;
2731   static interface_counter_t default_counter = { 0, };
2732
2733   vec_validate_init_empty (vam->combined_interface_counters,
2734                            vnet_counter_type, NULL);
2735   vec_validate_init_empty (vam->combined_interface_counters
2736                            [vnet_counter_type], sw_if_index, default_counter);
2737   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2738 }
2739
2740 static void vl_api_vnet_interface_simple_counters_t_handler
2741   (vl_api_vnet_interface_simple_counters_t * mp)
2742 {
2743   /* not supported */
2744 }
2745
2746 static void vl_api_vnet_interface_combined_counters_t_handler
2747   (vl_api_vnet_interface_combined_counters_t * mp)
2748 {
2749   /* not supported */
2750 }
2751
2752 static void vl_api_vnet_interface_simple_counters_t_handler_json
2753   (vl_api_vnet_interface_simple_counters_t * mp)
2754 {
2755   u64 *v_packets;
2756   u64 packets;
2757   u32 count;
2758   u32 first_sw_if_index;
2759   int i;
2760
2761   count = ntohl (mp->count);
2762   first_sw_if_index = ntohl (mp->first_sw_if_index);
2763
2764   v_packets = (u64 *) & mp->data;
2765   for (i = 0; i < count; i++)
2766     {
2767       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2768       set_simple_interface_counter (mp->vnet_counter_type,
2769                                     first_sw_if_index + i, packets);
2770       v_packets++;
2771     }
2772 }
2773
2774 static void vl_api_vnet_interface_combined_counters_t_handler_json
2775   (vl_api_vnet_interface_combined_counters_t * mp)
2776 {
2777   interface_counter_t counter;
2778   vlib_counter_t *v;
2779   u32 first_sw_if_index;
2780   int i;
2781   u32 count;
2782
2783   count = ntohl (mp->count);
2784   first_sw_if_index = ntohl (mp->first_sw_if_index);
2785
2786   v = (vlib_counter_t *) & mp->data;
2787   for (i = 0; i < count; i++)
2788     {
2789       counter.packets =
2790         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2791       counter.bytes =
2792         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2793       set_combined_interface_counter (mp->vnet_counter_type,
2794                                       first_sw_if_index + i, counter);
2795       v++;
2796     }
2797 }
2798
2799 static u32
2800 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2801 {
2802   vat_main_t *vam = &vat_main;
2803   u32 i;
2804
2805   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2806     {
2807       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2808         {
2809           return i;
2810         }
2811     }
2812   return ~0;
2813 }
2814
2815 static u32
2816 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   u32 i;
2820
2821   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2822     {
2823       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2824         {
2825           return i;
2826         }
2827     }
2828   return ~0;
2829 }
2830
2831 static void vl_api_vnet_ip4_fib_counters_t_handler
2832   (vl_api_vnet_ip4_fib_counters_t * mp)
2833 {
2834   /* not supported */
2835 }
2836
2837 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2838   (vl_api_vnet_ip4_fib_counters_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vl_api_ip4_fib_counter_t *v;
2842   ip4_fib_counter_t *counter;
2843   struct in_addr ip4;
2844   u32 vrf_id;
2845   u32 vrf_index;
2846   u32 count;
2847   int i;
2848
2849   vrf_id = ntohl (mp->vrf_id);
2850   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2851   if (~0 == vrf_index)
2852     {
2853       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2854       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2855       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2856       vec_validate (vam->ip4_fib_counters, vrf_index);
2857       vam->ip4_fib_counters[vrf_index] = NULL;
2858     }
2859
2860   vec_free (vam->ip4_fib_counters[vrf_index]);
2861   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2862   count = ntohl (mp->count);
2863   for (i = 0; i < count; i++)
2864     {
2865       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2866       counter = &vam->ip4_fib_counters[vrf_index][i];
2867       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2868       counter->address = ip4;
2869       counter->address_length = v->address_length;
2870       counter->packets = clib_net_to_host_u64 (v->packets);
2871       counter->bytes = clib_net_to_host_u64 (v->bytes);
2872       v++;
2873     }
2874 }
2875
2876 static void vl_api_vnet_ip4_nbr_counters_t_handler
2877   (vl_api_vnet_ip4_nbr_counters_t * mp)
2878 {
2879   /* not supported */
2880 }
2881
2882 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2883   (vl_api_vnet_ip4_nbr_counters_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   vl_api_ip4_nbr_counter_t *v;
2887   ip4_nbr_counter_t *counter;
2888   u32 sw_if_index;
2889   u32 count;
2890   int i;
2891
2892   sw_if_index = ntohl (mp->sw_if_index);
2893   count = ntohl (mp->count);
2894   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2895
2896   if (mp->begin)
2897     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2898
2899   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2900   for (i = 0; i < count; i++)
2901     {
2902       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2903       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2904       counter->address.s_addr = v->address;
2905       counter->packets = clib_net_to_host_u64 (v->packets);
2906       counter->bytes = clib_net_to_host_u64 (v->bytes);
2907       counter->linkt = v->link_type;
2908       v++;
2909     }
2910 }
2911
2912 static void vl_api_vnet_ip6_fib_counters_t_handler
2913   (vl_api_vnet_ip6_fib_counters_t * mp)
2914 {
2915   /* not supported */
2916 }
2917
2918 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2919   (vl_api_vnet_ip6_fib_counters_t * mp)
2920 {
2921   vat_main_t *vam = &vat_main;
2922   vl_api_ip6_fib_counter_t *v;
2923   ip6_fib_counter_t *counter;
2924   struct in6_addr ip6;
2925   u32 vrf_id;
2926   u32 vrf_index;
2927   u32 count;
2928   int i;
2929
2930   vrf_id = ntohl (mp->vrf_id);
2931   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2932   if (~0 == vrf_index)
2933     {
2934       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2935       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2936       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2937       vec_validate (vam->ip6_fib_counters, vrf_index);
2938       vam->ip6_fib_counters[vrf_index] = NULL;
2939     }
2940
2941   vec_free (vam->ip6_fib_counters[vrf_index]);
2942   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2943   count = ntohl (mp->count);
2944   for (i = 0; i < count; i++)
2945     {
2946       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2947       counter = &vam->ip6_fib_counters[vrf_index][i];
2948       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2949       counter->address = ip6;
2950       counter->address_length = v->address_length;
2951       counter->packets = clib_net_to_host_u64 (v->packets);
2952       counter->bytes = clib_net_to_host_u64 (v->bytes);
2953       v++;
2954     }
2955 }
2956
2957 static void vl_api_vnet_ip6_nbr_counters_t_handler
2958   (vl_api_vnet_ip6_nbr_counters_t * mp)
2959 {
2960   /* not supported */
2961 }
2962
2963 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2964   (vl_api_vnet_ip6_nbr_counters_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   vl_api_ip6_nbr_counter_t *v;
2968   ip6_nbr_counter_t *counter;
2969   struct in6_addr ip6;
2970   u32 sw_if_index;
2971   u32 count;
2972   int i;
2973
2974   sw_if_index = ntohl (mp->sw_if_index);
2975   count = ntohl (mp->count);
2976   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2977
2978   if (mp->begin)
2979     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2980
2981   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2982   for (i = 0; i < count; i++)
2983     {
2984       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2985       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2986       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2987       counter->address = ip6;
2988       counter->packets = clib_net_to_host_u64 (v->packets);
2989       counter->bytes = clib_net_to_host_u64 (v->bytes);
2990       v++;
2991     }
2992 }
2993
2994 static void vl_api_get_first_msg_id_reply_t_handler
2995   (vl_api_get_first_msg_id_reply_t * mp)
2996 {
2997   vat_main_t *vam = &vat_main;
2998   i32 retval = ntohl (mp->retval);
2999
3000   if (vam->async_mode)
3001     {
3002       vam->async_errors += (retval < 0);
3003     }
3004   else
3005     {
3006       vam->retval = retval;
3007       vam->result_ready = 1;
3008     }
3009   if (retval >= 0)
3010     {
3011       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3012     }
3013 }
3014
3015 static void vl_api_get_first_msg_id_reply_t_handler_json
3016   (vl_api_get_first_msg_id_reply_t * mp)
3017 {
3018   vat_main_t *vam = &vat_main;
3019   vat_json_node_t node;
3020
3021   vat_json_init_object (&node);
3022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3023   vat_json_object_add_uint (&node, "first_msg_id",
3024                             (uint) ntohs (mp->first_msg_id));
3025
3026   vat_json_print (vam->ofp, &node);
3027   vat_json_free (&node);
3028
3029   vam->retval = ntohl (mp->retval);
3030   vam->result_ready = 1;
3031 }
3032
3033 static void vl_api_get_node_graph_reply_t_handler
3034   (vl_api_get_node_graph_reply_t * mp)
3035 {
3036   vat_main_t *vam = &vat_main;
3037   api_main_t *am = &api_main;
3038   i32 retval = ntohl (mp->retval);
3039   u8 *pvt_copy, *reply;
3040   void *oldheap;
3041   vlib_node_t *node;
3042   int i;
3043
3044   if (vam->async_mode)
3045     {
3046       vam->async_errors += (retval < 0);
3047     }
3048   else
3049     {
3050       vam->retval = retval;
3051       vam->result_ready = 1;
3052     }
3053
3054   /* "Should never happen..." */
3055   if (retval != 0)
3056     return;
3057
3058   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3059   pvt_copy = vec_dup (reply);
3060
3061   /* Toss the shared-memory original... */
3062   pthread_mutex_lock (&am->vlib_rp->mutex);
3063   oldheap = svm_push_data_heap (am->vlib_rp);
3064
3065   vec_free (reply);
3066
3067   svm_pop_heap (oldheap);
3068   pthread_mutex_unlock (&am->vlib_rp->mutex);
3069
3070   if (vam->graph_nodes)
3071     {
3072       hash_free (vam->graph_node_index_by_name);
3073
3074       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3075         {
3076           node = vam->graph_nodes[0][i];
3077           vec_free (node->name);
3078           vec_free (node->next_nodes);
3079           vec_free (node);
3080         }
3081       vec_free (vam->graph_nodes[0]);
3082       vec_free (vam->graph_nodes);
3083     }
3084
3085   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3086   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3087   vec_free (pvt_copy);
3088
3089   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3090     {
3091       node = vam->graph_nodes[0][i];
3092       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3093     }
3094 }
3095
3096 static void vl_api_get_node_graph_reply_t_handler_json
3097   (vl_api_get_node_graph_reply_t * mp)
3098 {
3099   vat_main_t *vam = &vat_main;
3100   api_main_t *am = &api_main;
3101   void *oldheap;
3102   vat_json_node_t node;
3103   u8 *reply;
3104
3105   /* $$$$ make this real? */
3106   vat_json_init_object (&node);
3107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3108   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3109
3110   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3111
3112   /* Toss the shared-memory original... */
3113   pthread_mutex_lock (&am->vlib_rp->mutex);
3114   oldheap = svm_push_data_heap (am->vlib_rp);
3115
3116   vec_free (reply);
3117
3118   svm_pop_heap (oldheap);
3119   pthread_mutex_unlock (&am->vlib_rp->mutex);
3120
3121   vat_json_print (vam->ofp, &node);
3122   vat_json_free (&node);
3123
3124   vam->retval = ntohl (mp->retval);
3125   vam->result_ready = 1;
3126 }
3127
3128 static void
3129 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3130 {
3131   vat_main_t *vam = &vat_main;
3132   u8 *s = 0;
3133
3134   if (mp->local)
3135     {
3136       s = format (s, "%=16d%=16d%=16d",
3137                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3138     }
3139   else
3140     {
3141       s = format (s, "%=16U%=16d%=16d",
3142                   mp->is_ipv6 ? format_ip6_address :
3143                   format_ip4_address,
3144                   mp->ip_address, mp->priority, mp->weight);
3145     }
3146
3147   print (vam->ofp, "%v", s);
3148   vec_free (s);
3149 }
3150
3151 static void
3152 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3153 {
3154   vat_main_t *vam = &vat_main;
3155   vat_json_node_t *node = NULL;
3156   struct in6_addr ip6;
3157   struct in_addr ip4;
3158
3159   if (VAT_JSON_ARRAY != vam->json_tree.type)
3160     {
3161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3162       vat_json_init_array (&vam->json_tree);
3163     }
3164   node = vat_json_array_add (&vam->json_tree);
3165   vat_json_init_object (node);
3166
3167   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3168   vat_json_object_add_uint (node, "priority", mp->priority);
3169   vat_json_object_add_uint (node, "weight", mp->weight);
3170
3171   if (mp->local)
3172     vat_json_object_add_uint (node, "sw_if_index",
3173                               clib_net_to_host_u32 (mp->sw_if_index));
3174   else
3175     {
3176       if (mp->is_ipv6)
3177         {
3178           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3179           vat_json_object_add_ip6 (node, "address", ip6);
3180         }
3181       else
3182         {
3183           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3184           vat_json_object_add_ip4 (node, "address", ip4);
3185         }
3186     }
3187 }
3188
3189 static void
3190 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3191                                           mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   u8 *ls_name = 0;
3195
3196   ls_name = format (0, "%s", mp->ls_name);
3197
3198   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3199          ls_name);
3200   vec_free (ls_name);
3201 }
3202
3203 static void
3204   vl_api_one_locator_set_details_t_handler_json
3205   (vl_api_one_locator_set_details_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t *node = 0;
3209   u8 *ls_name = 0;
3210
3211   ls_name = format (0, "%s", mp->ls_name);
3212   vec_add1 (ls_name, 0);
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220
3221   vat_json_init_object (node);
3222   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3223   vat_json_object_add_uint (node, "ls_index",
3224                             clib_net_to_host_u32 (mp->ls_index));
3225   vec_free (ls_name);
3226 }
3227
3228 typedef struct
3229 {
3230   u32 spi;
3231   u8 si;
3232 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3233
3234 uword
3235 unformat_nsh_address (unformat_input_t * input, va_list * args)
3236 {
3237   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3238   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3239 }
3240
3241 u8 *
3242 format_nsh_address_vat (u8 * s, va_list * args)
3243 {
3244   nsh_t *a = va_arg (*args, nsh_t *);
3245   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3246 }
3247
3248 static u8 *
3249 format_lisp_flat_eid (u8 * s, va_list * args)
3250 {
3251   u32 type = va_arg (*args, u32);
3252   u8 *eid = va_arg (*args, u8 *);
3253   u32 eid_len = va_arg (*args, u32);
3254
3255   switch (type)
3256     {
3257     case 0:
3258       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3259     case 1:
3260       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3261     case 2:
3262       return format (s, "%U", format_ethernet_address, eid);
3263     case 3:
3264       return format (s, "%U", format_nsh_address_vat, eid);
3265     }
3266   return 0;
3267 }
3268
3269 static u8 *
3270 format_lisp_eid_vat (u8 * s, va_list * args)
3271 {
3272   u32 type = va_arg (*args, u32);
3273   u8 *eid = va_arg (*args, u8 *);
3274   u32 eid_len = va_arg (*args, u32);
3275   u8 *seid = va_arg (*args, u8 *);
3276   u32 seid_len = va_arg (*args, u32);
3277   u32 is_src_dst = va_arg (*args, u32);
3278
3279   if (is_src_dst)
3280     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3281
3282   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3283
3284   return s;
3285 }
3286
3287 static void
3288 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   u8 *s = 0, *eid = 0;
3292
3293   if (~0 == mp->locator_set_index)
3294     s = format (0, "action: %d", mp->action);
3295   else
3296     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3297
3298   eid = format (0, "%U", format_lisp_eid_vat,
3299                 mp->eid_type,
3300                 mp->eid,
3301                 mp->eid_prefix_len,
3302                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3303   vec_add1 (eid, 0);
3304
3305   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3306          clib_net_to_host_u32 (mp->vni),
3307          eid,
3308          mp->is_local ? "local" : "remote",
3309          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3310          clib_net_to_host_u16 (mp->key_id), mp->key);
3311
3312   vec_free (s);
3313   vec_free (eid);
3314 }
3315
3316 static void
3317 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3318                                              * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321   vat_json_node_t *node = 0;
3322   u8 *eid = 0;
3323
3324   if (VAT_JSON_ARRAY != vam->json_tree.type)
3325     {
3326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3327       vat_json_init_array (&vam->json_tree);
3328     }
3329   node = vat_json_array_add (&vam->json_tree);
3330
3331   vat_json_init_object (node);
3332   if (~0 == mp->locator_set_index)
3333     vat_json_object_add_uint (node, "action", mp->action);
3334   else
3335     vat_json_object_add_uint (node, "locator_set_index",
3336                               clib_net_to_host_u32 (mp->locator_set_index));
3337
3338   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3339   if (mp->eid_type == 3)
3340     {
3341       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3342       vat_json_init_object (nsh_json);
3343       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3344       vat_json_object_add_uint (nsh_json, "spi",
3345                                 clib_net_to_host_u32 (nsh->spi));
3346       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3347     }
3348   else
3349     {
3350       eid = format (0, "%U", format_lisp_eid_vat,
3351                     mp->eid_type,
3352                     mp->eid,
3353                     mp->eid_prefix_len,
3354                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3355       vec_add1 (eid, 0);
3356       vat_json_object_add_string_copy (node, "eid", eid);
3357       vec_free (eid);
3358     }
3359   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3360   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3361   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3362
3363   if (mp->key_id)
3364     {
3365       vat_json_object_add_uint (node, "key_id",
3366                                 clib_net_to_host_u16 (mp->key_id));
3367       vat_json_object_add_string_copy (node, "key", mp->key);
3368     }
3369 }
3370
3371 static void
3372 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3373 {
3374   vat_main_t *vam = &vat_main;
3375   u8 *seid = 0, *deid = 0;
3376   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3377
3378   deid = format (0, "%U", format_lisp_eid_vat,
3379                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3380
3381   seid = format (0, "%U", format_lisp_eid_vat,
3382                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3383
3384   vec_add1 (deid, 0);
3385   vec_add1 (seid, 0);
3386
3387   if (mp->is_ip4)
3388     format_ip_address_fcn = format_ip4_address;
3389   else
3390     format_ip_address_fcn = format_ip6_address;
3391
3392
3393   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3394          clib_net_to_host_u32 (mp->vni),
3395          seid, deid,
3396          format_ip_address_fcn, mp->lloc,
3397          format_ip_address_fcn, mp->rloc,
3398          clib_net_to_host_u32 (mp->pkt_count),
3399          clib_net_to_host_u32 (mp->bytes));
3400
3401   vec_free (deid);
3402   vec_free (seid);
3403 }
3404
3405 static void
3406 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3407 {
3408   struct in6_addr ip6;
3409   struct in_addr ip4;
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t *node = 0;
3412   u8 *deid = 0, *seid = 0;
3413
3414   if (VAT_JSON_ARRAY != vam->json_tree.type)
3415     {
3416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3417       vat_json_init_array (&vam->json_tree);
3418     }
3419   node = vat_json_array_add (&vam->json_tree);
3420
3421   vat_json_init_object (node);
3422   deid = format (0, "%U", format_lisp_eid_vat,
3423                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3424
3425   seid = format (0, "%U", format_lisp_eid_vat,
3426                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3427
3428   vec_add1 (deid, 0);
3429   vec_add1 (seid, 0);
3430
3431   vat_json_object_add_string_copy (node, "seid", seid);
3432   vat_json_object_add_string_copy (node, "deid", deid);
3433   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3434
3435   if (mp->is_ip4)
3436     {
3437       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3438       vat_json_object_add_ip4 (node, "lloc", ip4);
3439       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3440       vat_json_object_add_ip4 (node, "rloc", ip4);
3441     }
3442   else
3443     {
3444       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3445       vat_json_object_add_ip6 (node, "lloc", ip6);
3446       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3447       vat_json_object_add_ip6 (node, "rloc", ip6);
3448     }
3449   vat_json_object_add_uint (node, "pkt_count",
3450                             clib_net_to_host_u32 (mp->pkt_count));
3451   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3452
3453   vec_free (deid);
3454   vec_free (seid);
3455 }
3456
3457 static void
3458   vl_api_one_eid_table_map_details_t_handler
3459   (vl_api_one_eid_table_map_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   u8 *line = format (0, "%=10d%=10d",
3464                      clib_net_to_host_u32 (mp->vni),
3465                      clib_net_to_host_u32 (mp->dp_table));
3466   print (vam->ofp, "%v", line);
3467   vec_free (line);
3468 }
3469
3470 static void
3471   vl_api_one_eid_table_map_details_t_handler_json
3472   (vl_api_one_eid_table_map_details_t * mp)
3473 {
3474   vat_main_t *vam = &vat_main;
3475   vat_json_node_t *node = NULL;
3476
3477   if (VAT_JSON_ARRAY != vam->json_tree.type)
3478     {
3479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3480       vat_json_init_array (&vam->json_tree);
3481     }
3482   node = vat_json_array_add (&vam->json_tree);
3483   vat_json_init_object (node);
3484   vat_json_object_add_uint (node, "dp_table",
3485                             clib_net_to_host_u32 (mp->dp_table));
3486   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3487 }
3488
3489 static void
3490   vl_api_one_eid_table_vni_details_t_handler
3491   (vl_api_one_eid_table_vni_details_t * mp)
3492 {
3493   vat_main_t *vam = &vat_main;
3494
3495   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3496   print (vam->ofp, "%v", line);
3497   vec_free (line);
3498 }
3499
3500 static void
3501   vl_api_one_eid_table_vni_details_t_handler_json
3502   (vl_api_one_eid_table_vni_details_t * mp)
3503 {
3504   vat_main_t *vam = &vat_main;
3505   vat_json_node_t *node = NULL;
3506
3507   if (VAT_JSON_ARRAY != vam->json_tree.type)
3508     {
3509       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3510       vat_json_init_array (&vam->json_tree);
3511     }
3512   node = vat_json_array_add (&vam->json_tree);
3513   vat_json_init_object (node);
3514   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3515 }
3516
3517 static void
3518   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3519   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523
3524   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3525   print (vam->ofp, "fallback threshold value: %d", mp->value);
3526
3527   vam->retval = retval;
3528   vam->result_ready = 1;
3529 }
3530
3531 static void
3532   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3533   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3534 {
3535   vat_main_t *vam = &vat_main;
3536   vat_json_node_t _node, *node = &_node;
3537   int retval = clib_net_to_host_u32 (mp->retval);
3538
3539   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3540   vat_json_init_object (node);
3541   vat_json_object_add_uint (node, "value", mp->value);
3542
3543   vat_json_print (vam->ofp, node);
3544   vat_json_free (node);
3545
3546   vam->retval = retval;
3547   vam->result_ready = 1;
3548 }
3549
3550 static void
3551   vl_api_show_one_map_register_state_reply_t_handler
3552   (vl_api_show_one_map_register_state_reply_t * mp)
3553 {
3554   vat_main_t *vam = &vat_main;
3555   int retval = clib_net_to_host_u32 (mp->retval);
3556
3557   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3558
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_show_one_map_register_state_reply_t_handler_json
3565   (vl_api_show_one_map_register_state_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   vat_json_node_t _node, *node = &_node;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570
3571   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3572
3573   vat_json_init_object (node);
3574   vat_json_object_add_string_copy (node, "state", s);
3575
3576   vat_json_print (vam->ofp, node);
3577   vat_json_free (node);
3578
3579   vam->retval = retval;
3580   vam->result_ready = 1;
3581   vec_free (s);
3582 }
3583
3584 static void
3585   vl_api_show_one_rloc_probe_state_reply_t_handler
3586   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3587 {
3588   vat_main_t *vam = &vat_main;
3589   int retval = clib_net_to_host_u32 (mp->retval);
3590
3591   if (retval)
3592     goto end;
3593
3594   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3595 end:
3596   vam->retval = retval;
3597   vam->result_ready = 1;
3598 }
3599
3600 static void
3601   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3602   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3603 {
3604   vat_main_t *vam = &vat_main;
3605   vat_json_node_t _node, *node = &_node;
3606   int retval = clib_net_to_host_u32 (mp->retval);
3607
3608   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3609   vat_json_init_object (node);
3610   vat_json_object_add_string_copy (node, "state", s);
3611
3612   vat_json_print (vam->ofp, node);
3613   vat_json_free (node);
3614
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617   vec_free (s);
3618 }
3619
3620 static void
3621   vl_api_show_one_stats_enable_disable_reply_t_handler
3622   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3623 {
3624   vat_main_t *vam = &vat_main;
3625   int retval = clib_net_to_host_u32 (mp->retval);
3626
3627   if (retval)
3628     goto end;
3629
3630   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3638   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3639 {
3640   vat_main_t *vam = &vat_main;
3641   vat_json_node_t _node, *node = &_node;
3642   int retval = clib_net_to_host_u32 (mp->retval);
3643
3644   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3645   vat_json_init_object (node);
3646   vat_json_object_add_string_copy (node, "state", s);
3647
3648   vat_json_print (vam->ofp, node);
3649   vat_json_free (node);
3650
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653   vec_free (s);
3654 }
3655
3656 static void
3657 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3658 {
3659   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3660   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3661   e->vni = clib_net_to_host_u32 (e->vni);
3662 }
3663
3664 static void
3665   gpe_fwd_entries_get_reply_t_net_to_host
3666   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3667 {
3668   u32 i;
3669
3670   mp->count = clib_net_to_host_u32 (mp->count);
3671   for (i = 0; i < mp->count; i++)
3672     {
3673       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3674     }
3675 }
3676
3677 static u8 *
3678 format_gpe_encap_mode (u8 * s, va_list * args)
3679 {
3680   u32 mode = va_arg (*args, u32);
3681
3682   switch (mode)
3683     {
3684     case 0:
3685       return format (s, "lisp");
3686     case 1:
3687       return format (s, "vxlan");
3688     }
3689   return 0;
3690 }
3691
3692 static void
3693   vl_api_gpe_get_encap_mode_reply_t_handler
3694   (vl_api_gpe_get_encap_mode_reply_t * mp)
3695 {
3696   vat_main_t *vam = &vat_main;
3697
3698   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3699   vam->retval = ntohl (mp->retval);
3700   vam->result_ready = 1;
3701 }
3702
3703 static void
3704   vl_api_gpe_get_encap_mode_reply_t_handler_json
3705   (vl_api_gpe_get_encap_mode_reply_t * mp)
3706 {
3707   vat_main_t *vam = &vat_main;
3708   vat_json_node_t node;
3709
3710   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3711   vec_add1 (encap_mode, 0);
3712
3713   vat_json_init_object (&node);
3714   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3715
3716   vec_free (encap_mode);
3717   vat_json_print (vam->ofp, &node);
3718   vat_json_free (&node);
3719
3720   vam->retval = ntohl (mp->retval);
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_gpe_fwd_entry_path_details_t_handler
3726   (vl_api_gpe_fwd_entry_path_details_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3730
3731   if (mp->lcl_loc.is_ip4)
3732     format_ip_address_fcn = format_ip4_address;
3733   else
3734     format_ip_address_fcn = format_ip6_address;
3735
3736   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3737          format_ip_address_fcn, &mp->lcl_loc,
3738          format_ip_address_fcn, &mp->rmt_loc);
3739 }
3740
3741 static void
3742 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3743 {
3744   struct in6_addr ip6;
3745   struct in_addr ip4;
3746
3747   if (loc->is_ip4)
3748     {
3749       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3750       vat_json_object_add_ip4 (n, "address", ip4);
3751     }
3752   else
3753     {
3754       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3755       vat_json_object_add_ip6 (n, "address", ip6);
3756     }
3757   vat_json_object_add_uint (n, "weight", loc->weight);
3758 }
3759
3760 static void
3761   vl_api_gpe_fwd_entry_path_details_t_handler_json
3762   (vl_api_gpe_fwd_entry_path_details_t * mp)
3763 {
3764   vat_main_t *vam = &vat_main;
3765   vat_json_node_t *node = NULL;
3766   vat_json_node_t *loc_node;
3767
3768   if (VAT_JSON_ARRAY != vam->json_tree.type)
3769     {
3770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3771       vat_json_init_array (&vam->json_tree);
3772     }
3773   node = vat_json_array_add (&vam->json_tree);
3774   vat_json_init_object (node);
3775
3776   loc_node = vat_json_object_add (node, "local_locator");
3777   vat_json_init_object (loc_node);
3778   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3779
3780   loc_node = vat_json_object_add (node, "remote_locator");
3781   vat_json_init_object (loc_node);
3782   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3783 }
3784
3785 static void
3786   vl_api_gpe_fwd_entries_get_reply_t_handler
3787   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792   vl_api_gpe_fwd_entry_t *e;
3793
3794   if (retval)
3795     goto end;
3796
3797   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3798
3799   for (i = 0; i < mp->count; i++)
3800     {
3801       e = &mp->entries[i];
3802       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3803              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3804              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3814   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3815 {
3816   u8 *s = 0;
3817   vat_main_t *vam = &vat_main;
3818   vat_json_node_t *e = 0, root;
3819   u32 i;
3820   int retval = clib_net_to_host_u32 (mp->retval);
3821   vl_api_gpe_fwd_entry_t *fwd;
3822
3823   if (retval)
3824     goto end;
3825
3826   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < mp->count; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       fwd = &mp->entries[i];
3833
3834       vat_json_init_object (e);
3835       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3836       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3837       vat_json_object_add_int (e, "vni", fwd->vni);
3838       vat_json_object_add_int (e, "action", fwd->action);
3839
3840       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3841                   fwd->leid_prefix_len);
3842       vec_add1 (s, 0);
3843       vat_json_object_add_string_copy (e, "leid", s);
3844       vec_free (s);
3845
3846       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3847                   fwd->reid_prefix_len);
3848       vec_add1 (s, 0);
3849       vat_json_object_add_string_copy (e, "reid", s);
3850       vec_free (s);
3851     }
3852
3853   vat_json_print (vam->ofp, &root);
3854   vat_json_free (&root);
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3863   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   u32 i, n;
3867   int retval = clib_net_to_host_u32 (mp->retval);
3868   vl_api_gpe_native_fwd_rpath_t *r;
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874
3875   for (i = 0; i < n; i++)
3876     {
3877       r = &mp->entries[i];
3878       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3879              clib_net_to_host_u32 (r->fib_index),
3880              clib_net_to_host_u32 (r->nh_sw_if_index),
3881              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3882     }
3883
3884 end:
3885   vam->retval = retval;
3886   vam->result_ready = 1;
3887 }
3888
3889 static void
3890   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3891   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3892 {
3893   vat_main_t *vam = &vat_main;
3894   vat_json_node_t root, *e;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897   vl_api_gpe_native_fwd_rpath_t *r;
3898   u8 *s;
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904   vat_json_init_array (&root);
3905
3906   for (i = 0; i < n; i++)
3907     {
3908       e = vat_json_array_add (&root);
3909       vat_json_init_object (e);
3910       r = &mp->entries[i];
3911       s =
3912         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3913                 r->nh_addr);
3914       vec_add1 (s, 0);
3915       vat_json_object_add_string_copy (e, "ip4", s);
3916       vec_free (s);
3917
3918       vat_json_object_add_uint (e, "fib_index",
3919                                 clib_net_to_host_u32 (r->fib_index));
3920       vat_json_object_add_uint (e, "nh_sw_if_index",
3921                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3922     }
3923
3924   vat_json_print (vam->ofp, &root);
3925   vat_json_free (&root);
3926
3927 end:
3928   vam->retval = retval;
3929   vam->result_ready = 1;
3930 }
3931
3932 static void
3933   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3934   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3935 {
3936   vat_main_t *vam = &vat_main;
3937   u32 i, n;
3938   int retval = clib_net_to_host_u32 (mp->retval);
3939
3940   if (retval)
3941     goto end;
3942
3943   n = clib_net_to_host_u32 (mp->count);
3944
3945   for (i = 0; i < n; i++)
3946     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3947
3948 end:
3949   vam->retval = retval;
3950   vam->result_ready = 1;
3951 }
3952
3953 static void
3954   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3955   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3956 {
3957   vat_main_t *vam = &vat_main;
3958   vat_json_node_t root;
3959   u32 i, n;
3960   int retval = clib_net_to_host_u32 (mp->retval);
3961
3962   if (retval)
3963     goto end;
3964
3965   n = clib_net_to_host_u32 (mp->count);
3966   vat_json_init_array (&root);
3967
3968   for (i = 0; i < n; i++)
3969     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3970
3971   vat_json_print (vam->ofp, &root);
3972   vat_json_free (&root);
3973
3974 end:
3975   vam->retval = retval;
3976   vam->result_ready = 1;
3977 }
3978
3979 static void
3980   vl_api_one_ndp_entries_get_reply_t_handler
3981   (vl_api_one_ndp_entries_get_reply_t * mp)
3982 {
3983   vat_main_t *vam = &vat_main;
3984   u32 i, n;
3985   int retval = clib_net_to_host_u32 (mp->retval);
3986
3987   if (retval)
3988     goto end;
3989
3990   n = clib_net_to_host_u32 (mp->count);
3991
3992   for (i = 0; i < n; i++)
3993     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3994            format_ethernet_address, mp->entries[i].mac);
3995
3996 end:
3997   vam->retval = retval;
3998   vam->result_ready = 1;
3999 }
4000
4001 static void
4002   vl_api_one_ndp_entries_get_reply_t_handler_json
4003   (vl_api_one_ndp_entries_get_reply_t * mp)
4004 {
4005   u8 *s = 0;
4006   vat_main_t *vam = &vat_main;
4007   vat_json_node_t *e = 0, root;
4008   u32 i, n;
4009   int retval = clib_net_to_host_u32 (mp->retval);
4010   vl_api_one_ndp_entry_t *arp_entry;
4011
4012   if (retval)
4013     goto end;
4014
4015   n = clib_net_to_host_u32 (mp->count);
4016   vat_json_init_array (&root);
4017
4018   for (i = 0; i < n; i++)
4019     {
4020       e = vat_json_array_add (&root);
4021       arp_entry = &mp->entries[i];
4022
4023       vat_json_init_object (e);
4024       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4025       vec_add1 (s, 0);
4026
4027       vat_json_object_add_string_copy (e, "mac", s);
4028       vec_free (s);
4029
4030       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4031       vec_add1 (s, 0);
4032       vat_json_object_add_string_copy (e, "ip6", s);
4033       vec_free (s);
4034     }
4035
4036   vat_json_print (vam->ofp, &root);
4037   vat_json_free (&root);
4038
4039 end:
4040   vam->retval = retval;
4041   vam->result_ready = 1;
4042 }
4043
4044 static void
4045   vl_api_one_l2_arp_entries_get_reply_t_handler
4046   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4047 {
4048   vat_main_t *vam = &vat_main;
4049   u32 i, n;
4050   int retval = clib_net_to_host_u32 (mp->retval);
4051
4052   if (retval)
4053     goto end;
4054
4055   n = clib_net_to_host_u32 (mp->count);
4056
4057   for (i = 0; i < n; i++)
4058     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4059            format_ethernet_address, mp->entries[i].mac);
4060
4061 end:
4062   vam->retval = retval;
4063   vam->result_ready = 1;
4064 }
4065
4066 static void
4067   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4068   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4069 {
4070   u8 *s = 0;
4071   vat_main_t *vam = &vat_main;
4072   vat_json_node_t *e = 0, root;
4073   u32 i, n;
4074   int retval = clib_net_to_host_u32 (mp->retval);
4075   vl_api_one_l2_arp_entry_t *arp_entry;
4076
4077   if (retval)
4078     goto end;
4079
4080   n = clib_net_to_host_u32 (mp->count);
4081   vat_json_init_array (&root);
4082
4083   for (i = 0; i < n; i++)
4084     {
4085       e = vat_json_array_add (&root);
4086       arp_entry = &mp->entries[i];
4087
4088       vat_json_init_object (e);
4089       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4090       vec_add1 (s, 0);
4091
4092       vat_json_object_add_string_copy (e, "mac", s);
4093       vec_free (s);
4094
4095       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4096       vec_add1 (s, 0);
4097       vat_json_object_add_string_copy (e, "ip4", s);
4098       vec_free (s);
4099     }
4100
4101   vat_json_print (vam->ofp, &root);
4102   vat_json_free (&root);
4103
4104 end:
4105   vam->retval = retval;
4106   vam->result_ready = 1;
4107 }
4108
4109 static void
4110 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4111 {
4112   vat_main_t *vam = &vat_main;
4113   u32 i, n;
4114   int retval = clib_net_to_host_u32 (mp->retval);
4115
4116   if (retval)
4117     goto end;
4118
4119   n = clib_net_to_host_u32 (mp->count);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4124     }
4125
4126 end:
4127   vam->retval = retval;
4128   vam->result_ready = 1;
4129 }
4130
4131 static void
4132   vl_api_one_ndp_bd_get_reply_t_handler_json
4133   (vl_api_one_ndp_bd_get_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   vat_json_node_t root;
4137   u32 i, n;
4138   int retval = clib_net_to_host_u32 (mp->retval);
4139
4140   if (retval)
4141     goto end;
4142
4143   n = clib_net_to_host_u32 (mp->count);
4144   vat_json_init_array (&root);
4145
4146   for (i = 0; i < n; i++)
4147     {
4148       vat_json_array_add_uint (&root,
4149                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4150     }
4151
4152   vat_json_print (vam->ofp, &root);
4153   vat_json_free (&root);
4154
4155 end:
4156   vam->retval = retval;
4157   vam->result_ready = 1;
4158 }
4159
4160 static void
4161   vl_api_one_l2_arp_bd_get_reply_t_handler
4162   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4163 {
4164   vat_main_t *vam = &vat_main;
4165   u32 i, n;
4166   int retval = clib_net_to_host_u32 (mp->retval);
4167
4168   if (retval)
4169     goto end;
4170
4171   n = clib_net_to_host_u32 (mp->count);
4172
4173   for (i = 0; i < n; i++)
4174     {
4175       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4176     }
4177
4178 end:
4179   vam->retval = retval;
4180   vam->result_ready = 1;
4181 }
4182
4183 static void
4184   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4185   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   vat_json_node_t root;
4189   u32 i, n;
4190   int retval = clib_net_to_host_u32 (mp->retval);
4191
4192   if (retval)
4193     goto end;
4194
4195   n = clib_net_to_host_u32 (mp->count);
4196   vat_json_init_array (&root);
4197
4198   for (i = 0; i < n; i++)
4199     {
4200       vat_json_array_add_uint (&root,
4201                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4202     }
4203
4204   vat_json_print (vam->ofp, &root);
4205   vat_json_free (&root);
4206
4207 end:
4208   vam->retval = retval;
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_one_adjacencies_get_reply_t_handler
4214   (vl_api_one_adjacencies_get_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   u32 i, n;
4218   int retval = clib_net_to_host_u32 (mp->retval);
4219   vl_api_one_adjacency_t *a;
4220
4221   if (retval)
4222     goto end;
4223
4224   n = clib_net_to_host_u32 (mp->count);
4225
4226   for (i = 0; i < n; i++)
4227     {
4228       a = &mp->adjacencies[i];
4229       print (vam->ofp, "%U %40U",
4230              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4231              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4232     }
4233
4234 end:
4235   vam->retval = retval;
4236   vam->result_ready = 1;
4237 }
4238
4239 static void
4240   vl_api_one_adjacencies_get_reply_t_handler_json
4241   (vl_api_one_adjacencies_get_reply_t * mp)
4242 {
4243   u8 *s = 0;
4244   vat_main_t *vam = &vat_main;
4245   vat_json_node_t *e = 0, root;
4246   u32 i, n;
4247   int retval = clib_net_to_host_u32 (mp->retval);
4248   vl_api_one_adjacency_t *a;
4249
4250   if (retval)
4251     goto end;
4252
4253   n = clib_net_to_host_u32 (mp->count);
4254   vat_json_init_array (&root);
4255
4256   for (i = 0; i < n; i++)
4257     {
4258       e = vat_json_array_add (&root);
4259       a = &mp->adjacencies[i];
4260
4261       vat_json_init_object (e);
4262       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4263                   a->leid_prefix_len);
4264       vec_add1 (s, 0);
4265       vat_json_object_add_string_copy (e, "leid", s);
4266       vec_free (s);
4267
4268       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4269                   a->reid_prefix_len);
4270       vec_add1 (s, 0);
4271       vat_json_object_add_string_copy (e, "reid", s);
4272       vec_free (s);
4273     }
4274
4275   vat_json_print (vam->ofp, &root);
4276   vat_json_free (&root);
4277
4278 end:
4279   vam->retval = retval;
4280   vam->result_ready = 1;
4281 }
4282
4283 static void
4284 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4285 {
4286   vat_main_t *vam = &vat_main;
4287
4288   print (vam->ofp, "%=20U",
4289          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4290          mp->ip_address);
4291 }
4292
4293 static void
4294   vl_api_one_map_server_details_t_handler_json
4295   (vl_api_one_map_server_details_t * mp)
4296 {
4297   vat_main_t *vam = &vat_main;
4298   vat_json_node_t *node = NULL;
4299   struct in6_addr ip6;
4300   struct in_addr ip4;
4301
4302   if (VAT_JSON_ARRAY != vam->json_tree.type)
4303     {
4304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4305       vat_json_init_array (&vam->json_tree);
4306     }
4307   node = vat_json_array_add (&vam->json_tree);
4308
4309   vat_json_init_object (node);
4310   if (mp->is_ipv6)
4311     {
4312       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4313       vat_json_object_add_ip6 (node, "map-server", ip6);
4314     }
4315   else
4316     {
4317       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4318       vat_json_object_add_ip4 (node, "map-server", ip4);
4319     }
4320 }
4321
4322 static void
4323 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4324                                            * mp)
4325 {
4326   vat_main_t *vam = &vat_main;
4327
4328   print (vam->ofp, "%=20U",
4329          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4330          mp->ip_address);
4331 }
4332
4333 static void
4334   vl_api_one_map_resolver_details_t_handler_json
4335   (vl_api_one_map_resolver_details_t * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338   vat_json_node_t *node = NULL;
4339   struct in6_addr ip6;
4340   struct in_addr ip4;
4341
4342   if (VAT_JSON_ARRAY != vam->json_tree.type)
4343     {
4344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4345       vat_json_init_array (&vam->json_tree);
4346     }
4347   node = vat_json_array_add (&vam->json_tree);
4348
4349   vat_json_init_object (node);
4350   if (mp->is_ipv6)
4351     {
4352       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4353       vat_json_object_add_ip6 (node, "map resolver", ip6);
4354     }
4355   else
4356     {
4357       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4358       vat_json_object_add_ip4 (node, "map resolver", ip4);
4359     }
4360 }
4361
4362 static void
4363 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4364 {
4365   vat_main_t *vam = &vat_main;
4366   i32 retval = ntohl (mp->retval);
4367
4368   if (0 <= retval)
4369     {
4370       print (vam->ofp, "feature: %s\ngpe: %s",
4371              mp->feature_status ? "enabled" : "disabled",
4372              mp->gpe_status ? "enabled" : "disabled");
4373     }
4374
4375   vam->retval = retval;
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_show_one_status_reply_t_handler_json
4381   (vl_api_show_one_status_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   vat_json_node_t node;
4385   u8 *gpe_status = NULL;
4386   u8 *feature_status = NULL;
4387
4388   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4389   feature_status = format (0, "%s",
4390                            mp->feature_status ? "enabled" : "disabled");
4391   vec_add1 (gpe_status, 0);
4392   vec_add1 (feature_status, 0);
4393
4394   vat_json_init_object (&node);
4395   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4396   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4397
4398   vec_free (gpe_status);
4399   vec_free (feature_status);
4400
4401   vat_json_print (vam->ofp, &node);
4402   vat_json_free (&node);
4403
4404   vam->retval = ntohl (mp->retval);
4405   vam->result_ready = 1;
4406 }
4407
4408 static void
4409   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4410   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4411 {
4412   vat_main_t *vam = &vat_main;
4413   i32 retval = ntohl (mp->retval);
4414
4415   if (retval >= 0)
4416     {
4417       print (vam->ofp, "%=20s", mp->locator_set_name);
4418     }
4419
4420   vam->retval = retval;
4421   vam->result_ready = 1;
4422 }
4423
4424 static void
4425   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4426   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4427 {
4428   vat_main_t *vam = &vat_main;
4429   vat_json_node_t *node = NULL;
4430
4431   if (VAT_JSON_ARRAY != vam->json_tree.type)
4432     {
4433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4434       vat_json_init_array (&vam->json_tree);
4435     }
4436   node = vat_json_array_add (&vam->json_tree);
4437
4438   vat_json_init_object (node);
4439   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4440
4441   vat_json_print (vam->ofp, node);
4442   vat_json_free (node);
4443
4444   vam->retval = ntohl (mp->retval);
4445   vam->result_ready = 1;
4446 }
4447
4448 static u8 *
4449 format_lisp_map_request_mode (u8 * s, va_list * args)
4450 {
4451   u32 mode = va_arg (*args, u32);
4452
4453   switch (mode)
4454     {
4455     case 0:
4456       return format (0, "dst-only");
4457     case 1:
4458       return format (0, "src-dst");
4459     }
4460   return 0;
4461 }
4462
4463 static void
4464   vl_api_show_one_map_request_mode_reply_t_handler
4465   (vl_api_show_one_map_request_mode_reply_t * mp)
4466 {
4467   vat_main_t *vam = &vat_main;
4468   i32 retval = ntohl (mp->retval);
4469
4470   if (0 <= retval)
4471     {
4472       u32 mode = mp->mode;
4473       print (vam->ofp, "map_request_mode: %U",
4474              format_lisp_map_request_mode, mode);
4475     }
4476
4477   vam->retval = retval;
4478   vam->result_ready = 1;
4479 }
4480
4481 static void
4482   vl_api_show_one_map_request_mode_reply_t_handler_json
4483   (vl_api_show_one_map_request_mode_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   vat_json_node_t node;
4487   u8 *s = 0;
4488   u32 mode;
4489
4490   mode = mp->mode;
4491   s = format (0, "%U", format_lisp_map_request_mode, mode);
4492   vec_add1 (s, 0);
4493
4494   vat_json_init_object (&node);
4495   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4496   vat_json_print (vam->ofp, &node);
4497   vat_json_free (&node);
4498
4499   vec_free (s);
4500   vam->retval = ntohl (mp->retval);
4501   vam->result_ready = 1;
4502 }
4503
4504 static void
4505   vl_api_one_show_xtr_mode_reply_t_handler
4506   (vl_api_one_show_xtr_mode_reply_t * mp)
4507 {
4508   vat_main_t *vam = &vat_main;
4509   i32 retval = ntohl (mp->retval);
4510
4511   if (0 <= retval)
4512     {
4513       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4514     }
4515
4516   vam->retval = retval;
4517   vam->result_ready = 1;
4518 }
4519
4520 static void
4521   vl_api_one_show_xtr_mode_reply_t_handler_json
4522   (vl_api_one_show_xtr_mode_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   vat_json_node_t node;
4526   u8 *status = 0;
4527
4528   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4529   vec_add1 (status, 0);
4530
4531   vat_json_init_object (&node);
4532   vat_json_object_add_string_copy (&node, "status", status);
4533
4534   vec_free (status);
4535
4536   vat_json_print (vam->ofp, &node);
4537   vat_json_free (&node);
4538
4539   vam->retval = ntohl (mp->retval);
4540   vam->result_ready = 1;
4541 }
4542
4543 static void
4544   vl_api_one_show_pitr_mode_reply_t_handler
4545   (vl_api_one_show_pitr_mode_reply_t * mp)
4546 {
4547   vat_main_t *vam = &vat_main;
4548   i32 retval = ntohl (mp->retval);
4549
4550   if (0 <= retval)
4551     {
4552       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4553     }
4554
4555   vam->retval = retval;
4556   vam->result_ready = 1;
4557 }
4558
4559 static void
4560   vl_api_one_show_pitr_mode_reply_t_handler_json
4561   (vl_api_one_show_pitr_mode_reply_t * mp)
4562 {
4563   vat_main_t *vam = &vat_main;
4564   vat_json_node_t node;
4565   u8 *status = 0;
4566
4567   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4568   vec_add1 (status, 0);
4569
4570   vat_json_init_object (&node);
4571   vat_json_object_add_string_copy (&node, "status", status);
4572
4573   vec_free (status);
4574
4575   vat_json_print (vam->ofp, &node);
4576   vat_json_free (&node);
4577
4578   vam->retval = ntohl (mp->retval);
4579   vam->result_ready = 1;
4580 }
4581
4582 static void
4583   vl_api_one_show_petr_mode_reply_t_handler
4584   (vl_api_one_show_petr_mode_reply_t * mp)
4585 {
4586   vat_main_t *vam = &vat_main;
4587   i32 retval = ntohl (mp->retval);
4588
4589   if (0 <= retval)
4590     {
4591       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4592     }
4593
4594   vam->retval = retval;
4595   vam->result_ready = 1;
4596 }
4597
4598 static void
4599   vl_api_one_show_petr_mode_reply_t_handler_json
4600   (vl_api_one_show_petr_mode_reply_t * mp)
4601 {
4602   vat_main_t *vam = &vat_main;
4603   vat_json_node_t node;
4604   u8 *status = 0;
4605
4606   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4607   vec_add1 (status, 0);
4608
4609   vat_json_init_object (&node);
4610   vat_json_object_add_string_copy (&node, "status", status);
4611
4612   vec_free (status);
4613
4614   vat_json_print (vam->ofp, &node);
4615   vat_json_free (&node);
4616
4617   vam->retval = ntohl (mp->retval);
4618   vam->result_ready = 1;
4619 }
4620
4621 static void
4622   vl_api_show_one_use_petr_reply_t_handler
4623   (vl_api_show_one_use_petr_reply_t * mp)
4624 {
4625   vat_main_t *vam = &vat_main;
4626   i32 retval = ntohl (mp->retval);
4627
4628   if (0 <= retval)
4629     {
4630       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4631       if (mp->status)
4632         {
4633           print (vam->ofp, "Proxy-ETR address; %U",
4634                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4635                  mp->address);
4636         }
4637     }
4638
4639   vam->retval = retval;
4640   vam->result_ready = 1;
4641 }
4642
4643 static void
4644   vl_api_show_one_use_petr_reply_t_handler_json
4645   (vl_api_show_one_use_petr_reply_t * mp)
4646 {
4647   vat_main_t *vam = &vat_main;
4648   vat_json_node_t node;
4649   u8 *status = 0;
4650   struct in_addr ip4;
4651   struct in6_addr ip6;
4652
4653   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4654   vec_add1 (status, 0);
4655
4656   vat_json_init_object (&node);
4657   vat_json_object_add_string_copy (&node, "status", status);
4658   if (mp->status)
4659     {
4660       if (mp->is_ip4)
4661         {
4662           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4663           vat_json_object_add_ip6 (&node, "address", ip6);
4664         }
4665       else
4666         {
4667           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4668           vat_json_object_add_ip4 (&node, "address", ip4);
4669         }
4670     }
4671
4672   vec_free (status);
4673
4674   vat_json_print (vam->ofp, &node);
4675   vat_json_free (&node);
4676
4677   vam->retval = ntohl (mp->retval);
4678   vam->result_ready = 1;
4679 }
4680
4681 static void
4682   vl_api_show_one_nsh_mapping_reply_t_handler
4683   (vl_api_show_one_nsh_mapping_reply_t * mp)
4684 {
4685   vat_main_t *vam = &vat_main;
4686   i32 retval = ntohl (mp->retval);
4687
4688   if (0 <= retval)
4689     {
4690       print (vam->ofp, "%-20s%-16s",
4691              mp->is_set ? "set" : "not-set",
4692              mp->is_set ? (char *) mp->locator_set_name : "");
4693     }
4694
4695   vam->retval = retval;
4696   vam->result_ready = 1;
4697 }
4698
4699 static void
4700   vl_api_show_one_nsh_mapping_reply_t_handler_json
4701   (vl_api_show_one_nsh_mapping_reply_t * mp)
4702 {
4703   vat_main_t *vam = &vat_main;
4704   vat_json_node_t node;
4705   u8 *status = 0;
4706
4707   status = format (0, "%s", mp->is_set ? "yes" : "no");
4708   vec_add1 (status, 0);
4709
4710   vat_json_init_object (&node);
4711   vat_json_object_add_string_copy (&node, "is_set", status);
4712   if (mp->is_set)
4713     {
4714       vat_json_object_add_string_copy (&node, "locator_set",
4715                                        mp->locator_set_name);
4716     }
4717
4718   vec_free (status);
4719
4720   vat_json_print (vam->ofp, &node);
4721   vat_json_free (&node);
4722
4723   vam->retval = ntohl (mp->retval);
4724   vam->result_ready = 1;
4725 }
4726
4727 static void
4728   vl_api_show_one_map_register_ttl_reply_t_handler
4729   (vl_api_show_one_map_register_ttl_reply_t * mp)
4730 {
4731   vat_main_t *vam = &vat_main;
4732   i32 retval = ntohl (mp->retval);
4733
4734   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4735
4736   if (0 <= retval)
4737     {
4738       print (vam->ofp, "ttl: %u", mp->ttl);
4739     }
4740
4741   vam->retval = retval;
4742   vam->result_ready = 1;
4743 }
4744
4745 static void
4746   vl_api_show_one_map_register_ttl_reply_t_handler_json
4747   (vl_api_show_one_map_register_ttl_reply_t * mp)
4748 {
4749   vat_main_t *vam = &vat_main;
4750   vat_json_node_t node;
4751
4752   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4753   vat_json_init_object (&node);
4754   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4755
4756   vat_json_print (vam->ofp, &node);
4757   vat_json_free (&node);
4758
4759   vam->retval = ntohl (mp->retval);
4760   vam->result_ready = 1;
4761 }
4762
4763 static void
4764 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4765 {
4766   vat_main_t *vam = &vat_main;
4767   i32 retval = ntohl (mp->retval);
4768
4769   if (0 <= retval)
4770     {
4771       print (vam->ofp, "%-20s%-16s",
4772              mp->status ? "enabled" : "disabled",
4773              mp->status ? (char *) mp->locator_set_name : "");
4774     }
4775
4776   vam->retval = retval;
4777   vam->result_ready = 1;
4778 }
4779
4780 static void
4781 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4782 {
4783   vat_main_t *vam = &vat_main;
4784   vat_json_node_t node;
4785   u8 *status = 0;
4786
4787   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4788   vec_add1 (status, 0);
4789
4790   vat_json_init_object (&node);
4791   vat_json_object_add_string_copy (&node, "status", status);
4792   if (mp->status)
4793     {
4794       vat_json_object_add_string_copy (&node, "locator_set",
4795                                        mp->locator_set_name);
4796     }
4797
4798   vec_free (status);
4799
4800   vat_json_print (vam->ofp, &node);
4801   vat_json_free (&node);
4802
4803   vam->retval = ntohl (mp->retval);
4804   vam->result_ready = 1;
4805 }
4806
4807 static u8 *
4808 format_policer_type (u8 * s, va_list * va)
4809 {
4810   u32 i = va_arg (*va, u32);
4811
4812   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4813     s = format (s, "1r2c");
4814   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4815     s = format (s, "1r3c");
4816   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4817     s = format (s, "2r3c-2698");
4818   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4819     s = format (s, "2r3c-4115");
4820   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4821     s = format (s, "2r3c-mef5cf1");
4822   else
4823     s = format (s, "ILLEGAL");
4824   return s;
4825 }
4826
4827 static u8 *
4828 format_policer_rate_type (u8 * s, va_list * va)
4829 {
4830   u32 i = va_arg (*va, u32);
4831
4832   if (i == SSE2_QOS_RATE_KBPS)
4833     s = format (s, "kbps");
4834   else if (i == SSE2_QOS_RATE_PPS)
4835     s = format (s, "pps");
4836   else
4837     s = format (s, "ILLEGAL");
4838   return s;
4839 }
4840
4841 static u8 *
4842 format_policer_round_type (u8 * s, va_list * va)
4843 {
4844   u32 i = va_arg (*va, u32);
4845
4846   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4847     s = format (s, "closest");
4848   else if (i == SSE2_QOS_ROUND_TO_UP)
4849     s = format (s, "up");
4850   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4851     s = format (s, "down");
4852   else
4853     s = format (s, "ILLEGAL");
4854   return s;
4855 }
4856
4857 static u8 *
4858 format_policer_action_type (u8 * s, va_list * va)
4859 {
4860   u32 i = va_arg (*va, u32);
4861
4862   if (i == SSE2_QOS_ACTION_DROP)
4863     s = format (s, "drop");
4864   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4865     s = format (s, "transmit");
4866   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4867     s = format (s, "mark-and-transmit");
4868   else
4869     s = format (s, "ILLEGAL");
4870   return s;
4871 }
4872
4873 static u8 *
4874 format_dscp (u8 * s, va_list * va)
4875 {
4876   u32 i = va_arg (*va, u32);
4877   char *t = 0;
4878
4879   switch (i)
4880     {
4881 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4882       foreach_vnet_dscp
4883 #undef _
4884     default:
4885       return format (s, "ILLEGAL");
4886     }
4887   s = format (s, "%s", t);
4888   return s;
4889 }
4890
4891 static void
4892 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4893 {
4894   vat_main_t *vam = &vat_main;
4895   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4896
4897   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4898     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4899   else
4900     conform_dscp_str = format (0, "");
4901
4902   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4903     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4904   else
4905     exceed_dscp_str = format (0, "");
4906
4907   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4908     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4909   else
4910     violate_dscp_str = format (0, "");
4911
4912   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4913          "rate type %U, round type %U, %s rate, %s color-aware, "
4914          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4915          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4916          "conform action %U%s, exceed action %U%s, violate action %U%s",
4917          mp->name,
4918          format_policer_type, mp->type,
4919          ntohl (mp->cir),
4920          ntohl (mp->eir),
4921          clib_net_to_host_u64 (mp->cb),
4922          clib_net_to_host_u64 (mp->eb),
4923          format_policer_rate_type, mp->rate_type,
4924          format_policer_round_type, mp->round_type,
4925          mp->single_rate ? "single" : "dual",
4926          mp->color_aware ? "is" : "not",
4927          ntohl (mp->cir_tokens_per_period),
4928          ntohl (mp->pir_tokens_per_period),
4929          ntohl (mp->scale),
4930          ntohl (mp->current_limit),
4931          ntohl (mp->current_bucket),
4932          ntohl (mp->extended_limit),
4933          ntohl (mp->extended_bucket),
4934          clib_net_to_host_u64 (mp->last_update_time),
4935          format_policer_action_type, mp->conform_action_type,
4936          conform_dscp_str,
4937          format_policer_action_type, mp->exceed_action_type,
4938          exceed_dscp_str,
4939          format_policer_action_type, mp->violate_action_type,
4940          violate_dscp_str);
4941
4942   vec_free (conform_dscp_str);
4943   vec_free (exceed_dscp_str);
4944   vec_free (violate_dscp_str);
4945 }
4946
4947 static void vl_api_policer_details_t_handler_json
4948   (vl_api_policer_details_t * mp)
4949 {
4950   vat_main_t *vam = &vat_main;
4951   vat_json_node_t *node;
4952   u8 *rate_type_str, *round_type_str, *type_str;
4953   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4954
4955   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4956   round_type_str =
4957     format (0, "%U", format_policer_round_type, mp->round_type);
4958   type_str = format (0, "%U", format_policer_type, mp->type);
4959   conform_action_str = format (0, "%U", format_policer_action_type,
4960                                mp->conform_action_type);
4961   exceed_action_str = format (0, "%U", format_policer_action_type,
4962                               mp->exceed_action_type);
4963   violate_action_str = format (0, "%U", format_policer_action_type,
4964                                mp->violate_action_type);
4965
4966   if (VAT_JSON_ARRAY != vam->json_tree.type)
4967     {
4968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4969       vat_json_init_array (&vam->json_tree);
4970     }
4971   node = vat_json_array_add (&vam->json_tree);
4972
4973   vat_json_init_object (node);
4974   vat_json_object_add_string_copy (node, "name", mp->name);
4975   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4976   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4977   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4978   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4979   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4980   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4981   vat_json_object_add_string_copy (node, "type", type_str);
4982   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4983   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4984   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4985   vat_json_object_add_uint (node, "cir_tokens_per_period",
4986                             ntohl (mp->cir_tokens_per_period));
4987   vat_json_object_add_uint (node, "eir_tokens_per_period",
4988                             ntohl (mp->pir_tokens_per_period));
4989   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4990   vat_json_object_add_uint (node, "current_bucket",
4991                             ntohl (mp->current_bucket));
4992   vat_json_object_add_uint (node, "extended_limit",
4993                             ntohl (mp->extended_limit));
4994   vat_json_object_add_uint (node, "extended_bucket",
4995                             ntohl (mp->extended_bucket));
4996   vat_json_object_add_uint (node, "last_update_time",
4997                             ntohl (mp->last_update_time));
4998   vat_json_object_add_string_copy (node, "conform_action",
4999                                    conform_action_str);
5000   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5001     {
5002       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5003       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5004       vec_free (dscp_str);
5005     }
5006   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5007   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5008     {
5009       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5010       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5011       vec_free (dscp_str);
5012     }
5013   vat_json_object_add_string_copy (node, "violate_action",
5014                                    violate_action_str);
5015   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5016     {
5017       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5018       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5019       vec_free (dscp_str);
5020     }
5021
5022   vec_free (rate_type_str);
5023   vec_free (round_type_str);
5024   vec_free (type_str);
5025   vec_free (conform_action_str);
5026   vec_free (exceed_action_str);
5027   vec_free (violate_action_str);
5028 }
5029
5030 static void
5031 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5032                                            mp)
5033 {
5034   vat_main_t *vam = &vat_main;
5035   int i, count = ntohl (mp->count);
5036
5037   if (count > 0)
5038     print (vam->ofp, "classify table ids (%d) : ", count);
5039   for (i = 0; i < count; i++)
5040     {
5041       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5042       print (vam->ofp, (i < count - 1) ? "," : "");
5043     }
5044   vam->retval = ntohl (mp->retval);
5045   vam->result_ready = 1;
5046 }
5047
5048 static void
5049   vl_api_classify_table_ids_reply_t_handler_json
5050   (vl_api_classify_table_ids_reply_t * mp)
5051 {
5052   vat_main_t *vam = &vat_main;
5053   int i, count = ntohl (mp->count);
5054
5055   if (count > 0)
5056     {
5057       vat_json_node_t node;
5058
5059       vat_json_init_object (&node);
5060       for (i = 0; i < count; i++)
5061         {
5062           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5063         }
5064       vat_json_print (vam->ofp, &node);
5065       vat_json_free (&node);
5066     }
5067   vam->retval = ntohl (mp->retval);
5068   vam->result_ready = 1;
5069 }
5070
5071 static void
5072   vl_api_classify_table_by_interface_reply_t_handler
5073   (vl_api_classify_table_by_interface_reply_t * mp)
5074 {
5075   vat_main_t *vam = &vat_main;
5076   u32 table_id;
5077
5078   table_id = ntohl (mp->l2_table_id);
5079   if (table_id != ~0)
5080     print (vam->ofp, "l2 table id : %d", table_id);
5081   else
5082     print (vam->ofp, "l2 table id : No input ACL tables configured");
5083   table_id = ntohl (mp->ip4_table_id);
5084   if (table_id != ~0)
5085     print (vam->ofp, "ip4 table id : %d", table_id);
5086   else
5087     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5088   table_id = ntohl (mp->ip6_table_id);
5089   if (table_id != ~0)
5090     print (vam->ofp, "ip6 table id : %d", table_id);
5091   else
5092     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5093   vam->retval = ntohl (mp->retval);
5094   vam->result_ready = 1;
5095 }
5096
5097 static void
5098   vl_api_classify_table_by_interface_reply_t_handler_json
5099   (vl_api_classify_table_by_interface_reply_t * mp)
5100 {
5101   vat_main_t *vam = &vat_main;
5102   vat_json_node_t node;
5103
5104   vat_json_init_object (&node);
5105
5106   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5107   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5108   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5109
5110   vat_json_print (vam->ofp, &node);
5111   vat_json_free (&node);
5112
5113   vam->retval = ntohl (mp->retval);
5114   vam->result_ready = 1;
5115 }
5116
5117 static void vl_api_policer_add_del_reply_t_handler
5118   (vl_api_policer_add_del_reply_t * mp)
5119 {
5120   vat_main_t *vam = &vat_main;
5121   i32 retval = ntohl (mp->retval);
5122   if (vam->async_mode)
5123     {
5124       vam->async_errors += (retval < 0);
5125     }
5126   else
5127     {
5128       vam->retval = retval;
5129       vam->result_ready = 1;
5130       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5131         /*
5132          * Note: this is just barely thread-safe, depends on
5133          * the main thread spinning waiting for an answer...
5134          */
5135         errmsg ("policer index %d", ntohl (mp->policer_index));
5136     }
5137 }
5138
5139 static void vl_api_policer_add_del_reply_t_handler_json
5140   (vl_api_policer_add_del_reply_t * mp)
5141 {
5142   vat_main_t *vam = &vat_main;
5143   vat_json_node_t node;
5144
5145   vat_json_init_object (&node);
5146   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5147   vat_json_object_add_uint (&node, "policer_index",
5148                             ntohl (mp->policer_index));
5149
5150   vat_json_print (vam->ofp, &node);
5151   vat_json_free (&node);
5152
5153   vam->retval = ntohl (mp->retval);
5154   vam->result_ready = 1;
5155 }
5156
5157 /* Format hex dump. */
5158 u8 *
5159 format_hex_bytes (u8 * s, va_list * va)
5160 {
5161   u8 *bytes = va_arg (*va, u8 *);
5162   int n_bytes = va_arg (*va, int);
5163   uword i;
5164
5165   /* Print short or long form depending on byte count. */
5166   uword short_form = n_bytes <= 32;
5167   u32 indent = format_get_indent (s);
5168
5169   if (n_bytes == 0)
5170     return s;
5171
5172   for (i = 0; i < n_bytes; i++)
5173     {
5174       if (!short_form && (i % 32) == 0)
5175         s = format (s, "%08x: ", i);
5176       s = format (s, "%02x", bytes[i]);
5177       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5178         s = format (s, "\n%U", format_white_space, indent);
5179     }
5180
5181   return s;
5182 }
5183
5184 static void
5185 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5186                                             * mp)
5187 {
5188   vat_main_t *vam = &vat_main;
5189   i32 retval = ntohl (mp->retval);
5190   if (retval == 0)
5191     {
5192       print (vam->ofp, "classify table info :");
5193       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5194              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5195              ntohl (mp->miss_next_index));
5196       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5197              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5198              ntohl (mp->match_n_vectors));
5199       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5200              ntohl (mp->mask_length));
5201     }
5202   vam->retval = retval;
5203   vam->result_ready = 1;
5204 }
5205
5206 static void
5207   vl_api_classify_table_info_reply_t_handler_json
5208   (vl_api_classify_table_info_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sessions",
5219                                ntohl (mp->active_sessions));
5220       vat_json_object_add_int (&node, "nexttbl",
5221                                ntohl (mp->next_table_index));
5222       vat_json_object_add_int (&node, "nextnode",
5223                                ntohl (mp->miss_next_index));
5224       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5225       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5226       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5227       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5228                       ntohl (mp->mask_length), 0);
5229       vat_json_object_add_string_copy (&node, "mask", s);
5230
5231       vat_json_print (vam->ofp, &node);
5232       vat_json_free (&node);
5233     }
5234   vam->retval = ntohl (mp->retval);
5235   vam->result_ready = 1;
5236 }
5237
5238 static void
5239 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5240                                            mp)
5241 {
5242   vat_main_t *vam = &vat_main;
5243
5244   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5245          ntohl (mp->hit_next_index), ntohl (mp->advance),
5246          ntohl (mp->opaque_index));
5247   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5248          ntohl (mp->match_length));
5249 }
5250
5251 static void
5252   vl_api_classify_session_details_t_handler_json
5253   (vl_api_classify_session_details_t * mp)
5254 {
5255   vat_main_t *vam = &vat_main;
5256   vat_json_node_t *node = NULL;
5257
5258   if (VAT_JSON_ARRAY != vam->json_tree.type)
5259     {
5260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5261       vat_json_init_array (&vam->json_tree);
5262     }
5263   node = vat_json_array_add (&vam->json_tree);
5264
5265   vat_json_init_object (node);
5266   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5267   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5268   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5269   u8 *s =
5270     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5271             0);
5272   vat_json_object_add_string_copy (node, "match", s);
5273 }
5274
5275 static void vl_api_pg_create_interface_reply_t_handler
5276   (vl_api_pg_create_interface_reply_t * mp)
5277 {
5278   vat_main_t *vam = &vat_main;
5279
5280   vam->retval = ntohl (mp->retval);
5281   vam->result_ready = 1;
5282 }
5283
5284 static void vl_api_pg_create_interface_reply_t_handler_json
5285   (vl_api_pg_create_interface_reply_t * mp)
5286 {
5287   vat_main_t *vam = &vat_main;
5288   vat_json_node_t node;
5289
5290   i32 retval = ntohl (mp->retval);
5291   if (retval == 0)
5292     {
5293       vat_json_init_object (&node);
5294
5295       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5296
5297       vat_json_print (vam->ofp, &node);
5298       vat_json_free (&node);
5299     }
5300   vam->retval = ntohl (mp->retval);
5301   vam->result_ready = 1;
5302 }
5303
5304 static void vl_api_policer_classify_details_t_handler
5305   (vl_api_policer_classify_details_t * mp)
5306 {
5307   vat_main_t *vam = &vat_main;
5308
5309   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5310          ntohl (mp->table_index));
5311 }
5312
5313 static void vl_api_policer_classify_details_t_handler_json
5314   (vl_api_policer_classify_details_t * mp)
5315 {
5316   vat_main_t *vam = &vat_main;
5317   vat_json_node_t *node;
5318
5319   if (VAT_JSON_ARRAY != vam->json_tree.type)
5320     {
5321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5322       vat_json_init_array (&vam->json_tree);
5323     }
5324   node = vat_json_array_add (&vam->json_tree);
5325
5326   vat_json_init_object (node);
5327   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5328   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5329 }
5330
5331 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5332   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5333 {
5334   vat_main_t *vam = &vat_main;
5335   i32 retval = ntohl (mp->retval);
5336   if (vam->async_mode)
5337     {
5338       vam->async_errors += (retval < 0);
5339     }
5340   else
5341     {
5342       vam->retval = retval;
5343       vam->sw_if_index = ntohl (mp->sw_if_index);
5344       vam->result_ready = 1;
5345     }
5346   vam->regenerate_interface_table = 1;
5347 }
5348
5349 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5350   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5351 {
5352   vat_main_t *vam = &vat_main;
5353   vat_json_node_t node;
5354
5355   vat_json_init_object (&node);
5356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5357   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5358
5359   vat_json_print (vam->ofp, &node);
5360   vat_json_free (&node);
5361
5362   vam->retval = ntohl (mp->retval);
5363   vam->result_ready = 1;
5364 }
5365
5366 static void vl_api_flow_classify_details_t_handler
5367   (vl_api_flow_classify_details_t * mp)
5368 {
5369   vat_main_t *vam = &vat_main;
5370
5371   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5372          ntohl (mp->table_index));
5373 }
5374
5375 static void vl_api_flow_classify_details_t_handler_json
5376   (vl_api_flow_classify_details_t * mp)
5377 {
5378   vat_main_t *vam = &vat_main;
5379   vat_json_node_t *node;
5380
5381   if (VAT_JSON_ARRAY != vam->json_tree.type)
5382     {
5383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5384       vat_json_init_array (&vam->json_tree);
5385     }
5386   node = vat_json_array_add (&vam->json_tree);
5387
5388   vat_json_init_object (node);
5389   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5390   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5391 }
5392
5393 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5394 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5395 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5396 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5397 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5398 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5399 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5400 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5401 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5402 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5403 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5404 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5405 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5406 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5407 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5408 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5409 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5410 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5411 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5412 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5413 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5414 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5415
5416 /*
5417  * Generate boilerplate reply handlers, which
5418  * dig the return value out of the xxx_reply_t API message,
5419  * stick it into vam->retval, and set vam->result_ready
5420  *
5421  * Could also do this by pointing N message decode slots at
5422  * a single function, but that could break in subtle ways.
5423  */
5424
5425 #define foreach_standard_reply_retval_handler           \
5426 _(sw_interface_set_flags_reply)                         \
5427 _(sw_interface_add_del_address_reply)                   \
5428 _(sw_interface_set_rx_mode_reply)                       \
5429 _(sw_interface_set_rx_placement_reply)                  \
5430 _(sw_interface_set_table_reply)                         \
5431 _(sw_interface_set_mpls_enable_reply)                   \
5432 _(sw_interface_set_vpath_reply)                         \
5433 _(sw_interface_set_vxlan_bypass_reply)                  \
5434 _(sw_interface_set_geneve_bypass_reply)                 \
5435 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5436 _(sw_interface_set_l2_bridge_reply)                     \
5437 _(bridge_domain_add_del_reply)                          \
5438 _(sw_interface_set_l2_xconnect_reply)                   \
5439 _(l2fib_add_del_reply)                                  \
5440 _(l2fib_flush_int_reply)                                \
5441 _(l2fib_flush_bd_reply)                                 \
5442 _(ip_add_del_route_reply)                               \
5443 _(ip_table_add_del_reply)                               \
5444 _(ip_mroute_add_del_reply)                              \
5445 _(mpls_route_add_del_reply)                             \
5446 _(mpls_table_add_del_reply)                             \
5447 _(mpls_ip_bind_unbind_reply)                            \
5448 _(bier_route_add_del_reply)                             \
5449 _(bier_table_add_del_reply)                             \
5450 _(proxy_arp_add_del_reply)                              \
5451 _(proxy_arp_intfc_enable_disable_reply)                 \
5452 _(sw_interface_set_unnumbered_reply)                    \
5453 _(ip_neighbor_add_del_reply)                            \
5454 _(oam_add_del_reply)                                    \
5455 _(reset_fib_reply)                                      \
5456 _(dhcp_proxy_config_reply)                              \
5457 _(dhcp_proxy_set_vss_reply)                             \
5458 _(dhcp_client_config_reply)                             \
5459 _(set_ip_flow_hash_reply)                               \
5460 _(sw_interface_ip6_enable_disable_reply)                \
5461 _(sw_interface_ip6_set_link_local_address_reply)        \
5462 _(ip6nd_proxy_add_del_reply)                            \
5463 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5464 _(sw_interface_ip6nd_ra_config_reply)                   \
5465 _(set_arp_neighbor_limit_reply)                         \
5466 _(l2_patch_add_del_reply)                               \
5467 _(sr_mpls_policy_add_reply)                             \
5468 _(sr_mpls_policy_mod_reply)                             \
5469 _(sr_mpls_policy_del_reply)                             \
5470 _(sr_policy_add_reply)                                  \
5471 _(sr_policy_mod_reply)                                  \
5472 _(sr_policy_del_reply)                                  \
5473 _(sr_localsid_add_del_reply)                            \
5474 _(sr_steering_add_del_reply)                            \
5475 _(classify_add_del_session_reply)                       \
5476 _(classify_set_interface_ip_table_reply)                \
5477 _(classify_set_interface_l2_tables_reply)               \
5478 _(l2tpv3_set_tunnel_cookies_reply)                      \
5479 _(l2tpv3_interface_enable_disable_reply)                \
5480 _(l2tpv3_set_lookup_key_reply)                          \
5481 _(l2_fib_clear_table_reply)                             \
5482 _(l2_interface_efp_filter_reply)                        \
5483 _(l2_interface_vlan_tag_rewrite_reply)                  \
5484 _(modify_vhost_user_if_reply)                           \
5485 _(delete_vhost_user_if_reply)                           \
5486 _(ip_probe_neighbor_reply)                              \
5487 _(ip_scan_neighbor_enable_disable_reply)                \
5488 _(want_ip4_arp_events_reply)                            \
5489 _(want_ip6_nd_events_reply)                             \
5490 _(want_l2_macs_events_reply)                            \
5491 _(input_acl_set_interface_reply)                        \
5492 _(ipsec_spd_add_del_reply)                              \
5493 _(ipsec_interface_add_del_spd_reply)                    \
5494 _(ipsec_spd_add_del_entry_reply)                        \
5495 _(ipsec_sad_add_del_entry_reply)                        \
5496 _(ipsec_sa_set_key_reply)                               \
5497 _(ipsec_tunnel_if_add_del_reply)                        \
5498 _(ipsec_tunnel_if_set_key_reply)                        \
5499 _(ipsec_tunnel_if_set_sa_reply)                         \
5500 _(ikev2_profile_add_del_reply)                          \
5501 _(ikev2_profile_set_auth_reply)                         \
5502 _(ikev2_profile_set_id_reply)                           \
5503 _(ikev2_profile_set_ts_reply)                           \
5504 _(ikev2_set_local_key_reply)                            \
5505 _(ikev2_set_responder_reply)                            \
5506 _(ikev2_set_ike_transforms_reply)                       \
5507 _(ikev2_set_esp_transforms_reply)                       \
5508 _(ikev2_set_sa_lifetime_reply)                          \
5509 _(ikev2_initiate_sa_init_reply)                         \
5510 _(ikev2_initiate_del_ike_sa_reply)                      \
5511 _(ikev2_initiate_del_child_sa_reply)                    \
5512 _(ikev2_initiate_rekey_child_sa_reply)                  \
5513 _(delete_loopback_reply)                                \
5514 _(bd_ip_mac_add_del_reply)                              \
5515 _(want_interface_events_reply)                          \
5516 _(want_stats_reply)                                     \
5517 _(cop_interface_enable_disable_reply)                   \
5518 _(cop_whitelist_enable_disable_reply)                   \
5519 _(sw_interface_clear_stats_reply)                       \
5520 _(ioam_enable_reply)                                    \
5521 _(ioam_disable_reply)                                   \
5522 _(one_add_del_locator_reply)                            \
5523 _(one_add_del_local_eid_reply)                          \
5524 _(one_add_del_remote_mapping_reply)                     \
5525 _(one_add_del_adjacency_reply)                          \
5526 _(one_add_del_map_resolver_reply)                       \
5527 _(one_add_del_map_server_reply)                         \
5528 _(one_enable_disable_reply)                             \
5529 _(one_rloc_probe_enable_disable_reply)                  \
5530 _(one_map_register_enable_disable_reply)                \
5531 _(one_map_register_set_ttl_reply)                       \
5532 _(one_set_transport_protocol_reply)                     \
5533 _(one_map_register_fallback_threshold_reply)            \
5534 _(one_pitr_set_locator_set_reply)                       \
5535 _(one_map_request_mode_reply)                           \
5536 _(one_add_del_map_request_itr_rlocs_reply)              \
5537 _(one_eid_table_add_del_map_reply)                      \
5538 _(one_use_petr_reply)                                   \
5539 _(one_stats_enable_disable_reply)                       \
5540 _(one_add_del_l2_arp_entry_reply)                       \
5541 _(one_add_del_ndp_entry_reply)                          \
5542 _(one_stats_flush_reply)                                \
5543 _(one_enable_disable_xtr_mode_reply)                    \
5544 _(one_enable_disable_pitr_mode_reply)                   \
5545 _(one_enable_disable_petr_mode_reply)                   \
5546 _(gpe_enable_disable_reply)                             \
5547 _(gpe_set_encap_mode_reply)                             \
5548 _(gpe_add_del_iface_reply)                              \
5549 _(gpe_add_del_native_fwd_rpath_reply)                   \
5550 _(af_packet_delete_reply)                               \
5551 _(policer_classify_set_interface_reply)                 \
5552 _(netmap_create_reply)                                  \
5553 _(netmap_delete_reply)                                  \
5554 _(set_ipfix_exporter_reply)                             \
5555 _(set_ipfix_classify_stream_reply)                      \
5556 _(ipfix_classify_table_add_del_reply)                   \
5557 _(flow_classify_set_interface_reply)                    \
5558 _(sw_interface_span_enable_disable_reply)               \
5559 _(pg_capture_reply)                                     \
5560 _(pg_enable_disable_reply)                              \
5561 _(ip_source_and_port_range_check_add_del_reply)         \
5562 _(ip_source_and_port_range_check_interface_add_del_reply)\
5563 _(delete_subif_reply)                                   \
5564 _(l2_interface_pbb_tag_rewrite_reply)                   \
5565 _(punt_reply)                                           \
5566 _(feature_enable_disable_reply)                         \
5567 _(sw_interface_tag_add_del_reply)                       \
5568 _(hw_interface_set_mtu_reply)                           \
5569 _(p2p_ethernet_add_reply)                               \
5570 _(p2p_ethernet_del_reply)                               \
5571 _(lldp_config_reply)                                    \
5572 _(sw_interface_set_lldp_reply)                          \
5573 _(tcp_configure_src_addresses_reply)                    \
5574 _(dns_enable_disable_reply)                             \
5575 _(dns_name_server_add_del_reply)                        \
5576 _(session_rule_add_del_reply)                           \
5577 _(ip_container_proxy_add_del_reply)                     \
5578 _(output_acl_set_interface_reply)                       \
5579 _(qos_record_enable_disable_reply)
5580
5581 #define _(n)                                    \
5582     static void vl_api_##n##_t_handler          \
5583     (vl_api_##n##_t * mp)                       \
5584     {                                           \
5585         vat_main_t * vam = &vat_main;           \
5586         i32 retval = ntohl(mp->retval);         \
5587         if (vam->async_mode) {                  \
5588             vam->async_errors += (retval < 0);  \
5589         } else {                                \
5590             vam->retval = retval;               \
5591             vam->result_ready = 1;              \
5592         }                                       \
5593     }
5594 foreach_standard_reply_retval_handler;
5595 #undef _
5596
5597 #define _(n)                                    \
5598     static void vl_api_##n##_t_handler_json     \
5599     (vl_api_##n##_t * mp)                       \
5600     {                                           \
5601         vat_main_t * vam = &vat_main;           \
5602         vat_json_node_t node;                   \
5603         vat_json_init_object(&node);            \
5604         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5605         vat_json_print(vam->ofp, &node);        \
5606         vam->retval = ntohl(mp->retval);        \
5607         vam->result_ready = 1;                  \
5608     }
5609 foreach_standard_reply_retval_handler;
5610 #undef _
5611
5612 /*
5613  * Table of message reply handlers, must include boilerplate handlers
5614  * we just generated
5615  */
5616
5617 #define foreach_vpe_api_reply_msg                                       \
5618 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5619 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5620 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5621 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5622 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5623 _(CLI_REPLY, cli_reply)                                                 \
5624 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5625 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5626   sw_interface_add_del_address_reply)                                   \
5627 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5628 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5629 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5630 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5631 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5632 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5633 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5634 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5635 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5636 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5637   sw_interface_set_l2_xconnect_reply)                                   \
5638 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5639   sw_interface_set_l2_bridge_reply)                                     \
5640 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5641 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5642 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5643 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5644 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5645 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5646 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5647 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5648 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5649 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5650 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5651 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5652 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5653 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5654 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5655 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5656 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5657 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5658 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5659 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5660 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5661 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5662 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5663 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5664 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5665 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5666 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5667 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5668 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5669 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5670 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5671   proxy_arp_intfc_enable_disable_reply)                                 \
5672 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5673 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5674   sw_interface_set_unnumbered_reply)                                    \
5675 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5676 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5677 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5678 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5679 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5680 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5681 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5682 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5683 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5684 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5685 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5686   sw_interface_ip6_enable_disable_reply)                                \
5687 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5688   sw_interface_ip6_set_link_local_address_reply)                        \
5689 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5690 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5691 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5692   sw_interface_ip6nd_ra_prefix_reply)                                   \
5693 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5694   sw_interface_ip6nd_ra_config_reply)                                   \
5695 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5696 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5697 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5698 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5699 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5700 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5701 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5702 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5703 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5704 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5705 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5706 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5707 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5708 classify_set_interface_ip_table_reply)                                  \
5709 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5710   classify_set_interface_l2_tables_reply)                               \
5711 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5712 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5713 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5714 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5715 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5716   l2tpv3_interface_enable_disable_reply)                                \
5717 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5718 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5719 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5720 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5721 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5722 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5723 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5724 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5725 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5726 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5727 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5728 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5729 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5730 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5731 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5732 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5733 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5734 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5735 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5736 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5737 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5738 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5739 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5740 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5741 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5742 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5743 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5744 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5745 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5746 _(L2_MACS_EVENT, l2_macs_event)                                         \
5747 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5748 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5749 _(IP_DETAILS, ip_details)                                               \
5750 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5751 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5752 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5753 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5754 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5755 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5756 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5757 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5758 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5759 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5760 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5761 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5762 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5763 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5764 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5765 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5766 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5767 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5768 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5769 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5770 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5771 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5772 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5773 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5774 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5775 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5776 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5777 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5778 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5779 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5780 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5781 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5782 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5783 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5784 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5785 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5786 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5787 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5788 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5789 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5790 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5791 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5792 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5793 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5794   one_map_register_enable_disable_reply)                                \
5795 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5796 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5797 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5798 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5799   one_map_register_fallback_threshold_reply)                            \
5800 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5801   one_rloc_probe_enable_disable_reply)                                  \
5802 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5803 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5804 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5805 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5806 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5807 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5808 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5809 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5810 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5811 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5812 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5813 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5814 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5815 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5816 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5817 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5818   show_one_stats_enable_disable_reply)                                  \
5819 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5820 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5821 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5822 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5823 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5824 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5825 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5826 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5827   one_enable_disable_pitr_mode_reply)                                   \
5828 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5829   one_enable_disable_petr_mode_reply)                                   \
5830 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5831 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5832 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5833 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5834 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5835 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5836 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5837 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5838 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5839 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5840 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5841 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5842   gpe_add_del_native_fwd_rpath_reply)                                   \
5843 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5844   gpe_fwd_entry_path_details)                                           \
5845 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5846 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5847   one_add_del_map_request_itr_rlocs_reply)                              \
5848 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5849   one_get_map_request_itr_rlocs_reply)                                  \
5850 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5851 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5852 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5853 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5854 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5855 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5856   show_one_map_register_state_reply)                                    \
5857 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5858 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5859   show_one_map_register_fallback_threshold_reply)                       \
5860 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5861 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5862 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5863 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5864 _(POLICER_DETAILS, policer_details)                                     \
5865 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5866 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5867 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5868 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5869 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5870 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5871 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5872 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5873 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5874 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5875 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5876 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5877 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5878 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5879 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5880 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5881 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5882 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5883 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5884 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5885 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5886 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5887 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5888 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5889 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5890  ip_source_and_port_range_check_add_del_reply)                          \
5891 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5892  ip_source_and_port_range_check_interface_add_del_reply)                \
5893 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5894 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5895 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5896 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5897 _(PUNT_REPLY, punt_reply)                                               \
5898 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5899 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5900 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5901 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5902 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5903 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5904 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5905 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5906 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5907 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5908 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5909 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5910 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5911 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5912 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5913 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5914 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5915 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5916 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5917 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5918 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5919 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5920 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5921
5922 #define foreach_standalone_reply_msg                                    \
5923 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5924 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5925 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5926 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5927 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5928 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5929 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5930
5931 typedef struct
5932 {
5933   u8 *name;
5934   u32 value;
5935 } name_sort_t;
5936
5937 #define STR_VTR_OP_CASE(op)     \
5938     case L2_VTR_ ## op:         \
5939         return "" # op;
5940
5941 static const char *
5942 str_vtr_op (u32 vtr_op)
5943 {
5944   switch (vtr_op)
5945     {
5946       STR_VTR_OP_CASE (DISABLED);
5947       STR_VTR_OP_CASE (PUSH_1);
5948       STR_VTR_OP_CASE (PUSH_2);
5949       STR_VTR_OP_CASE (POP_1);
5950       STR_VTR_OP_CASE (POP_2);
5951       STR_VTR_OP_CASE (TRANSLATE_1_1);
5952       STR_VTR_OP_CASE (TRANSLATE_1_2);
5953       STR_VTR_OP_CASE (TRANSLATE_2_1);
5954       STR_VTR_OP_CASE (TRANSLATE_2_2);
5955     }
5956
5957   return "UNKNOWN";
5958 }
5959
5960 static int
5961 dump_sub_interface_table (vat_main_t * vam)
5962 {
5963   const sw_interface_subif_t *sub = NULL;
5964
5965   if (vam->json_output)
5966     {
5967       clib_warning
5968         ("JSON output supported only for VPE API calls and dump_stats_table");
5969       return -99;
5970     }
5971
5972   print (vam->ofp,
5973          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5974          "Interface", "sw_if_index",
5975          "sub id", "dot1ad", "tags", "outer id",
5976          "inner id", "exact", "default", "outer any", "inner any");
5977
5978   vec_foreach (sub, vam->sw_if_subif_table)
5979   {
5980     print (vam->ofp,
5981            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5982            sub->interface_name,
5983            sub->sw_if_index,
5984            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5985            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5986            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5987            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5988     if (sub->vtr_op != L2_VTR_DISABLED)
5989       {
5990         print (vam->ofp,
5991                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5992                "tag1: %d tag2: %d ]",
5993                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5994                sub->vtr_tag1, sub->vtr_tag2);
5995       }
5996   }
5997
5998   return 0;
5999 }
6000
6001 static int
6002 name_sort_cmp (void *a1, void *a2)
6003 {
6004   name_sort_t *n1 = a1;
6005   name_sort_t *n2 = a2;
6006
6007   return strcmp ((char *) n1->name, (char *) n2->name);
6008 }
6009
6010 static int
6011 dump_interface_table (vat_main_t * vam)
6012 {
6013   hash_pair_t *p;
6014   name_sort_t *nses = 0, *ns;
6015
6016   if (vam->json_output)
6017     {
6018       clib_warning
6019         ("JSON output supported only for VPE API calls and dump_stats_table");
6020       return -99;
6021     }
6022
6023   /* *INDENT-OFF* */
6024   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6025   ({
6026     vec_add2 (nses, ns, 1);
6027     ns->name = (u8 *)(p->key);
6028     ns->value = (u32) p->value[0];
6029   }));
6030   /* *INDENT-ON* */
6031
6032   vec_sort_with_function (nses, name_sort_cmp);
6033
6034   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6035   vec_foreach (ns, nses)
6036   {
6037     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6038   }
6039   vec_free (nses);
6040   return 0;
6041 }
6042
6043 static int
6044 dump_ip_table (vat_main_t * vam, int is_ipv6)
6045 {
6046   const ip_details_t *det = NULL;
6047   const ip_address_details_t *address = NULL;
6048   u32 i = ~0;
6049
6050   print (vam->ofp, "%-12s", "sw_if_index");
6051
6052   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6053   {
6054     i++;
6055     if (!det->present)
6056       {
6057         continue;
6058       }
6059     print (vam->ofp, "%-12d", i);
6060     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6061     if (!det->addr)
6062       {
6063         continue;
6064       }
6065     vec_foreach (address, det->addr)
6066     {
6067       print (vam->ofp,
6068              "            %-30U%-13d",
6069              is_ipv6 ? format_ip6_address : format_ip4_address,
6070              address->ip, address->prefix_length);
6071     }
6072   }
6073
6074   return 0;
6075 }
6076
6077 static int
6078 dump_ipv4_table (vat_main_t * vam)
6079 {
6080   if (vam->json_output)
6081     {
6082       clib_warning
6083         ("JSON output supported only for VPE API calls and dump_stats_table");
6084       return -99;
6085     }
6086
6087   return dump_ip_table (vam, 0);
6088 }
6089
6090 static int
6091 dump_ipv6_table (vat_main_t * vam)
6092 {
6093   if (vam->json_output)
6094     {
6095       clib_warning
6096         ("JSON output supported only for VPE API calls and dump_stats_table");
6097       return -99;
6098     }
6099
6100   return dump_ip_table (vam, 1);
6101 }
6102
6103 static char *
6104 counter_type_to_str (u8 counter_type, u8 is_combined)
6105 {
6106   if (!is_combined)
6107     {
6108       switch (counter_type)
6109         {
6110         case VNET_INTERFACE_COUNTER_DROP:
6111           return "drop";
6112         case VNET_INTERFACE_COUNTER_PUNT:
6113           return "punt";
6114         case VNET_INTERFACE_COUNTER_IP4:
6115           return "ip4";
6116         case VNET_INTERFACE_COUNTER_IP6:
6117           return "ip6";
6118         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6119           return "rx-no-buf";
6120         case VNET_INTERFACE_COUNTER_RX_MISS:
6121           return "rx-miss";
6122         case VNET_INTERFACE_COUNTER_RX_ERROR:
6123           return "rx-error";
6124         case VNET_INTERFACE_COUNTER_TX_ERROR:
6125           return "tx-error";
6126         default:
6127           return "INVALID-COUNTER-TYPE";
6128         }
6129     }
6130   else
6131     {
6132       switch (counter_type)
6133         {
6134         case VNET_INTERFACE_COUNTER_RX:
6135           return "rx";
6136         case VNET_INTERFACE_COUNTER_TX:
6137           return "tx";
6138         default:
6139           return "INVALID-COUNTER-TYPE";
6140         }
6141     }
6142 }
6143
6144 static int
6145 dump_stats_table (vat_main_t * vam)
6146 {
6147   vat_json_node_t node;
6148   vat_json_node_t *msg_array;
6149   vat_json_node_t *msg;
6150   vat_json_node_t *counter_array;
6151   vat_json_node_t *counter;
6152   interface_counter_t c;
6153   u64 packets;
6154   ip4_fib_counter_t *c4;
6155   ip6_fib_counter_t *c6;
6156   ip4_nbr_counter_t *n4;
6157   ip6_nbr_counter_t *n6;
6158   int i, j;
6159
6160   if (!vam->json_output)
6161     {
6162       clib_warning ("dump_stats_table supported only in JSON format");
6163       return -99;
6164     }
6165
6166   vat_json_init_object (&node);
6167
6168   /* interface counters */
6169   msg_array = vat_json_object_add (&node, "interface_counters");
6170   vat_json_init_array (msg_array);
6171   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6172     {
6173       msg = vat_json_array_add (msg_array);
6174       vat_json_init_object (msg);
6175       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6176                                        (u8 *) counter_type_to_str (i, 0));
6177       vat_json_object_add_int (msg, "is_combined", 0);
6178       counter_array = vat_json_object_add (msg, "data");
6179       vat_json_init_array (counter_array);
6180       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6181         {
6182           packets = vam->simple_interface_counters[i][j];
6183           vat_json_array_add_uint (counter_array, packets);
6184         }
6185     }
6186   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6187     {
6188       msg = vat_json_array_add (msg_array);
6189       vat_json_init_object (msg);
6190       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6191                                        (u8 *) counter_type_to_str (i, 1));
6192       vat_json_object_add_int (msg, "is_combined", 1);
6193       counter_array = vat_json_object_add (msg, "data");
6194       vat_json_init_array (counter_array);
6195       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6196         {
6197           c = vam->combined_interface_counters[i][j];
6198           counter = vat_json_array_add (counter_array);
6199           vat_json_init_object (counter);
6200           vat_json_object_add_uint (counter, "packets", c.packets);
6201           vat_json_object_add_uint (counter, "bytes", c.bytes);
6202         }
6203     }
6204
6205   /* ip4 fib counters */
6206   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6207   vat_json_init_array (msg_array);
6208   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6209     {
6210       msg = vat_json_array_add (msg_array);
6211       vat_json_init_object (msg);
6212       vat_json_object_add_uint (msg, "vrf_id",
6213                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6214       counter_array = vat_json_object_add (msg, "c");
6215       vat_json_init_array (counter_array);
6216       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6217         {
6218           counter = vat_json_array_add (counter_array);
6219           vat_json_init_object (counter);
6220           c4 = &vam->ip4_fib_counters[i][j];
6221           vat_json_object_add_ip4 (counter, "address", c4->address);
6222           vat_json_object_add_uint (counter, "address_length",
6223                                     c4->address_length);
6224           vat_json_object_add_uint (counter, "packets", c4->packets);
6225           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6226         }
6227     }
6228
6229   /* ip6 fib counters */
6230   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6231   vat_json_init_array (msg_array);
6232   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6233     {
6234       msg = vat_json_array_add (msg_array);
6235       vat_json_init_object (msg);
6236       vat_json_object_add_uint (msg, "vrf_id",
6237                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6238       counter_array = vat_json_object_add (msg, "c");
6239       vat_json_init_array (counter_array);
6240       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6241         {
6242           counter = vat_json_array_add (counter_array);
6243           vat_json_init_object (counter);
6244           c6 = &vam->ip6_fib_counters[i][j];
6245           vat_json_object_add_ip6 (counter, "address", c6->address);
6246           vat_json_object_add_uint (counter, "address_length",
6247                                     c6->address_length);
6248           vat_json_object_add_uint (counter, "packets", c6->packets);
6249           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6250         }
6251     }
6252
6253   /* ip4 nbr counters */
6254   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6255   vat_json_init_array (msg_array);
6256   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6257     {
6258       msg = vat_json_array_add (msg_array);
6259       vat_json_init_object (msg);
6260       vat_json_object_add_uint (msg, "sw_if_index", i);
6261       counter_array = vat_json_object_add (msg, "c");
6262       vat_json_init_array (counter_array);
6263       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6264         {
6265           counter = vat_json_array_add (counter_array);
6266           vat_json_init_object (counter);
6267           n4 = &vam->ip4_nbr_counters[i][j];
6268           vat_json_object_add_ip4 (counter, "address", n4->address);
6269           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6270           vat_json_object_add_uint (counter, "packets", n4->packets);
6271           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6272         }
6273     }
6274
6275   /* ip6 nbr counters */
6276   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6277   vat_json_init_array (msg_array);
6278   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6279     {
6280       msg = vat_json_array_add (msg_array);
6281       vat_json_init_object (msg);
6282       vat_json_object_add_uint (msg, "sw_if_index", i);
6283       counter_array = vat_json_object_add (msg, "c");
6284       vat_json_init_array (counter_array);
6285       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6286         {
6287           counter = vat_json_array_add (counter_array);
6288           vat_json_init_object (counter);
6289           n6 = &vam->ip6_nbr_counters[i][j];
6290           vat_json_object_add_ip6 (counter, "address", n6->address);
6291           vat_json_object_add_uint (counter, "packets", n6->packets);
6292           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6293         }
6294     }
6295
6296   vat_json_print (vam->ofp, &node);
6297   vat_json_free (&node);
6298
6299   return 0;
6300 }
6301
6302 /*
6303  * Pass CLI buffers directly in the CLI_INBAND API message,
6304  * instead of an additional shared memory area.
6305  */
6306 static int
6307 exec_inband (vat_main_t * vam)
6308 {
6309   vl_api_cli_inband_t *mp;
6310   unformat_input_t *i = vam->input;
6311   int ret;
6312
6313   if (vec_len (i->buffer) == 0)
6314     return -1;
6315
6316   if (vam->exec_mode == 0 && unformat (i, "mode"))
6317     {
6318       vam->exec_mode = 1;
6319       return 0;
6320     }
6321   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6322     {
6323       vam->exec_mode = 0;
6324       return 0;
6325     }
6326
6327   /*
6328    * In order for the CLI command to work, it
6329    * must be a vector ending in \n, not a C-string ending
6330    * in \n\0.
6331    */
6332   u32 len = vec_len (vam->input->buffer);
6333   M2 (CLI_INBAND, mp, len);
6334   clib_memcpy (mp->cmd, vam->input->buffer, len);
6335   mp->length = htonl (len);
6336
6337   S (mp);
6338   W (ret);
6339   /* json responses may or may not include a useful reply... */
6340   if (vec_len (vam->cmd_reply))
6341     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6342   return ret;
6343 }
6344
6345 int
6346 exec (vat_main_t * vam)
6347 {
6348   return exec_inband (vam);
6349 }
6350
6351 static int
6352 api_create_loopback (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_create_loopback_t *mp;
6356   vl_api_create_loopback_instance_t *mp_lbi;
6357   u8 mac_address[6];
6358   u8 mac_set = 0;
6359   u8 is_specified = 0;
6360   u32 user_instance = 0;
6361   int ret;
6362
6363   clib_memset (mac_address, 0, sizeof (mac_address));
6364
6365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6366     {
6367       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6368         mac_set = 1;
6369       if (unformat (i, "instance %d", &user_instance))
6370         is_specified = 1;
6371       else
6372         break;
6373     }
6374
6375   if (is_specified)
6376     {
6377       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6378       mp_lbi->is_specified = is_specified;
6379       if (is_specified)
6380         mp_lbi->user_instance = htonl (user_instance);
6381       if (mac_set)
6382         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6383       S (mp_lbi);
6384     }
6385   else
6386     {
6387       /* Construct the API message */
6388       M (CREATE_LOOPBACK, mp);
6389       if (mac_set)
6390         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6391       S (mp);
6392     }
6393
6394   W (ret);
6395   return ret;
6396 }
6397
6398 static int
6399 api_delete_loopback (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_delete_loopback_t *mp;
6403   u32 sw_if_index = ~0;
6404   int ret;
6405
6406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6407     {
6408       if (unformat (i, "sw_if_index %d", &sw_if_index))
6409         ;
6410       else
6411         break;
6412     }
6413
6414   if (sw_if_index == ~0)
6415     {
6416       errmsg ("missing sw_if_index");
6417       return -99;
6418     }
6419
6420   /* Construct the API message */
6421   M (DELETE_LOOPBACK, mp);
6422   mp->sw_if_index = ntohl (sw_if_index);
6423
6424   S (mp);
6425   W (ret);
6426   return ret;
6427 }
6428
6429 static int
6430 api_want_stats (vat_main_t * vam)
6431 {
6432   unformat_input_t *i = vam->input;
6433   vl_api_want_stats_t *mp;
6434   int enable = -1;
6435   int ret;
6436
6437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6438     {
6439       if (unformat (i, "enable"))
6440         enable = 1;
6441       else if (unformat (i, "disable"))
6442         enable = 0;
6443       else
6444         break;
6445     }
6446
6447   if (enable == -1)
6448     {
6449       errmsg ("missing enable|disable");
6450       return -99;
6451     }
6452
6453   M (WANT_STATS, mp);
6454   mp->enable_disable = enable;
6455
6456   S (mp);
6457   W (ret);
6458   return ret;
6459 }
6460
6461 static int
6462 api_want_interface_events (vat_main_t * vam)
6463 {
6464   unformat_input_t *i = vam->input;
6465   vl_api_want_interface_events_t *mp;
6466   int enable = -1;
6467   int ret;
6468
6469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6470     {
6471       if (unformat (i, "enable"))
6472         enable = 1;
6473       else if (unformat (i, "disable"))
6474         enable = 0;
6475       else
6476         break;
6477     }
6478
6479   if (enable == -1)
6480     {
6481       errmsg ("missing enable|disable");
6482       return -99;
6483     }
6484
6485   M (WANT_INTERFACE_EVENTS, mp);
6486   mp->enable_disable = enable;
6487
6488   vam->interface_event_display = enable;
6489
6490   S (mp);
6491   W (ret);
6492   return ret;
6493 }
6494
6495
6496 /* Note: non-static, called once to set up the initial intfc table */
6497 int
6498 api_sw_interface_dump (vat_main_t * vam)
6499 {
6500   vl_api_sw_interface_dump_t *mp;
6501   vl_api_control_ping_t *mp_ping;
6502   hash_pair_t *p;
6503   name_sort_t *nses = 0, *ns;
6504   sw_interface_subif_t *sub = NULL;
6505   int ret;
6506
6507   /* Toss the old name table */
6508   /* *INDENT-OFF* */
6509   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6510   ({
6511     vec_add2 (nses, ns, 1);
6512     ns->name = (u8 *)(p->key);
6513     ns->value = (u32) p->value[0];
6514   }));
6515   /* *INDENT-ON* */
6516
6517   hash_free (vam->sw_if_index_by_interface_name);
6518
6519   vec_foreach (ns, nses) vec_free (ns->name);
6520
6521   vec_free (nses);
6522
6523   vec_foreach (sub, vam->sw_if_subif_table)
6524   {
6525     vec_free (sub->interface_name);
6526   }
6527   vec_free (vam->sw_if_subif_table);
6528
6529   /* recreate the interface name hash table */
6530   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6531
6532   /*
6533    * Ask for all interface names. Otherwise, the epic catalog of
6534    * name filters becomes ridiculously long, and vat ends up needing
6535    * to be taught about new interface types.
6536    */
6537   M (SW_INTERFACE_DUMP, mp);
6538   S (mp);
6539
6540   /* Use a control ping for synchronization */
6541   MPING (CONTROL_PING, mp_ping);
6542   S (mp_ping);
6543
6544   W (ret);
6545   return ret;
6546 }
6547
6548 static int
6549 api_sw_interface_set_flags (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_sw_interface_set_flags_t *mp;
6553   u32 sw_if_index;
6554   u8 sw_if_index_set = 0;
6555   u8 admin_up = 0;
6556   int ret;
6557
6558   /* Parse args required to build the message */
6559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6560     {
6561       if (unformat (i, "admin-up"))
6562         admin_up = 1;
6563       else if (unformat (i, "admin-down"))
6564         admin_up = 0;
6565       else
6566         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6567         sw_if_index_set = 1;
6568       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6569         sw_if_index_set = 1;
6570       else
6571         break;
6572     }
6573
6574   if (sw_if_index_set == 0)
6575     {
6576       errmsg ("missing interface name or sw_if_index");
6577       return -99;
6578     }
6579
6580   /* Construct the API message */
6581   M (SW_INTERFACE_SET_FLAGS, mp);
6582   mp->sw_if_index = ntohl (sw_if_index);
6583   mp->admin_up_down = admin_up;
6584
6585   /* send it... */
6586   S (mp);
6587
6588   /* Wait for a reply, return the good/bad news... */
6589   W (ret);
6590   return ret;
6591 }
6592
6593 static int
6594 api_sw_interface_set_rx_mode (vat_main_t * vam)
6595 {
6596   unformat_input_t *i = vam->input;
6597   vl_api_sw_interface_set_rx_mode_t *mp;
6598   u32 sw_if_index;
6599   u8 sw_if_index_set = 0;
6600   int ret;
6601   u8 queue_id_valid = 0;
6602   u32 queue_id;
6603   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6604
6605   /* Parse args required to build the message */
6606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6607     {
6608       if (unformat (i, "queue %d", &queue_id))
6609         queue_id_valid = 1;
6610       else if (unformat (i, "polling"))
6611         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6612       else if (unformat (i, "interrupt"))
6613         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6614       else if (unformat (i, "adaptive"))
6615         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6616       else
6617         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6620         sw_if_index_set = 1;
6621       else
6622         break;
6623     }
6624
6625   if (sw_if_index_set == 0)
6626     {
6627       errmsg ("missing interface name or sw_if_index");
6628       return -99;
6629     }
6630   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6631     {
6632       errmsg ("missing rx-mode");
6633       return -99;
6634     }
6635
6636   /* Construct the API message */
6637   M (SW_INTERFACE_SET_RX_MODE, mp);
6638   mp->sw_if_index = ntohl (sw_if_index);
6639   mp->mode = mode;
6640   mp->queue_id_valid = queue_id_valid;
6641   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6642
6643   /* send it... */
6644   S (mp);
6645
6646   /* Wait for a reply, return the good/bad news... */
6647   W (ret);
6648   return ret;
6649 }
6650
6651 static int
6652 api_sw_interface_set_rx_placement (vat_main_t * vam)
6653 {
6654   unformat_input_t *i = vam->input;
6655   vl_api_sw_interface_set_rx_placement_t *mp;
6656   u32 sw_if_index;
6657   u8 sw_if_index_set = 0;
6658   int ret;
6659   u8 is_main = 0;
6660   u32 queue_id, thread_index;
6661
6662   /* Parse args required to build the message */
6663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6664     {
6665       if (unformat (i, "queue %d", &queue_id))
6666         ;
6667       else if (unformat (i, "main"))
6668         is_main = 1;
6669       else if (unformat (i, "worker %d", &thread_index))
6670         ;
6671       else
6672         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6673         sw_if_index_set = 1;
6674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6675         sw_if_index_set = 1;
6676       else
6677         break;
6678     }
6679
6680   if (sw_if_index_set == 0)
6681     {
6682       errmsg ("missing interface name or sw_if_index");
6683       return -99;
6684     }
6685
6686   if (is_main)
6687     thread_index = 0;
6688   /* Construct the API message */
6689   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6690   mp->sw_if_index = ntohl (sw_if_index);
6691   mp->worker_id = ntohl (thread_index);
6692   mp->queue_id = ntohl (queue_id);
6693   mp->is_main = is_main;
6694
6695   /* send it... */
6696   S (mp);
6697   /* Wait for a reply, return the good/bad news... */
6698   W (ret);
6699   return ret;
6700 }
6701
6702 static void vl_api_sw_interface_rx_placement_details_t_handler
6703   (vl_api_sw_interface_rx_placement_details_t * mp)
6704 {
6705   vat_main_t *vam = &vat_main;
6706   u32 worker_id = ntohl (mp->worker_id);
6707
6708   print (vam->ofp,
6709          "\n%-11d %-11s %-6d %-5d %-9s",
6710          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6711          worker_id, ntohl (mp->queue_id),
6712          (mp->mode ==
6713           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6714 }
6715
6716 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6717   (vl_api_sw_interface_rx_placement_details_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t *node = NULL;
6721
6722   if (VAT_JSON_ARRAY != vam->json_tree.type)
6723     {
6724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6725       vat_json_init_array (&vam->json_tree);
6726     }
6727   node = vat_json_array_add (&vam->json_tree);
6728
6729   vat_json_init_object (node);
6730   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6731   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6732   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6733   vat_json_object_add_uint (node, "mode", mp->mode);
6734 }
6735
6736 static int
6737 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6738 {
6739   unformat_input_t *i = vam->input;
6740   vl_api_sw_interface_rx_placement_dump_t *mp;
6741   vl_api_control_ping_t *mp_ping;
6742   int ret;
6743   u32 sw_if_index;
6744   u8 sw_if_index_set = 0;
6745
6746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6747     {
6748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6749         sw_if_index_set++;
6750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6751         sw_if_index_set++;
6752       else
6753         break;
6754     }
6755
6756   print (vam->ofp,
6757          "\n%-11s %-11s %-6s %-5s %-4s",
6758          "sw_if_index", "main/worker", "thread", "queue", "mode");
6759
6760   /* Dump Interface rx placement */
6761   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6762
6763   if (sw_if_index_set)
6764     mp->sw_if_index = htonl (sw_if_index);
6765   else
6766     mp->sw_if_index = ~0;
6767
6768   S (mp);
6769
6770   /* Use a control ping for synchronization */
6771   MPING (CONTROL_PING, mp_ping);
6772   S (mp_ping);
6773
6774   W (ret);
6775   return ret;
6776 }
6777
6778 static int
6779 api_sw_interface_clear_stats (vat_main_t * vam)
6780 {
6781   unformat_input_t *i = vam->input;
6782   vl_api_sw_interface_clear_stats_t *mp;
6783   u32 sw_if_index;
6784   u8 sw_if_index_set = 0;
6785   int ret;
6786
6787   /* Parse args required to build the message */
6788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789     {
6790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6791         sw_if_index_set = 1;
6792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6793         sw_if_index_set = 1;
6794       else
6795         break;
6796     }
6797
6798   /* Construct the API message */
6799   M (SW_INTERFACE_CLEAR_STATS, mp);
6800
6801   if (sw_if_index_set == 1)
6802     mp->sw_if_index = ntohl (sw_if_index);
6803   else
6804     mp->sw_if_index = ~0;
6805
6806   /* send it... */
6807   S (mp);
6808
6809   /* Wait for a reply, return the good/bad news... */
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_sw_interface_add_del_address (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_sw_interface_add_del_address_t *mp;
6819   u32 sw_if_index;
6820   u8 sw_if_index_set = 0;
6821   u8 is_add = 1, del_all = 0;
6822   u32 address_length = 0;
6823   u8 v4_address_set = 0;
6824   u8 v6_address_set = 0;
6825   ip4_address_t v4address;
6826   ip6_address_t v6address;
6827   int ret;
6828
6829   /* Parse args required to build the message */
6830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6831     {
6832       if (unformat (i, "del-all"))
6833         del_all = 1;
6834       else if (unformat (i, "del"))
6835         is_add = 0;
6836       else
6837         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "%U/%d",
6842                          unformat_ip4_address, &v4address, &address_length))
6843         v4_address_set = 1;
6844       else if (unformat (i, "%U/%d",
6845                          unformat_ip6_address, &v6address, &address_length))
6846         v6_address_set = 1;
6847       else
6848         break;
6849     }
6850
6851   if (sw_if_index_set == 0)
6852     {
6853       errmsg ("missing interface name or sw_if_index");
6854       return -99;
6855     }
6856   if (v4_address_set && v6_address_set)
6857     {
6858       errmsg ("both v4 and v6 addresses set");
6859       return -99;
6860     }
6861   if (!v4_address_set && !v6_address_set && !del_all)
6862     {
6863       errmsg ("no addresses set");
6864       return -99;
6865     }
6866
6867   /* Construct the API message */
6868   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6869
6870   mp->sw_if_index = ntohl (sw_if_index);
6871   mp->is_add = is_add;
6872   mp->del_all = del_all;
6873   if (v6_address_set)
6874     {
6875       mp->is_ipv6 = 1;
6876       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6877     }
6878   else
6879     {
6880       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6881     }
6882   mp->address_length = address_length;
6883
6884   /* send it... */
6885   S (mp);
6886
6887   /* Wait for a reply, return good/bad news  */
6888   W (ret);
6889   return ret;
6890 }
6891
6892 static int
6893 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6894 {
6895   unformat_input_t *i = vam->input;
6896   vl_api_sw_interface_set_mpls_enable_t *mp;
6897   u32 sw_if_index;
6898   u8 sw_if_index_set = 0;
6899   u8 enable = 1;
6900   int ret;
6901
6902   /* Parse args required to build the message */
6903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6904     {
6905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6906         sw_if_index_set = 1;
6907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6908         sw_if_index_set = 1;
6909       else if (unformat (i, "disable"))
6910         enable = 0;
6911       else if (unformat (i, "dis"))
6912         enable = 0;
6913       else
6914         break;
6915     }
6916
6917   if (sw_if_index_set == 0)
6918     {
6919       errmsg ("missing interface name or sw_if_index");
6920       return -99;
6921     }
6922
6923   /* Construct the API message */
6924   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6925
6926   mp->sw_if_index = ntohl (sw_if_index);
6927   mp->enable = enable;
6928
6929   /* send it... */
6930   S (mp);
6931
6932   /* Wait for a reply... */
6933   W (ret);
6934   return ret;
6935 }
6936
6937 static int
6938 api_sw_interface_set_table (vat_main_t * vam)
6939 {
6940   unformat_input_t *i = vam->input;
6941   vl_api_sw_interface_set_table_t *mp;
6942   u32 sw_if_index, vrf_id = 0;
6943   u8 sw_if_index_set = 0;
6944   u8 is_ipv6 = 0;
6945   int ret;
6946
6947   /* Parse args required to build the message */
6948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6949     {
6950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6951         sw_if_index_set = 1;
6952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6953         sw_if_index_set = 1;
6954       else if (unformat (i, "vrf %d", &vrf_id))
6955         ;
6956       else if (unformat (i, "ipv6"))
6957         is_ipv6 = 1;
6958       else
6959         break;
6960     }
6961
6962   if (sw_if_index_set == 0)
6963     {
6964       errmsg ("missing interface name or sw_if_index");
6965       return -99;
6966     }
6967
6968   /* Construct the API message */
6969   M (SW_INTERFACE_SET_TABLE, mp);
6970
6971   mp->sw_if_index = ntohl (sw_if_index);
6972   mp->is_ipv6 = is_ipv6;
6973   mp->vrf_id = ntohl (vrf_id);
6974
6975   /* send it... */
6976   S (mp);
6977
6978   /* Wait for a reply... */
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static void vl_api_sw_interface_get_table_reply_t_handler
6984   (vl_api_sw_interface_get_table_reply_t * mp)
6985 {
6986   vat_main_t *vam = &vat_main;
6987
6988   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6989
6990   vam->retval = ntohl (mp->retval);
6991   vam->result_ready = 1;
6992
6993 }
6994
6995 static void vl_api_sw_interface_get_table_reply_t_handler_json
6996   (vl_api_sw_interface_get_table_reply_t * mp)
6997 {
6998   vat_main_t *vam = &vat_main;
6999   vat_json_node_t node;
7000
7001   vat_json_init_object (&node);
7002   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7003   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7004
7005   vat_json_print (vam->ofp, &node);
7006   vat_json_free (&node);
7007
7008   vam->retval = ntohl (mp->retval);
7009   vam->result_ready = 1;
7010 }
7011
7012 static int
7013 api_sw_interface_get_table (vat_main_t * vam)
7014 {
7015   unformat_input_t *i = vam->input;
7016   vl_api_sw_interface_get_table_t *mp;
7017   u32 sw_if_index;
7018   u8 sw_if_index_set = 0;
7019   u8 is_ipv6 = 0;
7020   int ret;
7021
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7025         sw_if_index_set = 1;
7026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7027         sw_if_index_set = 1;
7028       else if (unformat (i, "ipv6"))
7029         is_ipv6 = 1;
7030       else
7031         break;
7032     }
7033
7034   if (sw_if_index_set == 0)
7035     {
7036       errmsg ("missing interface name or sw_if_index");
7037       return -99;
7038     }
7039
7040   M (SW_INTERFACE_GET_TABLE, mp);
7041   mp->sw_if_index = htonl (sw_if_index);
7042   mp->is_ipv6 = is_ipv6;
7043
7044   S (mp);
7045   W (ret);
7046   return ret;
7047 }
7048
7049 static int
7050 api_sw_interface_set_vpath (vat_main_t * vam)
7051 {
7052   unformat_input_t *i = vam->input;
7053   vl_api_sw_interface_set_vpath_t *mp;
7054   u32 sw_if_index = 0;
7055   u8 sw_if_index_set = 0;
7056   u8 is_enable = 0;
7057   int ret;
7058
7059   /* Parse args required to build the message */
7060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7061     {
7062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7063         sw_if_index_set = 1;
7064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7065         sw_if_index_set = 1;
7066       else if (unformat (i, "enable"))
7067         is_enable = 1;
7068       else if (unformat (i, "disable"))
7069         is_enable = 0;
7070       else
7071         break;
7072     }
7073
7074   if (sw_if_index_set == 0)
7075     {
7076       errmsg ("missing interface name or sw_if_index");
7077       return -99;
7078     }
7079
7080   /* Construct the API message */
7081   M (SW_INTERFACE_SET_VPATH, mp);
7082
7083   mp->sw_if_index = ntohl (sw_if_index);
7084   mp->enable = is_enable;
7085
7086   /* send it... */
7087   S (mp);
7088
7089   /* Wait for a reply... */
7090   W (ret);
7091   return ret;
7092 }
7093
7094 static int
7095 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7099   u32 sw_if_index = 0;
7100   u8 sw_if_index_set = 0;
7101   u8 is_enable = 1;
7102   u8 is_ipv6 = 0;
7103   int ret;
7104
7105   /* Parse args required to build the message */
7106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7107     {
7108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7109         sw_if_index_set = 1;
7110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7111         sw_if_index_set = 1;
7112       else if (unformat (i, "enable"))
7113         is_enable = 1;
7114       else if (unformat (i, "disable"))
7115         is_enable = 0;
7116       else if (unformat (i, "ip4"))
7117         is_ipv6 = 0;
7118       else if (unformat (i, "ip6"))
7119         is_ipv6 = 1;
7120       else
7121         break;
7122     }
7123
7124   if (sw_if_index_set == 0)
7125     {
7126       errmsg ("missing interface name or sw_if_index");
7127       return -99;
7128     }
7129
7130   /* Construct the API message */
7131   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7132
7133   mp->sw_if_index = ntohl (sw_if_index);
7134   mp->enable = is_enable;
7135   mp->is_ipv6 = is_ipv6;
7136
7137   /* send it... */
7138   S (mp);
7139
7140   /* Wait for a reply... */
7141   W (ret);
7142   return ret;
7143 }
7144
7145 static int
7146 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_sw_interface_set_geneve_bypass_t *mp;
7150   u32 sw_if_index = 0;
7151   u8 sw_if_index_set = 0;
7152   u8 is_enable = 1;
7153   u8 is_ipv6 = 0;
7154   int ret;
7155
7156   /* Parse args required to build the message */
7157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158     {
7159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7160         sw_if_index_set = 1;
7161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7162         sw_if_index_set = 1;
7163       else if (unformat (i, "enable"))
7164         is_enable = 1;
7165       else if (unformat (i, "disable"))
7166         is_enable = 0;
7167       else if (unformat (i, "ip4"))
7168         is_ipv6 = 0;
7169       else if (unformat (i, "ip6"))
7170         is_ipv6 = 1;
7171       else
7172         break;
7173     }
7174
7175   if (sw_if_index_set == 0)
7176     {
7177       errmsg ("missing interface name or sw_if_index");
7178       return -99;
7179     }
7180
7181   /* Construct the API message */
7182   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7183
7184   mp->sw_if_index = ntohl (sw_if_index);
7185   mp->enable = is_enable;
7186   mp->is_ipv6 = is_ipv6;
7187
7188   /* send it... */
7189   S (mp);
7190
7191   /* Wait for a reply... */
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_sw_interface_set_l2_xconnect_t *mp;
7201   u32 rx_sw_if_index;
7202   u8 rx_sw_if_index_set = 0;
7203   u32 tx_sw_if_index;
7204   u8 tx_sw_if_index_set = 0;
7205   u8 enable = 1;
7206   int ret;
7207
7208   /* Parse args required to build the message */
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7212         rx_sw_if_index_set = 1;
7213       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7214         tx_sw_if_index_set = 1;
7215       else if (unformat (i, "rx"))
7216         {
7217           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218             {
7219               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7220                             &rx_sw_if_index))
7221                 rx_sw_if_index_set = 1;
7222             }
7223           else
7224             break;
7225         }
7226       else if (unformat (i, "tx"))
7227         {
7228           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7229             {
7230               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7231                             &tx_sw_if_index))
7232                 tx_sw_if_index_set = 1;
7233             }
7234           else
7235             break;
7236         }
7237       else if (unformat (i, "enable"))
7238         enable = 1;
7239       else if (unformat (i, "disable"))
7240         enable = 0;
7241       else
7242         break;
7243     }
7244
7245   if (rx_sw_if_index_set == 0)
7246     {
7247       errmsg ("missing rx interface name or rx_sw_if_index");
7248       return -99;
7249     }
7250
7251   if (enable && (tx_sw_if_index_set == 0))
7252     {
7253       errmsg ("missing tx interface name or tx_sw_if_index");
7254       return -99;
7255     }
7256
7257   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7258
7259   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7260   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7261   mp->enable = enable;
7262
7263   S (mp);
7264   W (ret);
7265   return ret;
7266 }
7267
7268 static int
7269 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7270 {
7271   unformat_input_t *i = vam->input;
7272   vl_api_sw_interface_set_l2_bridge_t *mp;
7273   vl_api_l2_port_type_t port_type;
7274   u32 rx_sw_if_index;
7275   u8 rx_sw_if_index_set = 0;
7276   u32 bd_id;
7277   u8 bd_id_set = 0;
7278   u32 shg = 0;
7279   u8 enable = 1;
7280   int ret;
7281
7282   port_type = L2_API_PORT_TYPE_NORMAL;
7283
7284   /* Parse args required to build the message */
7285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286     {
7287       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7288         rx_sw_if_index_set = 1;
7289       else if (unformat (i, "bd_id %d", &bd_id))
7290         bd_id_set = 1;
7291       else
7292         if (unformat
7293             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7294         rx_sw_if_index_set = 1;
7295       else if (unformat (i, "shg %d", &shg))
7296         ;
7297       else if (unformat (i, "bvi"))
7298         port_type = L2_API_PORT_TYPE_BVI;
7299       else if (unformat (i, "uu-fwd"))
7300         port_type = L2_API_PORT_TYPE_UU_FWD;
7301       else if (unformat (i, "enable"))
7302         enable = 1;
7303       else if (unformat (i, "disable"))
7304         enable = 0;
7305       else
7306         break;
7307     }
7308
7309   if (rx_sw_if_index_set == 0)
7310     {
7311       errmsg ("missing rx interface name or sw_if_index");
7312       return -99;
7313     }
7314
7315   if (enable && (bd_id_set == 0))
7316     {
7317       errmsg ("missing bridge domain");
7318       return -99;
7319     }
7320
7321   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7322
7323   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7324   mp->bd_id = ntohl (bd_id);
7325   mp->shg = (u8) shg;
7326   mp->port_type = ntohl (port_type);
7327   mp->enable = enable;
7328
7329   S (mp);
7330   W (ret);
7331   return ret;
7332 }
7333
7334 static int
7335 api_bridge_domain_dump (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_bridge_domain_dump_t *mp;
7339   vl_api_control_ping_t *mp_ping;
7340   u32 bd_id = ~0;
7341   int ret;
7342
7343   /* Parse args required to build the message */
7344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7345     {
7346       if (unformat (i, "bd_id %d", &bd_id))
7347         ;
7348       else
7349         break;
7350     }
7351
7352   M (BRIDGE_DOMAIN_DUMP, mp);
7353   mp->bd_id = ntohl (bd_id);
7354   S (mp);
7355
7356   /* Use a control ping for synchronization */
7357   MPING (CONTROL_PING, mp_ping);
7358   S (mp_ping);
7359
7360   W (ret);
7361   return ret;
7362 }
7363
7364 static int
7365 api_bridge_domain_add_del (vat_main_t * vam)
7366 {
7367   unformat_input_t *i = vam->input;
7368   vl_api_bridge_domain_add_del_t *mp;
7369   u32 bd_id = ~0;
7370   u8 is_add = 1;
7371   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7372   u8 *bd_tag = NULL;
7373   u32 mac_age = 0;
7374   int ret;
7375
7376   /* Parse args required to build the message */
7377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7378     {
7379       if (unformat (i, "bd_id %d", &bd_id))
7380         ;
7381       else if (unformat (i, "flood %d", &flood))
7382         ;
7383       else if (unformat (i, "uu-flood %d", &uu_flood))
7384         ;
7385       else if (unformat (i, "forward %d", &forward))
7386         ;
7387       else if (unformat (i, "learn %d", &learn))
7388         ;
7389       else if (unformat (i, "arp-term %d", &arp_term))
7390         ;
7391       else if (unformat (i, "mac-age %d", &mac_age))
7392         ;
7393       else if (unformat (i, "bd-tag %s", &bd_tag))
7394         ;
7395       else if (unformat (i, "del"))
7396         {
7397           is_add = 0;
7398           flood = uu_flood = forward = learn = 0;
7399         }
7400       else
7401         break;
7402     }
7403
7404   if (bd_id == ~0)
7405     {
7406       errmsg ("missing bridge domain");
7407       ret = -99;
7408       goto done;
7409     }
7410
7411   if (mac_age > 255)
7412     {
7413       errmsg ("mac age must be less than 256 ");
7414       ret = -99;
7415       goto done;
7416     }
7417
7418   if ((bd_tag) && (vec_len (bd_tag) > 63))
7419     {
7420       errmsg ("bd-tag cannot be longer than 63");
7421       ret = -99;
7422       goto done;
7423     }
7424
7425   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7426
7427   mp->bd_id = ntohl (bd_id);
7428   mp->flood = flood;
7429   mp->uu_flood = uu_flood;
7430   mp->forward = forward;
7431   mp->learn = learn;
7432   mp->arp_term = arp_term;
7433   mp->is_add = is_add;
7434   mp->mac_age = (u8) mac_age;
7435   if (bd_tag)
7436     {
7437       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7438       mp->bd_tag[vec_len (bd_tag)] = 0;
7439     }
7440   S (mp);
7441   W (ret);
7442
7443 done:
7444   vec_free (bd_tag);
7445   return ret;
7446 }
7447
7448 static int
7449 api_l2fib_flush_bd (vat_main_t * vam)
7450 {
7451   unformat_input_t *i = vam->input;
7452   vl_api_l2fib_flush_bd_t *mp;
7453   u32 bd_id = ~0;
7454   int ret;
7455
7456   /* Parse args required to build the message */
7457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7458     {
7459       if (unformat (i, "bd_id %d", &bd_id));
7460       else
7461         break;
7462     }
7463
7464   if (bd_id == ~0)
7465     {
7466       errmsg ("missing bridge domain");
7467       return -99;
7468     }
7469
7470   M (L2FIB_FLUSH_BD, mp);
7471
7472   mp->bd_id = htonl (bd_id);
7473
7474   S (mp);
7475   W (ret);
7476   return ret;
7477 }
7478
7479 static int
7480 api_l2fib_flush_int (vat_main_t * vam)
7481 {
7482   unformat_input_t *i = vam->input;
7483   vl_api_l2fib_flush_int_t *mp;
7484   u32 sw_if_index = ~0;
7485   int ret;
7486
7487   /* Parse args required to build the message */
7488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7489     {
7490       if (unformat (i, "sw_if_index %d", &sw_if_index));
7491       else
7492         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7493       else
7494         break;
7495     }
7496
7497   if (sw_if_index == ~0)
7498     {
7499       errmsg ("missing interface name or sw_if_index");
7500       return -99;
7501     }
7502
7503   M (L2FIB_FLUSH_INT, mp);
7504
7505   mp->sw_if_index = ntohl (sw_if_index);
7506
7507   S (mp);
7508   W (ret);
7509   return ret;
7510 }
7511
7512 static int
7513 api_l2fib_add_del (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_l2fib_add_del_t *mp;
7517   f64 timeout;
7518   u8 mac[6] = { 0 };
7519   u8 mac_set = 0;
7520   u32 bd_id;
7521   u8 bd_id_set = 0;
7522   u32 sw_if_index = 0;
7523   u8 sw_if_index_set = 0;
7524   u8 is_add = 1;
7525   u8 static_mac = 0;
7526   u8 filter_mac = 0;
7527   u8 bvi_mac = 0;
7528   int count = 1;
7529   f64 before = 0;
7530   int j;
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7536         mac_set = 1;
7537       else if (unformat (i, "bd_id %d", &bd_id))
7538         bd_id_set = 1;
7539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7540         sw_if_index_set = 1;
7541       else if (unformat (i, "sw_if"))
7542         {
7543           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7544             {
7545               if (unformat
7546                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7547                 sw_if_index_set = 1;
7548             }
7549           else
7550             break;
7551         }
7552       else if (unformat (i, "static"))
7553         static_mac = 1;
7554       else if (unformat (i, "filter"))
7555         {
7556           filter_mac = 1;
7557           static_mac = 1;
7558         }
7559       else if (unformat (i, "bvi"))
7560         {
7561           bvi_mac = 1;
7562           static_mac = 1;
7563         }
7564       else if (unformat (i, "del"))
7565         is_add = 0;
7566       else if (unformat (i, "count %d", &count))
7567         ;
7568       else
7569         break;
7570     }
7571
7572   if (mac_set == 0)
7573     {
7574       errmsg ("missing mac address");
7575       return -99;
7576     }
7577
7578   if (bd_id_set == 0)
7579     {
7580       errmsg ("missing bridge domain");
7581       return -99;
7582     }
7583
7584   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7585     {
7586       errmsg ("missing interface name or sw_if_index");
7587       return -99;
7588     }
7589
7590   if (count > 1)
7591     {
7592       /* Turn on async mode */
7593       vam->async_mode = 1;
7594       vam->async_errors = 0;
7595       before = vat_time_now (vam);
7596     }
7597
7598   for (j = 0; j < count; j++)
7599     {
7600       M (L2FIB_ADD_DEL, mp);
7601
7602       clib_memcpy (mp->mac, mac, 6);
7603       mp->bd_id = ntohl (bd_id);
7604       mp->is_add = is_add;
7605       mp->sw_if_index = ntohl (sw_if_index);
7606
7607       if (is_add)
7608         {
7609           mp->static_mac = static_mac;
7610           mp->filter_mac = filter_mac;
7611           mp->bvi_mac = bvi_mac;
7612         }
7613       increment_mac_address (mac);
7614       /* send it... */
7615       S (mp);
7616     }
7617
7618   if (count > 1)
7619     {
7620       vl_api_control_ping_t *mp_ping;
7621       f64 after;
7622
7623       /* Shut off async mode */
7624       vam->async_mode = 0;
7625
7626       MPING (CONTROL_PING, mp_ping);
7627       S (mp_ping);
7628
7629       timeout = vat_time_now (vam) + 1.0;
7630       while (vat_time_now (vam) < timeout)
7631         if (vam->result_ready == 1)
7632           goto out;
7633       vam->retval = -99;
7634
7635     out:
7636       if (vam->retval == -99)
7637         errmsg ("timeout");
7638
7639       if (vam->async_errors > 0)
7640         {
7641           errmsg ("%d asynchronous errors", vam->async_errors);
7642           vam->retval = -98;
7643         }
7644       vam->async_errors = 0;
7645       after = vat_time_now (vam);
7646
7647       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7648              count, after - before, count / (after - before));
7649     }
7650   else
7651     {
7652       int ret;
7653
7654       /* Wait for a reply... */
7655       W (ret);
7656       return ret;
7657     }
7658   /* Return the good/bad news */
7659   return (vam->retval);
7660 }
7661
7662 static int
7663 api_bridge_domain_set_mac_age (vat_main_t * vam)
7664 {
7665   unformat_input_t *i = vam->input;
7666   vl_api_bridge_domain_set_mac_age_t *mp;
7667   u32 bd_id = ~0;
7668   u32 mac_age = 0;
7669   int ret;
7670
7671   /* Parse args required to build the message */
7672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7673     {
7674       if (unformat (i, "bd_id %d", &bd_id));
7675       else if (unformat (i, "mac-age %d", &mac_age));
7676       else
7677         break;
7678     }
7679
7680   if (bd_id == ~0)
7681     {
7682       errmsg ("missing bridge domain");
7683       return -99;
7684     }
7685
7686   if (mac_age > 255)
7687     {
7688       errmsg ("mac age must be less than 256 ");
7689       return -99;
7690     }
7691
7692   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7693
7694   mp->bd_id = htonl (bd_id);
7695   mp->mac_age = (u8) mac_age;
7696
7697   S (mp);
7698   W (ret);
7699   return ret;
7700 }
7701
7702 static int
7703 api_l2_flags (vat_main_t * vam)
7704 {
7705   unformat_input_t *i = vam->input;
7706   vl_api_l2_flags_t *mp;
7707   u32 sw_if_index;
7708   u32 flags = 0;
7709   u8 sw_if_index_set = 0;
7710   u8 is_set = 0;
7711   int ret;
7712
7713   /* Parse args required to build the message */
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "sw_if_index %d", &sw_if_index))
7717         sw_if_index_set = 1;
7718       else if (unformat (i, "sw_if"))
7719         {
7720           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7721             {
7722               if (unformat
7723                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7724                 sw_if_index_set = 1;
7725             }
7726           else
7727             break;
7728         }
7729       else if (unformat (i, "learn"))
7730         flags |= L2_LEARN;
7731       else if (unformat (i, "forward"))
7732         flags |= L2_FWD;
7733       else if (unformat (i, "flood"))
7734         flags |= L2_FLOOD;
7735       else if (unformat (i, "uu-flood"))
7736         flags |= L2_UU_FLOOD;
7737       else if (unformat (i, "arp-term"))
7738         flags |= L2_ARP_TERM;
7739       else if (unformat (i, "off"))
7740         is_set = 0;
7741       else if (unformat (i, "disable"))
7742         is_set = 0;
7743       else
7744         break;
7745     }
7746
7747   if (sw_if_index_set == 0)
7748     {
7749       errmsg ("missing interface name or sw_if_index");
7750       return -99;
7751     }
7752
7753   M (L2_FLAGS, mp);
7754
7755   mp->sw_if_index = ntohl (sw_if_index);
7756   mp->feature_bitmap = ntohl (flags);
7757   mp->is_set = is_set;
7758
7759   S (mp);
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_bridge_flags (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_bridge_flags_t *mp;
7769   u32 bd_id;
7770   u8 bd_id_set = 0;
7771   u8 is_set = 1;
7772   bd_flags_t flags = 0;
7773   int ret;
7774
7775   /* Parse args required to build the message */
7776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7777     {
7778       if (unformat (i, "bd_id %d", &bd_id))
7779         bd_id_set = 1;
7780       else if (unformat (i, "learn"))
7781         flags |= BRIDGE_API_FLAG_LEARN;
7782       else if (unformat (i, "forward"))
7783         flags |= BRIDGE_API_FLAG_FWD;
7784       else if (unformat (i, "flood"))
7785         flags |= BRIDGE_API_FLAG_FLOOD;
7786       else if (unformat (i, "uu-flood"))
7787         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7788       else if (unformat (i, "arp-term"))
7789         flags |= BRIDGE_API_FLAG_ARP_TERM;
7790       else if (unformat (i, "off"))
7791         is_set = 0;
7792       else if (unformat (i, "disable"))
7793         is_set = 0;
7794       else
7795         break;
7796     }
7797
7798   if (bd_id_set == 0)
7799     {
7800       errmsg ("missing bridge domain");
7801       return -99;
7802     }
7803
7804   M (BRIDGE_FLAGS, mp);
7805
7806   mp->bd_id = ntohl (bd_id);
7807   mp->flags = ntohl (flags);
7808   mp->is_set = is_set;
7809
7810   S (mp);
7811   W (ret);
7812   return ret;
7813 }
7814
7815 static int
7816 api_bd_ip_mac_add_del (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_bd_ip_mac_add_del_t *mp;
7820   u32 bd_id;
7821   u8 is_ipv6 = 0;
7822   u8 is_add = 1;
7823   u8 bd_id_set = 0;
7824   u8 ip_set = 0;
7825   u8 mac_set = 0;
7826   ip4_address_t v4addr;
7827   ip6_address_t v6addr;
7828   u8 macaddr[6];
7829   int ret;
7830
7831
7832   /* Parse args required to build the message */
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "bd_id %d", &bd_id))
7836         {
7837           bd_id_set++;
7838         }
7839       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7840         {
7841           ip_set++;
7842         }
7843       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7844         {
7845           ip_set++;
7846           is_ipv6++;
7847         }
7848       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7849         {
7850           mac_set++;
7851         }
7852       else if (unformat (i, "del"))
7853         is_add = 0;
7854       else
7855         break;
7856     }
7857
7858   if (bd_id_set == 0)
7859     {
7860       errmsg ("missing bridge domain");
7861       return -99;
7862     }
7863   else if (ip_set == 0)
7864     {
7865       errmsg ("missing IP address");
7866       return -99;
7867     }
7868   else if (mac_set == 0)
7869     {
7870       errmsg ("missing MAC address");
7871       return -99;
7872     }
7873
7874   M (BD_IP_MAC_ADD_DEL, mp);
7875
7876   mp->bd_id = ntohl (bd_id);
7877   mp->is_ipv6 = is_ipv6;
7878   mp->is_add = is_add;
7879   if (is_ipv6)
7880     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7881   else
7882     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7883   clib_memcpy (mp->mac_address, macaddr, 6);
7884   S (mp);
7885   W (ret);
7886   return ret;
7887 }
7888
7889 static void vl_api_bd_ip_mac_details_t_handler
7890   (vl_api_bd_ip_mac_details_t * mp)
7891 {
7892   vat_main_t *vam = &vat_main;
7893   u8 *ip = 0;
7894
7895   if (!mp->is_ipv6)
7896     ip =
7897       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7898   else
7899     ip =
7900       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7901
7902   print (vam->ofp,
7903          "\n%-5d %-7s %-20U %-30s",
7904          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7905          format_ethernet_address, mp->mac_address, ip);
7906
7907   vec_free (ip);
7908 }
7909
7910 static void vl_api_bd_ip_mac_details_t_handler_json
7911   (vl_api_bd_ip_mac_details_t * mp)
7912 {
7913   vat_main_t *vam = &vat_main;
7914   vat_json_node_t *node = NULL;
7915
7916   if (VAT_JSON_ARRAY != vam->json_tree.type)
7917     {
7918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7919       vat_json_init_array (&vam->json_tree);
7920     }
7921   node = vat_json_array_add (&vam->json_tree);
7922
7923   vat_json_init_object (node);
7924   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7925   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7926   vat_json_object_add_string_copy (node, "mac_address",
7927                                    format (0, "%U", format_ethernet_address,
7928                                            &mp->mac_address));
7929   u8 *ip = 0;
7930
7931   if (!mp->is_ipv6)
7932     ip =
7933       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7934   else
7935     ip =
7936       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7937   vat_json_object_add_string_copy (node, "ip_address", ip);
7938   vec_free (ip);
7939 }
7940
7941 static int
7942 api_bd_ip_mac_dump (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_bd_ip_mac_dump_t *mp;
7946   vl_api_control_ping_t *mp_ping;
7947   int ret;
7948   u32 bd_id;
7949   u8 bd_id_set = 0;
7950
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "bd_id %d", &bd_id))
7954         {
7955           bd_id_set++;
7956         }
7957       else
7958         break;
7959     }
7960
7961   print (vam->ofp,
7962          "\n%-5s %-7s %-20s %-30s",
7963          "bd_id", "is_ipv6", "mac_address", "ip_address");
7964
7965   /* Dump Bridge Domain Ip to Mac entries */
7966   M (BD_IP_MAC_DUMP, mp);
7967
7968   if (bd_id_set)
7969     mp->bd_id = htonl (bd_id);
7970   else
7971     mp->bd_id = ~0;
7972
7973   S (mp);
7974
7975   /* Use a control ping for synchronization */
7976   MPING (CONTROL_PING, mp_ping);
7977   S (mp_ping);
7978
7979   W (ret);
7980   return ret;
7981 }
7982
7983 static int
7984 api_tap_connect (vat_main_t * vam)
7985 {
7986   unformat_input_t *i = vam->input;
7987   vl_api_tap_connect_t *mp;
7988   u8 mac_address[6];
7989   u8 random_mac = 1;
7990   u8 name_set = 0;
7991   u8 *tap_name;
7992   u8 *tag = 0;
7993   ip4_address_t ip4_address;
7994   u32 ip4_mask_width;
7995   int ip4_address_set = 0;
7996   ip6_address_t ip6_address;
7997   u32 ip6_mask_width;
7998   int ip6_address_set = 0;
7999   int ret;
8000
8001   clib_memset (mac_address, 0, sizeof (mac_address));
8002
8003   /* Parse args required to build the message */
8004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8005     {
8006       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8007         {
8008           random_mac = 0;
8009         }
8010       else if (unformat (i, "random-mac"))
8011         random_mac = 1;
8012       else if (unformat (i, "tapname %s", &tap_name))
8013         name_set = 1;
8014       else if (unformat (i, "tag %s", &tag))
8015         ;
8016       else if (unformat (i, "address %U/%d",
8017                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8018         ip4_address_set = 1;
8019       else if (unformat (i, "address %U/%d",
8020                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8021         ip6_address_set = 1;
8022       else
8023         break;
8024     }
8025
8026   if (name_set == 0)
8027     {
8028       errmsg ("missing tap name");
8029       return -99;
8030     }
8031   if (vec_len (tap_name) > 63)
8032     {
8033       errmsg ("tap name too long");
8034       return -99;
8035     }
8036   vec_add1 (tap_name, 0);
8037
8038   if (vec_len (tag) > 63)
8039     {
8040       errmsg ("tag too long");
8041       return -99;
8042     }
8043
8044   /* Construct the API message */
8045   M (TAP_CONNECT, mp);
8046
8047   mp->use_random_mac = random_mac;
8048   clib_memcpy (mp->mac_address, mac_address, 6);
8049   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8050   if (tag)
8051     clib_memcpy (mp->tag, tag, vec_len (tag));
8052
8053   if (ip4_address_set)
8054     {
8055       mp->ip4_address_set = 1;
8056       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8057       mp->ip4_mask_width = ip4_mask_width;
8058     }
8059   if (ip6_address_set)
8060     {
8061       mp->ip6_address_set = 1;
8062       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8063       mp->ip6_mask_width = ip6_mask_width;
8064     }
8065
8066   vec_free (tap_name);
8067   vec_free (tag);
8068
8069   /* send it... */
8070   S (mp);
8071
8072   /* Wait for a reply... */
8073   W (ret);
8074   return ret;
8075 }
8076
8077 static int
8078 api_tap_modify (vat_main_t * vam)
8079 {
8080   unformat_input_t *i = vam->input;
8081   vl_api_tap_modify_t *mp;
8082   u8 mac_address[6];
8083   u8 random_mac = 1;
8084   u8 name_set = 0;
8085   u8 *tap_name;
8086   u32 sw_if_index = ~0;
8087   u8 sw_if_index_set = 0;
8088   int ret;
8089
8090   clib_memset (mac_address, 0, sizeof (mac_address));
8091
8092   /* Parse args required to build the message */
8093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8094     {
8095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8096         sw_if_index_set = 1;
8097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8098         sw_if_index_set = 1;
8099       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8100         {
8101           random_mac = 0;
8102         }
8103       else if (unformat (i, "random-mac"))
8104         random_mac = 1;
8105       else if (unformat (i, "tapname %s", &tap_name))
8106         name_set = 1;
8107       else
8108         break;
8109     }
8110
8111   if (sw_if_index_set == 0)
8112     {
8113       errmsg ("missing vpp interface name");
8114       return -99;
8115     }
8116   if (name_set == 0)
8117     {
8118       errmsg ("missing tap name");
8119       return -99;
8120     }
8121   if (vec_len (tap_name) > 63)
8122     {
8123       errmsg ("tap name too long");
8124     }
8125   vec_add1 (tap_name, 0);
8126
8127   /* Construct the API message */
8128   M (TAP_MODIFY, mp);
8129
8130   mp->use_random_mac = random_mac;
8131   mp->sw_if_index = ntohl (sw_if_index);
8132   clib_memcpy (mp->mac_address, mac_address, 6);
8133   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8134   vec_free (tap_name);
8135
8136   /* send it... */
8137   S (mp);
8138
8139   /* Wait for a reply... */
8140   W (ret);
8141   return ret;
8142 }
8143
8144 static int
8145 api_tap_delete (vat_main_t * vam)
8146 {
8147   unformat_input_t *i = vam->input;
8148   vl_api_tap_delete_t *mp;
8149   u32 sw_if_index = ~0;
8150   u8 sw_if_index_set = 0;
8151   int ret;
8152
8153   /* Parse args required to build the message */
8154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8155     {
8156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8157         sw_if_index_set = 1;
8158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8159         sw_if_index_set = 1;
8160       else
8161         break;
8162     }
8163
8164   if (sw_if_index_set == 0)
8165     {
8166       errmsg ("missing vpp interface name");
8167       return -99;
8168     }
8169
8170   /* Construct the API message */
8171   M (TAP_DELETE, mp);
8172
8173   mp->sw_if_index = ntohl (sw_if_index);
8174
8175   /* send it... */
8176   S (mp);
8177
8178   /* Wait for a reply... */
8179   W (ret);
8180   return ret;
8181 }
8182
8183 static int
8184 api_tap_create_v2 (vat_main_t * vam)
8185 {
8186   unformat_input_t *i = vam->input;
8187   vl_api_tap_create_v2_t *mp;
8188   u8 mac_address[6];
8189   u8 random_mac = 1;
8190   u32 id = ~0;
8191   u8 *host_if_name = 0;
8192   u8 *host_ns = 0;
8193   u8 host_mac_addr[6];
8194   u8 host_mac_addr_set = 0;
8195   u8 *host_bridge = 0;
8196   ip4_address_t host_ip4_addr;
8197   ip4_address_t host_ip4_gw;
8198   u8 host_ip4_gw_set = 0;
8199   u32 host_ip4_prefix_len = 0;
8200   ip6_address_t host_ip6_addr;
8201   ip6_address_t host_ip6_gw;
8202   u8 host_ip6_gw_set = 0;
8203   u32 host_ip6_prefix_len = 0;
8204   int ret;
8205   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8206
8207   clib_memset (mac_address, 0, sizeof (mac_address));
8208
8209   /* Parse args required to build the message */
8210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8211     {
8212       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8213         {
8214           random_mac = 0;
8215         }
8216       else if (unformat (i, "id %u", &id))
8217         ;
8218       else if (unformat (i, "host-if-name %s", &host_if_name))
8219         ;
8220       else if (unformat (i, "host-ns %s", &host_ns))
8221         ;
8222       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8223                          host_mac_addr))
8224         host_mac_addr_set = 1;
8225       else if (unformat (i, "host-bridge %s", &host_bridge))
8226         ;
8227       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8228                          &host_ip4_addr, &host_ip4_prefix_len))
8229         ;
8230       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8231                          &host_ip6_addr, &host_ip6_prefix_len))
8232         ;
8233       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8234                          &host_ip4_gw))
8235         host_ip4_gw_set = 1;
8236       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8237                          &host_ip6_gw))
8238         host_ip6_gw_set = 1;
8239       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8240         ;
8241       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8242         ;
8243       else
8244         break;
8245     }
8246
8247   if (vec_len (host_if_name) > 63)
8248     {
8249       errmsg ("tap name too long. ");
8250       return -99;
8251     }
8252   if (vec_len (host_ns) > 63)
8253     {
8254       errmsg ("host name space too long. ");
8255       return -99;
8256     }
8257   if (vec_len (host_bridge) > 63)
8258     {
8259       errmsg ("host bridge name too long. ");
8260       return -99;
8261     }
8262   if (host_ip4_prefix_len > 32)
8263     {
8264       errmsg ("host ip4 prefix length not valid. ");
8265       return -99;
8266     }
8267   if (host_ip6_prefix_len > 128)
8268     {
8269       errmsg ("host ip6 prefix length not valid. ");
8270       return -99;
8271     }
8272   if (!is_pow2 (rx_ring_sz))
8273     {
8274       errmsg ("rx ring size must be power of 2. ");
8275       return -99;
8276     }
8277   if (rx_ring_sz > 32768)
8278     {
8279       errmsg ("rx ring size must be 32768 or lower. ");
8280       return -99;
8281     }
8282   if (!is_pow2 (tx_ring_sz))
8283     {
8284       errmsg ("tx ring size must be power of 2. ");
8285       return -99;
8286     }
8287   if (tx_ring_sz > 32768)
8288     {
8289       errmsg ("tx ring size must be 32768 or lower. ");
8290       return -99;
8291     }
8292
8293   /* Construct the API message */
8294   M (TAP_CREATE_V2, mp);
8295
8296   mp->use_random_mac = random_mac;
8297
8298   mp->id = ntohl (id);
8299   mp->host_namespace_set = host_ns != 0;
8300   mp->host_bridge_set = host_bridge != 0;
8301   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8302   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8303   mp->rx_ring_sz = ntohs (rx_ring_sz);
8304   mp->tx_ring_sz = ntohs (tx_ring_sz);
8305
8306   if (random_mac == 0)
8307     clib_memcpy (mp->mac_address, mac_address, 6);
8308   if (host_mac_addr_set)
8309     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8310   if (host_if_name)
8311     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8312   if (host_ns)
8313     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8314   if (host_bridge)
8315     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8316   if (host_ip4_prefix_len)
8317     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8318   if (host_ip6_prefix_len)
8319     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8320   if (host_ip4_gw_set)
8321     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8322   if (host_ip6_gw_set)
8323     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8324
8325   vec_free (host_ns);
8326   vec_free (host_if_name);
8327   vec_free (host_bridge);
8328
8329   /* send it... */
8330   S (mp);
8331
8332   /* Wait for a reply... */
8333   W (ret);
8334   return ret;
8335 }
8336
8337 static int
8338 api_tap_delete_v2 (vat_main_t * vam)
8339 {
8340   unformat_input_t *i = vam->input;
8341   vl_api_tap_delete_v2_t *mp;
8342   u32 sw_if_index = ~0;
8343   u8 sw_if_index_set = 0;
8344   int ret;
8345
8346   /* Parse args required to build the message */
8347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8348     {
8349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8350         sw_if_index_set = 1;
8351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8352         sw_if_index_set = 1;
8353       else
8354         break;
8355     }
8356
8357   if (sw_if_index_set == 0)
8358     {
8359       errmsg ("missing vpp interface name. ");
8360       return -99;
8361     }
8362
8363   /* Construct the API message */
8364   M (TAP_DELETE_V2, mp);
8365
8366   mp->sw_if_index = ntohl (sw_if_index);
8367
8368   /* send it... */
8369   S (mp);
8370
8371   /* Wait for a reply... */
8372   W (ret);
8373   return ret;
8374 }
8375
8376 static int
8377 api_bond_create (vat_main_t * vam)
8378 {
8379   unformat_input_t *i = vam->input;
8380   vl_api_bond_create_t *mp;
8381   u8 mac_address[6];
8382   u8 custom_mac = 0;
8383   int ret;
8384   u8 mode;
8385   u8 lb;
8386   u8 mode_is_set = 0;
8387
8388   clib_memset (mac_address, 0, sizeof (mac_address));
8389   lb = BOND_LB_L2;
8390
8391   /* Parse args required to build the message */
8392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8393     {
8394       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8395         mode_is_set = 1;
8396       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8397                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8398         ;
8399       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8400                          mac_address))
8401         custom_mac = 1;
8402       else
8403         break;
8404     }
8405
8406   if (mode_is_set == 0)
8407     {
8408       errmsg ("Missing bond mode. ");
8409       return -99;
8410     }
8411
8412   /* Construct the API message */
8413   M (BOND_CREATE, mp);
8414
8415   mp->use_custom_mac = custom_mac;
8416
8417   mp->mode = mode;
8418   mp->lb = lb;
8419
8420   if (custom_mac)
8421     clib_memcpy (mp->mac_address, mac_address, 6);
8422
8423   /* send it... */
8424   S (mp);
8425
8426   /* Wait for a reply... */
8427   W (ret);
8428   return ret;
8429 }
8430
8431 static int
8432 api_bond_delete (vat_main_t * vam)
8433 {
8434   unformat_input_t *i = vam->input;
8435   vl_api_bond_delete_t *mp;
8436   u32 sw_if_index = ~0;
8437   u8 sw_if_index_set = 0;
8438   int ret;
8439
8440   /* Parse args required to build the message */
8441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8442     {
8443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8444         sw_if_index_set = 1;
8445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8446         sw_if_index_set = 1;
8447       else
8448         break;
8449     }
8450
8451   if (sw_if_index_set == 0)
8452     {
8453       errmsg ("missing vpp interface name. ");
8454       return -99;
8455     }
8456
8457   /* Construct the API message */
8458   M (BOND_DELETE, mp);
8459
8460   mp->sw_if_index = ntohl (sw_if_index);
8461
8462   /* send it... */
8463   S (mp);
8464
8465   /* Wait for a reply... */
8466   W (ret);
8467   return ret;
8468 }
8469
8470 static int
8471 api_bond_enslave (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_bond_enslave_t *mp;
8475   u32 bond_sw_if_index;
8476   int ret;
8477   u8 is_passive;
8478   u8 is_long_timeout;
8479   u32 bond_sw_if_index_is_set = 0;
8480   u32 sw_if_index;
8481   u8 sw_if_index_is_set = 0;
8482
8483   /* Parse args required to build the message */
8484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8485     {
8486       if (unformat (i, "sw_if_index %d", &sw_if_index))
8487         sw_if_index_is_set = 1;
8488       else if (unformat (i, "bond %u", &bond_sw_if_index))
8489         bond_sw_if_index_is_set = 1;
8490       else if (unformat (i, "passive %d", &is_passive))
8491         ;
8492       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8493         ;
8494       else
8495         break;
8496     }
8497
8498   if (bond_sw_if_index_is_set == 0)
8499     {
8500       errmsg ("Missing bond sw_if_index. ");
8501       return -99;
8502     }
8503   if (sw_if_index_is_set == 0)
8504     {
8505       errmsg ("Missing slave sw_if_index. ");
8506       return -99;
8507     }
8508
8509   /* Construct the API message */
8510   M (BOND_ENSLAVE, mp);
8511
8512   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8513   mp->sw_if_index = ntohl (sw_if_index);
8514   mp->is_long_timeout = is_long_timeout;
8515   mp->is_passive = is_passive;
8516
8517   /* send it... */
8518   S (mp);
8519
8520   /* Wait for a reply... */
8521   W (ret);
8522   return ret;
8523 }
8524
8525 static int
8526 api_bond_detach_slave (vat_main_t * vam)
8527 {
8528   unformat_input_t *i = vam->input;
8529   vl_api_bond_detach_slave_t *mp;
8530   u32 sw_if_index = ~0;
8531   u8 sw_if_index_set = 0;
8532   int ret;
8533
8534   /* Parse args required to build the message */
8535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8536     {
8537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8538         sw_if_index_set = 1;
8539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8540         sw_if_index_set = 1;
8541       else
8542         break;
8543     }
8544
8545   if (sw_if_index_set == 0)
8546     {
8547       errmsg ("missing vpp interface name. ");
8548       return -99;
8549     }
8550
8551   /* Construct the API message */
8552   M (BOND_DETACH_SLAVE, mp);
8553
8554   mp->sw_if_index = ntohl (sw_if_index);
8555
8556   /* send it... */
8557   S (mp);
8558
8559   /* Wait for a reply... */
8560   W (ret);
8561   return ret;
8562 }
8563
8564 static int
8565 api_ip_table_add_del (vat_main_t * vam)
8566 {
8567   unformat_input_t *i = vam->input;
8568   vl_api_ip_table_add_del_t *mp;
8569   u32 table_id = ~0;
8570   u8 is_ipv6 = 0;
8571   u8 is_add = 1;
8572   int ret = 0;
8573
8574   /* Parse args required to build the message */
8575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8576     {
8577       if (unformat (i, "ipv6"))
8578         is_ipv6 = 1;
8579       else if (unformat (i, "del"))
8580         is_add = 0;
8581       else if (unformat (i, "add"))
8582         is_add = 1;
8583       else if (unformat (i, "table %d", &table_id))
8584         ;
8585       else
8586         {
8587           clib_warning ("parse error '%U'", format_unformat_error, i);
8588           return -99;
8589         }
8590     }
8591
8592   if (~0 == table_id)
8593     {
8594       errmsg ("missing table-ID");
8595       return -99;
8596     }
8597
8598   /* Construct the API message */
8599   M (IP_TABLE_ADD_DEL, mp);
8600
8601   mp->table_id = ntohl (table_id);
8602   mp->is_ipv6 = is_ipv6;
8603   mp->is_add = is_add;
8604
8605   /* send it... */
8606   S (mp);
8607
8608   /* Wait for a reply... */
8609   W (ret);
8610
8611   return ret;
8612 }
8613
8614 static int
8615 api_ip_add_del_route (vat_main_t * vam)
8616 {
8617   unformat_input_t *i = vam->input;
8618   vl_api_ip_add_del_route_t *mp;
8619   u32 sw_if_index = ~0, vrf_id = 0;
8620   u8 is_ipv6 = 0;
8621   u8 is_local = 0, is_drop = 0;
8622   u8 is_unreach = 0, is_prohibit = 0;
8623   u8 is_add = 1;
8624   u32 next_hop_weight = 1;
8625   u8 is_multipath = 0;
8626   u8 address_set = 0;
8627   u8 address_length_set = 0;
8628   u32 next_hop_table_id = 0;
8629   u32 resolve_attempts = 0;
8630   u32 dst_address_length = 0;
8631   u8 next_hop_set = 0;
8632   ip4_address_t v4_dst_address, v4_next_hop_address;
8633   ip6_address_t v6_dst_address, v6_next_hop_address;
8634   int count = 1;
8635   int j;
8636   f64 before = 0;
8637   u32 random_add_del = 0;
8638   u32 *random_vector = 0;
8639   uword *random_hash;
8640   u32 random_seed = 0xdeaddabe;
8641   u32 classify_table_index = ~0;
8642   u8 is_classify = 0;
8643   u8 resolve_host = 0, resolve_attached = 0;
8644   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8645   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8646   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8647
8648   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8649   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8654         ;
8655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8656         ;
8657       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8658         {
8659           address_set = 1;
8660           is_ipv6 = 0;
8661         }
8662       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8663         {
8664           address_set = 1;
8665           is_ipv6 = 1;
8666         }
8667       else if (unformat (i, "/%d", &dst_address_length))
8668         {
8669           address_length_set = 1;
8670         }
8671
8672       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8673                                          &v4_next_hop_address))
8674         {
8675           next_hop_set = 1;
8676         }
8677       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8678                                          &v6_next_hop_address))
8679         {
8680           next_hop_set = 1;
8681         }
8682       else
8683         if (unformat
8684             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8685         {
8686           next_hop_set = 1;
8687         }
8688       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8689         {
8690           next_hop_set = 1;
8691         }
8692       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8693         ;
8694       else if (unformat (i, "weight %d", &next_hop_weight))
8695         ;
8696       else if (unformat (i, "drop"))
8697         {
8698           is_drop = 1;
8699         }
8700       else if (unformat (i, "null-send-unreach"))
8701         {
8702           is_unreach = 1;
8703         }
8704       else if (unformat (i, "null-send-prohibit"))
8705         {
8706           is_prohibit = 1;
8707         }
8708       else if (unformat (i, "local"))
8709         {
8710           is_local = 1;
8711         }
8712       else if (unformat (i, "classify %d", &classify_table_index))
8713         {
8714           is_classify = 1;
8715         }
8716       else if (unformat (i, "del"))
8717         is_add = 0;
8718       else if (unformat (i, "add"))
8719         is_add = 1;
8720       else if (unformat (i, "resolve-via-host"))
8721         resolve_host = 1;
8722       else if (unformat (i, "resolve-via-attached"))
8723         resolve_attached = 1;
8724       else if (unformat (i, "multipath"))
8725         is_multipath = 1;
8726       else if (unformat (i, "vrf %d", &vrf_id))
8727         ;
8728       else if (unformat (i, "count %d", &count))
8729         ;
8730       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8731         ;
8732       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8733         ;
8734       else if (unformat (i, "out-label %d", &next_hop_out_label))
8735         {
8736           vl_api_fib_mpls_label_t fib_label = {
8737             .label = ntohl (next_hop_out_label),
8738             .ttl = 64,
8739             .exp = 0,
8740           };
8741           vec_add1 (next_hop_out_label_stack, fib_label);
8742         }
8743       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8744         ;
8745       else if (unformat (i, "random"))
8746         random_add_del = 1;
8747       else if (unformat (i, "seed %d", &random_seed))
8748         ;
8749       else
8750         {
8751           clib_warning ("parse error '%U'", format_unformat_error, i);
8752           return -99;
8753         }
8754     }
8755
8756   if (!next_hop_set && !is_drop && !is_local &&
8757       !is_classify && !is_unreach && !is_prohibit &&
8758       MPLS_LABEL_INVALID == next_hop_via_label)
8759     {
8760       errmsg
8761         ("next hop / local / drop / unreach / prohibit / classify not set");
8762       return -99;
8763     }
8764
8765   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8766     {
8767       errmsg ("next hop and next-hop via label set");
8768       return -99;
8769     }
8770   if (address_set == 0)
8771     {
8772       errmsg ("missing addresses");
8773       return -99;
8774     }
8775
8776   if (address_length_set == 0)
8777     {
8778       errmsg ("missing address length");
8779       return -99;
8780     }
8781
8782   /* Generate a pile of unique, random routes */
8783   if (random_add_del)
8784     {
8785       u32 this_random_address;
8786       random_hash = hash_create (count, sizeof (uword));
8787
8788       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8789       for (j = 0; j <= count; j++)
8790         {
8791           do
8792             {
8793               this_random_address = random_u32 (&random_seed);
8794               this_random_address =
8795                 clib_host_to_net_u32 (this_random_address);
8796             }
8797           while (hash_get (random_hash, this_random_address));
8798           vec_add1 (random_vector, this_random_address);
8799           hash_set (random_hash, this_random_address, 1);
8800         }
8801       hash_free (random_hash);
8802       v4_dst_address.as_u32 = random_vector[0];
8803     }
8804
8805   if (count > 1)
8806     {
8807       /* Turn on async mode */
8808       vam->async_mode = 1;
8809       vam->async_errors = 0;
8810       before = vat_time_now (vam);
8811     }
8812
8813   for (j = 0; j < count; j++)
8814     {
8815       /* Construct the API message */
8816       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8817           vec_len (next_hop_out_label_stack));
8818
8819       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8820       mp->table_id = ntohl (vrf_id);
8821
8822       mp->is_add = is_add;
8823       mp->is_drop = is_drop;
8824       mp->is_unreach = is_unreach;
8825       mp->is_prohibit = is_prohibit;
8826       mp->is_ipv6 = is_ipv6;
8827       mp->is_local = is_local;
8828       mp->is_classify = is_classify;
8829       mp->is_multipath = is_multipath;
8830       mp->is_resolve_host = resolve_host;
8831       mp->is_resolve_attached = resolve_attached;
8832       mp->next_hop_weight = next_hop_weight;
8833       mp->next_hop_preference = 0;
8834       mp->dst_address_length = dst_address_length;
8835       mp->next_hop_table_id = ntohl (next_hop_table_id);
8836       mp->classify_table_index = ntohl (classify_table_index);
8837       mp->next_hop_via_label = ntohl (next_hop_via_label);
8838       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8839       if (0 != mp->next_hop_n_out_labels)
8840         {
8841           memcpy (mp->next_hop_out_label_stack,
8842                   next_hop_out_label_stack,
8843                   (vec_len (next_hop_out_label_stack) *
8844                    sizeof (vl_api_fib_mpls_label_t)));
8845           vec_free (next_hop_out_label_stack);
8846         }
8847
8848       if (is_ipv6)
8849         {
8850           clib_memcpy (mp->dst_address, &v6_dst_address,
8851                        sizeof (v6_dst_address));
8852           if (next_hop_set)
8853             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8854                          sizeof (v6_next_hop_address));
8855           increment_v6_address (&v6_dst_address);
8856         }
8857       else
8858         {
8859           clib_memcpy (mp->dst_address, &v4_dst_address,
8860                        sizeof (v4_dst_address));
8861           if (next_hop_set)
8862             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8863                          sizeof (v4_next_hop_address));
8864           if (random_add_del)
8865             v4_dst_address.as_u32 = random_vector[j + 1];
8866           else
8867             increment_v4_address (&v4_dst_address);
8868         }
8869       /* send it... */
8870       S (mp);
8871       /* If we receive SIGTERM, stop now... */
8872       if (vam->do_exit)
8873         break;
8874     }
8875
8876   /* When testing multiple add/del ops, use a control-ping to sync */
8877   if (count > 1)
8878     {
8879       vl_api_control_ping_t *mp_ping;
8880       f64 after;
8881       f64 timeout;
8882
8883       /* Shut off async mode */
8884       vam->async_mode = 0;
8885
8886       MPING (CONTROL_PING, mp_ping);
8887       S (mp_ping);
8888
8889       timeout = vat_time_now (vam) + 1.0;
8890       while (vat_time_now (vam) < timeout)
8891         if (vam->result_ready == 1)
8892           goto out;
8893       vam->retval = -99;
8894
8895     out:
8896       if (vam->retval == -99)
8897         errmsg ("timeout");
8898
8899       if (vam->async_errors > 0)
8900         {
8901           errmsg ("%d asynchronous errors", vam->async_errors);
8902           vam->retval = -98;
8903         }
8904       vam->async_errors = 0;
8905       after = vat_time_now (vam);
8906
8907       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8908       if (j > 0)
8909         count = j;
8910
8911       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8912              count, after - before, count / (after - before));
8913     }
8914   else
8915     {
8916       int ret;
8917
8918       /* Wait for a reply... */
8919       W (ret);
8920       return ret;
8921     }
8922
8923   /* Return the good/bad news */
8924   return (vam->retval);
8925 }
8926
8927 static int
8928 api_ip_mroute_add_del (vat_main_t * vam)
8929 {
8930   unformat_input_t *i = vam->input;
8931   vl_api_ip_mroute_add_del_t *mp;
8932   u32 sw_if_index = ~0, vrf_id = 0;
8933   u8 is_ipv6 = 0;
8934   u8 is_local = 0;
8935   u8 is_add = 1;
8936   u8 address_set = 0;
8937   u32 grp_address_length = 0;
8938   ip4_address_t v4_grp_address, v4_src_address;
8939   ip6_address_t v6_grp_address, v6_src_address;
8940   mfib_itf_flags_t iflags = 0;
8941   mfib_entry_flags_t eflags = 0;
8942   int ret;
8943
8944   /* Parse args required to build the message */
8945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8946     {
8947       if (unformat (i, "sw_if_index %d", &sw_if_index))
8948         ;
8949       else if (unformat (i, "%U %U",
8950                          unformat_ip4_address, &v4_src_address,
8951                          unformat_ip4_address, &v4_grp_address))
8952         {
8953           grp_address_length = 64;
8954           address_set = 1;
8955           is_ipv6 = 0;
8956         }
8957       else if (unformat (i, "%U %U",
8958                          unformat_ip6_address, &v6_src_address,
8959                          unformat_ip6_address, &v6_grp_address))
8960         {
8961           grp_address_length = 256;
8962           address_set = 1;
8963           is_ipv6 = 1;
8964         }
8965       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8966         {
8967           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8968           grp_address_length = 32;
8969           address_set = 1;
8970           is_ipv6 = 0;
8971         }
8972       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8973         {
8974           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8975           grp_address_length = 128;
8976           address_set = 1;
8977           is_ipv6 = 1;
8978         }
8979       else if (unformat (i, "/%d", &grp_address_length))
8980         ;
8981       else if (unformat (i, "local"))
8982         {
8983           is_local = 1;
8984         }
8985       else if (unformat (i, "del"))
8986         is_add = 0;
8987       else if (unformat (i, "add"))
8988         is_add = 1;
8989       else if (unformat (i, "vrf %d", &vrf_id))
8990         ;
8991       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8992         ;
8993       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8994         ;
8995       else
8996         {
8997           clib_warning ("parse error '%U'", format_unformat_error, i);
8998           return -99;
8999         }
9000     }
9001
9002   if (address_set == 0)
9003     {
9004       errmsg ("missing addresses\n");
9005       return -99;
9006     }
9007
9008   /* Construct the API message */
9009   M (IP_MROUTE_ADD_DEL, mp);
9010
9011   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9012   mp->table_id = ntohl (vrf_id);
9013
9014   mp->is_add = is_add;
9015   mp->is_ipv6 = is_ipv6;
9016   mp->is_local = is_local;
9017   mp->itf_flags = ntohl (iflags);
9018   mp->entry_flags = ntohl (eflags);
9019   mp->grp_address_length = grp_address_length;
9020   mp->grp_address_length = ntohs (mp->grp_address_length);
9021
9022   if (is_ipv6)
9023     {
9024       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9025       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9026     }
9027   else
9028     {
9029       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9030       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9031
9032     }
9033
9034   /* send it... */
9035   S (mp);
9036   /* Wait for a reply... */
9037   W (ret);
9038   return ret;
9039 }
9040
9041 static int
9042 api_mpls_table_add_del (vat_main_t * vam)
9043 {
9044   unformat_input_t *i = vam->input;
9045   vl_api_mpls_table_add_del_t *mp;
9046   u32 table_id = ~0;
9047   u8 is_add = 1;
9048   int ret = 0;
9049
9050   /* Parse args required to build the message */
9051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9052     {
9053       if (unformat (i, "table %d", &table_id))
9054         ;
9055       else if (unformat (i, "del"))
9056         is_add = 0;
9057       else if (unformat (i, "add"))
9058         is_add = 1;
9059       else
9060         {
9061           clib_warning ("parse error '%U'", format_unformat_error, i);
9062           return -99;
9063         }
9064     }
9065
9066   if (~0 == table_id)
9067     {
9068       errmsg ("missing table-ID");
9069       return -99;
9070     }
9071
9072   /* Construct the API message */
9073   M (MPLS_TABLE_ADD_DEL, mp);
9074
9075   mp->mt_table_id = ntohl (table_id);
9076   mp->mt_is_add = is_add;
9077
9078   /* send it... */
9079   S (mp);
9080
9081   /* Wait for a reply... */
9082   W (ret);
9083
9084   return ret;
9085 }
9086
9087 static int
9088 api_mpls_route_add_del (vat_main_t * vam)
9089 {
9090   unformat_input_t *i = vam->input;
9091   vl_api_mpls_route_add_del_t *mp;
9092   u32 sw_if_index = ~0, table_id = 0;
9093   u8 is_add = 1;
9094   u32 next_hop_weight = 1;
9095   u8 is_multipath = 0;
9096   u32 next_hop_table_id = 0;
9097   u8 next_hop_set = 0;
9098   ip4_address_t v4_next_hop_address = {
9099     .as_u32 = 0,
9100   };
9101   ip6_address_t v6_next_hop_address = { {0} };
9102   int count = 1;
9103   int j;
9104   f64 before = 0;
9105   u32 classify_table_index = ~0;
9106   u8 is_classify = 0;
9107   u8 resolve_host = 0, resolve_attached = 0;
9108   u8 is_interface_rx = 0;
9109   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9110   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9111   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9112   mpls_label_t local_label = MPLS_LABEL_INVALID;
9113   u8 is_eos = 0;
9114   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9115
9116   /* Parse args required to build the message */
9117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9120         ;
9121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9122         ;
9123       else if (unformat (i, "%d", &local_label))
9124         ;
9125       else if (unformat (i, "eos"))
9126         is_eos = 1;
9127       else if (unformat (i, "non-eos"))
9128         is_eos = 0;
9129       else if (unformat (i, "via %U", unformat_ip4_address,
9130                          &v4_next_hop_address))
9131         {
9132           next_hop_set = 1;
9133           next_hop_proto = DPO_PROTO_IP4;
9134         }
9135       else if (unformat (i, "via %U", unformat_ip6_address,
9136                          &v6_next_hop_address))
9137         {
9138           next_hop_set = 1;
9139           next_hop_proto = DPO_PROTO_IP6;
9140         }
9141       else if (unformat (i, "weight %d", &next_hop_weight))
9142         ;
9143       else if (unformat (i, "classify %d", &classify_table_index))
9144         {
9145           is_classify = 1;
9146         }
9147       else if (unformat (i, "del"))
9148         is_add = 0;
9149       else if (unformat (i, "add"))
9150         is_add = 1;
9151       else if (unformat (i, "resolve-via-host"))
9152         resolve_host = 1;
9153       else if (unformat (i, "resolve-via-attached"))
9154         resolve_attached = 1;
9155       else if (unformat (i, "multipath"))
9156         is_multipath = 1;
9157       else if (unformat (i, "count %d", &count))
9158         ;
9159       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9160         {
9161           next_hop_set = 1;
9162           next_hop_proto = DPO_PROTO_IP4;
9163         }
9164       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9165         {
9166           next_hop_set = 1;
9167           next_hop_proto = DPO_PROTO_IP6;
9168         }
9169       else
9170         if (unformat
9171             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9172              &sw_if_index))
9173         {
9174           next_hop_set = 1;
9175           next_hop_proto = DPO_PROTO_ETHERNET;
9176           is_interface_rx = 1;
9177         }
9178       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9179         {
9180           next_hop_set = 1;
9181           next_hop_proto = DPO_PROTO_ETHERNET;
9182           is_interface_rx = 1;
9183         }
9184       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9185         next_hop_set = 1;
9186       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9187         next_hop_set = 1;
9188       else if (unformat (i, "out-label %d", &next_hop_out_label))
9189         {
9190           vl_api_fib_mpls_label_t fib_label = {
9191             .label = ntohl (next_hop_out_label),
9192             .ttl = 64,
9193             .exp = 0,
9194           };
9195           vec_add1 (next_hop_out_label_stack, fib_label);
9196         }
9197       else
9198         {
9199           clib_warning ("parse error '%U'", format_unformat_error, i);
9200           return -99;
9201         }
9202     }
9203
9204   if (!next_hop_set && !is_classify)
9205     {
9206       errmsg ("next hop / classify not set");
9207       return -99;
9208     }
9209
9210   if (MPLS_LABEL_INVALID == local_label)
9211     {
9212       errmsg ("missing label");
9213       return -99;
9214     }
9215
9216   if (count > 1)
9217     {
9218       /* Turn on async mode */
9219       vam->async_mode = 1;
9220       vam->async_errors = 0;
9221       before = vat_time_now (vam);
9222     }
9223
9224   for (j = 0; j < count; j++)
9225     {
9226       /* Construct the API message */
9227       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9228           vec_len (next_hop_out_label_stack));
9229
9230       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9231       mp->mr_table_id = ntohl (table_id);
9232
9233       mp->mr_is_add = is_add;
9234       mp->mr_next_hop_proto = next_hop_proto;
9235       mp->mr_is_classify = is_classify;
9236       mp->mr_is_multipath = is_multipath;
9237       mp->mr_is_resolve_host = resolve_host;
9238       mp->mr_is_resolve_attached = resolve_attached;
9239       mp->mr_is_interface_rx = is_interface_rx;
9240       mp->mr_next_hop_weight = next_hop_weight;
9241       mp->mr_next_hop_preference = 0;
9242       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9243       mp->mr_classify_table_index = ntohl (classify_table_index);
9244       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9245       mp->mr_label = ntohl (local_label);
9246       mp->mr_eos = is_eos;
9247
9248       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9249       if (0 != mp->mr_next_hop_n_out_labels)
9250         {
9251           memcpy (mp->mr_next_hop_out_label_stack,
9252                   next_hop_out_label_stack,
9253                   vec_len (next_hop_out_label_stack) *
9254                   sizeof (vl_api_fib_mpls_label_t));
9255           vec_free (next_hop_out_label_stack);
9256         }
9257
9258       if (next_hop_set)
9259         {
9260           if (DPO_PROTO_IP4 == next_hop_proto)
9261             {
9262               clib_memcpy (mp->mr_next_hop,
9263                            &v4_next_hop_address,
9264                            sizeof (v4_next_hop_address));
9265             }
9266           else if (DPO_PROTO_IP6 == next_hop_proto)
9267
9268             {
9269               clib_memcpy (mp->mr_next_hop,
9270                            &v6_next_hop_address,
9271                            sizeof (v6_next_hop_address));
9272             }
9273         }
9274       local_label++;
9275
9276       /* send it... */
9277       S (mp);
9278       /* If we receive SIGTERM, stop now... */
9279       if (vam->do_exit)
9280         break;
9281     }
9282
9283   /* When testing multiple add/del ops, use a control-ping to sync */
9284   if (count > 1)
9285     {
9286       vl_api_control_ping_t *mp_ping;
9287       f64 after;
9288       f64 timeout;
9289
9290       /* Shut off async mode */
9291       vam->async_mode = 0;
9292
9293       MPING (CONTROL_PING, mp_ping);
9294       S (mp_ping);
9295
9296       timeout = vat_time_now (vam) + 1.0;
9297       while (vat_time_now (vam) < timeout)
9298         if (vam->result_ready == 1)
9299           goto out;
9300       vam->retval = -99;
9301
9302     out:
9303       if (vam->retval == -99)
9304         errmsg ("timeout");
9305
9306       if (vam->async_errors > 0)
9307         {
9308           errmsg ("%d asynchronous errors", vam->async_errors);
9309           vam->retval = -98;
9310         }
9311       vam->async_errors = 0;
9312       after = vat_time_now (vam);
9313
9314       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9315       if (j > 0)
9316         count = j;
9317
9318       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9319              count, after - before, count / (after - before));
9320     }
9321   else
9322     {
9323       int ret;
9324
9325       /* Wait for a reply... */
9326       W (ret);
9327       return ret;
9328     }
9329
9330   /* Return the good/bad news */
9331   return (vam->retval);
9332 }
9333
9334 static int
9335 api_mpls_ip_bind_unbind (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_mpls_ip_bind_unbind_t *mp;
9339   u32 ip_table_id = 0;
9340   u8 is_bind = 1;
9341   u8 is_ip4 = 1;
9342   ip4_address_t v4_address;
9343   ip6_address_t v6_address;
9344   u32 address_length;
9345   u8 address_set = 0;
9346   mpls_label_t local_label = MPLS_LABEL_INVALID;
9347   int ret;
9348
9349   /* Parse args required to build the message */
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "%U/%d", unformat_ip4_address,
9353                     &v4_address, &address_length))
9354         {
9355           is_ip4 = 1;
9356           address_set = 1;
9357         }
9358       else if (unformat (i, "%U/%d", unformat_ip6_address,
9359                          &v6_address, &address_length))
9360         {
9361           is_ip4 = 0;
9362           address_set = 1;
9363         }
9364       else if (unformat (i, "%d", &local_label))
9365         ;
9366       else if (unformat (i, "table-id %d", &ip_table_id))
9367         ;
9368       else if (unformat (i, "unbind"))
9369         is_bind = 0;
9370       else if (unformat (i, "bind"))
9371         is_bind = 1;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (!address_set)
9380     {
9381       errmsg ("IP address not set");
9382       return -99;
9383     }
9384
9385   if (MPLS_LABEL_INVALID == local_label)
9386     {
9387       errmsg ("missing label");
9388       return -99;
9389     }
9390
9391   /* Construct the API message */
9392   M (MPLS_IP_BIND_UNBIND, mp);
9393
9394   mp->mb_is_bind = is_bind;
9395   mp->mb_is_ip4 = is_ip4;
9396   mp->mb_ip_table_id = ntohl (ip_table_id);
9397   mp->mb_mpls_table_id = 0;
9398   mp->mb_label = ntohl (local_label);
9399   mp->mb_address_length = address_length;
9400
9401   if (is_ip4)
9402     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9403   else
9404     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9405
9406   /* send it... */
9407   S (mp);
9408
9409   /* Wait for a reply... */
9410   W (ret);
9411   return ret;
9412 }
9413
9414 static int
9415 api_sr_mpls_policy_add (vat_main_t * vam)
9416 {
9417   unformat_input_t *i = vam->input;
9418   vl_api_sr_mpls_policy_add_t *mp;
9419   u32 bsid = 0;
9420   u32 weight = 1;
9421   u8 type = 0;
9422   u8 n_segments = 0;
9423   u32 sid;
9424   u32 *segments = NULL;
9425   int ret;
9426
9427   /* Parse args required to build the message */
9428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9429     {
9430       if (unformat (i, "bsid %d", &bsid))
9431         ;
9432       else if (unformat (i, "weight %d", &weight))
9433         ;
9434       else if (unformat (i, "spray"))
9435         type = 1;
9436       else if (unformat (i, "next %d", &sid))
9437         {
9438           n_segments += 1;
9439           vec_add1 (segments, htonl (sid));
9440         }
9441       else
9442         {
9443           clib_warning ("parse error '%U'", format_unformat_error, i);
9444           return -99;
9445         }
9446     }
9447
9448   if (bsid == 0)
9449     {
9450       errmsg ("bsid not set");
9451       return -99;
9452     }
9453
9454   if (n_segments == 0)
9455     {
9456       errmsg ("no sid in segment stack");
9457       return -99;
9458     }
9459
9460   /* Construct the API message */
9461   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9462
9463   mp->bsid = htonl (bsid);
9464   mp->weight = htonl (weight);
9465   mp->type = type;
9466   mp->n_segments = n_segments;
9467   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9468   vec_free (segments);
9469
9470   /* send it... */
9471   S (mp);
9472
9473   /* Wait for a reply... */
9474   W (ret);
9475   return ret;
9476 }
9477
9478 static int
9479 api_sr_mpls_policy_del (vat_main_t * vam)
9480 {
9481   unformat_input_t *i = vam->input;
9482   vl_api_sr_mpls_policy_del_t *mp;
9483   u32 bsid = 0;
9484   int ret;
9485
9486   /* Parse args required to build the message */
9487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (unformat (i, "bsid %d", &bsid))
9490         ;
9491       else
9492         {
9493           clib_warning ("parse error '%U'", format_unformat_error, i);
9494           return -99;
9495         }
9496     }
9497
9498   if (bsid == 0)
9499     {
9500       errmsg ("bsid not set");
9501       return -99;
9502     }
9503
9504   /* Construct the API message */
9505   M (SR_MPLS_POLICY_DEL, mp);
9506
9507   mp->bsid = htonl (bsid);
9508
9509   /* send it... */
9510   S (mp);
9511
9512   /* Wait for a reply... */
9513   W (ret);
9514   return ret;
9515 }
9516
9517 static int
9518 api_bier_table_add_del (vat_main_t * vam)
9519 {
9520   unformat_input_t *i = vam->input;
9521   vl_api_bier_table_add_del_t *mp;
9522   u8 is_add = 1;
9523   u32 set = 0, sub_domain = 0, hdr_len = 3;
9524   mpls_label_t local_label = MPLS_LABEL_INVALID;
9525   int ret;
9526
9527   /* Parse args required to build the message */
9528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9529     {
9530       if (unformat (i, "sub-domain %d", &sub_domain))
9531         ;
9532       else if (unformat (i, "set %d", &set))
9533         ;
9534       else if (unformat (i, "label %d", &local_label))
9535         ;
9536       else if (unformat (i, "hdr-len %d", &hdr_len))
9537         ;
9538       else if (unformat (i, "add"))
9539         is_add = 1;
9540       else if (unformat (i, "del"))
9541         is_add = 0;
9542       else
9543         {
9544           clib_warning ("parse error '%U'", format_unformat_error, i);
9545           return -99;
9546         }
9547     }
9548
9549   if (MPLS_LABEL_INVALID == local_label)
9550     {
9551       errmsg ("missing label\n");
9552       return -99;
9553     }
9554
9555   /* Construct the API message */
9556   M (BIER_TABLE_ADD_DEL, mp);
9557
9558   mp->bt_is_add = is_add;
9559   mp->bt_label = ntohl (local_label);
9560   mp->bt_tbl_id.bt_set = set;
9561   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9562   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9563
9564   /* send it... */
9565   S (mp);
9566
9567   /* Wait for a reply... */
9568   W (ret);
9569
9570   return (ret);
9571 }
9572
9573 static int
9574 api_bier_route_add_del (vat_main_t * vam)
9575 {
9576   unformat_input_t *i = vam->input;
9577   vl_api_bier_route_add_del_t *mp;
9578   u8 is_add = 1;
9579   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9580   ip4_address_t v4_next_hop_address;
9581   ip6_address_t v6_next_hop_address;
9582   u8 next_hop_set = 0;
9583   u8 next_hop_proto_is_ip4 = 1;
9584   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9585   int ret;
9586
9587   /* Parse args required to build the message */
9588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9589     {
9590       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9591         {
9592           next_hop_proto_is_ip4 = 1;
9593           next_hop_set = 1;
9594         }
9595       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9596         {
9597           next_hop_proto_is_ip4 = 0;
9598           next_hop_set = 1;
9599         }
9600       if (unformat (i, "sub-domain %d", &sub_domain))
9601         ;
9602       else if (unformat (i, "set %d", &set))
9603         ;
9604       else if (unformat (i, "hdr-len %d", &hdr_len))
9605         ;
9606       else if (unformat (i, "bp %d", &bp))
9607         ;
9608       else if (unformat (i, "add"))
9609         is_add = 1;
9610       else if (unformat (i, "del"))
9611         is_add = 0;
9612       else if (unformat (i, "out-label %d", &next_hop_out_label))
9613         ;
9614       else
9615         {
9616           clib_warning ("parse error '%U'", format_unformat_error, i);
9617           return -99;
9618         }
9619     }
9620
9621   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9622     {
9623       errmsg ("next hop / label set\n");
9624       return -99;
9625     }
9626   if (0 == bp)
9627     {
9628       errmsg ("bit=position not set\n");
9629       return -99;
9630     }
9631
9632   /* Construct the API message */
9633   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9634
9635   mp->br_is_add = is_add;
9636   mp->br_tbl_id.bt_set = set;
9637   mp->br_tbl_id.bt_sub_domain = sub_domain;
9638   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9639   mp->br_bp = ntohs (bp);
9640   mp->br_n_paths = 1;
9641   mp->br_paths[0].n_labels = 1;
9642   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9643   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9644
9645   if (next_hop_proto_is_ip4)
9646     {
9647       clib_memcpy (mp->br_paths[0].next_hop,
9648                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9649     }
9650   else
9651     {
9652       clib_memcpy (mp->br_paths[0].next_hop,
9653                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9654     }
9655
9656   /* send it... */
9657   S (mp);
9658
9659   /* Wait for a reply... */
9660   W (ret);
9661
9662   return (ret);
9663 }
9664
9665 static int
9666 api_proxy_arp_add_del (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_proxy_arp_add_del_t *mp;
9670   u32 vrf_id = 0;
9671   u8 is_add = 1;
9672   ip4_address_t lo, hi;
9673   u8 range_set = 0;
9674   int ret;
9675
9676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9677     {
9678       if (unformat (i, "vrf %d", &vrf_id))
9679         ;
9680       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9681                          unformat_ip4_address, &hi))
9682         range_set = 1;
9683       else if (unformat (i, "del"))
9684         is_add = 0;
9685       else
9686         {
9687           clib_warning ("parse error '%U'", format_unformat_error, i);
9688           return -99;
9689         }
9690     }
9691
9692   if (range_set == 0)
9693     {
9694       errmsg ("address range not set");
9695       return -99;
9696     }
9697
9698   M (PROXY_ARP_ADD_DEL, mp);
9699
9700   mp->proxy.vrf_id = ntohl (vrf_id);
9701   mp->is_add = is_add;
9702   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9703   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9704
9705   S (mp);
9706   W (ret);
9707   return ret;
9708 }
9709
9710 static int
9711 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9712 {
9713   unformat_input_t *i = vam->input;
9714   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9715   u32 sw_if_index;
9716   u8 enable = 1;
9717   u8 sw_if_index_set = 0;
9718   int ret;
9719
9720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9721     {
9722       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9723         sw_if_index_set = 1;
9724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9725         sw_if_index_set = 1;
9726       else if (unformat (i, "enable"))
9727         enable = 1;
9728       else if (unformat (i, "disable"))
9729         enable = 0;
9730       else
9731         {
9732           clib_warning ("parse error '%U'", format_unformat_error, i);
9733           return -99;
9734         }
9735     }
9736
9737   if (sw_if_index_set == 0)
9738     {
9739       errmsg ("missing interface name or sw_if_index");
9740       return -99;
9741     }
9742
9743   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9744
9745   mp->sw_if_index = ntohl (sw_if_index);
9746   mp->enable_disable = enable;
9747
9748   S (mp);
9749   W (ret);
9750   return ret;
9751 }
9752
9753 static int
9754 api_mpls_tunnel_add_del (vat_main_t * vam)
9755 {
9756   unformat_input_t *i = vam->input;
9757   vl_api_mpls_tunnel_add_del_t *mp;
9758
9759   u8 is_add = 1;
9760   u8 l2_only = 0;
9761   u32 sw_if_index = ~0;
9762   u32 next_hop_sw_if_index = ~0;
9763   u32 next_hop_proto_is_ip4 = 1;
9764
9765   u32 next_hop_table_id = 0;
9766   ip4_address_t v4_next_hop_address = {
9767     .as_u32 = 0,
9768   };
9769   ip6_address_t v6_next_hop_address = { {0} };
9770   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9771   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9772   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9773   int ret;
9774
9775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9776     {
9777       if (unformat (i, "add"))
9778         is_add = 1;
9779       else
9780         if (unformat
9781             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9782         is_add = 0;
9783       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9784         is_add = 0;
9785       else if (unformat (i, "via %U",
9786                          unformat_ip4_address, &v4_next_hop_address))
9787         {
9788           next_hop_proto_is_ip4 = 1;
9789         }
9790       else if (unformat (i, "via %U",
9791                          unformat_ip6_address, &v6_next_hop_address))
9792         {
9793           next_hop_proto_is_ip4 = 0;
9794         }
9795       else if (unformat (i, "via-label %d", &next_hop_via_label))
9796         ;
9797       else
9798         if (unformat
9799             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9800         ;
9801       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9802         ;
9803       else if (unformat (i, "l2-only"))
9804         l2_only = 1;
9805       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9806         ;
9807       else if (unformat (i, "out-label %d", &next_hop_out_label))
9808         {
9809           vl_api_fib_mpls_label_t fib_label = {
9810             .label = ntohl (next_hop_out_label),
9811             .ttl = 64,
9812             .exp = 0,
9813           };
9814           vec_add1 (next_hop_out_label_stack, fib_label);
9815         }
9816       else
9817         {
9818           clib_warning ("parse error '%U'", format_unformat_error, i);
9819           return -99;
9820         }
9821     }
9822
9823   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9824       vec_len (next_hop_out_label_stack));
9825
9826   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9827   mp->mt_sw_if_index = ntohl (sw_if_index);
9828   mp->mt_is_add = is_add;
9829   mp->mt_l2_only = l2_only;
9830   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9831   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9832   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9833   mp->mt_next_hop_weight = 1;
9834   mp->mt_next_hop_preference = 0;
9835
9836   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9837
9838   if (0 != mp->mt_next_hop_n_out_labels)
9839     {
9840       clib_memcpy (mp->mt_next_hop_out_label_stack,
9841                    next_hop_out_label_stack,
9842                    (vec_len (next_hop_out_label_stack) *
9843                     sizeof (vl_api_fib_mpls_label_t)));
9844       vec_free (next_hop_out_label_stack);
9845     }
9846
9847   if (next_hop_proto_is_ip4)
9848     {
9849       clib_memcpy (mp->mt_next_hop,
9850                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9851     }
9852   else
9853     {
9854       clib_memcpy (mp->mt_next_hop,
9855                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9856     }
9857
9858   S (mp);
9859   W (ret);
9860   return ret;
9861 }
9862
9863 static int
9864 api_sw_interface_set_unnumbered (vat_main_t * vam)
9865 {
9866   unformat_input_t *i = vam->input;
9867   vl_api_sw_interface_set_unnumbered_t *mp;
9868   u32 sw_if_index;
9869   u32 unnum_sw_index = ~0;
9870   u8 is_add = 1;
9871   u8 sw_if_index_set = 0;
9872   int ret;
9873
9874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9875     {
9876       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9877         sw_if_index_set = 1;
9878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9879         sw_if_index_set = 1;
9880       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9881         ;
9882       else if (unformat (i, "del"))
9883         is_add = 0;
9884       else
9885         {
9886           clib_warning ("parse error '%U'", format_unformat_error, i);
9887           return -99;
9888         }
9889     }
9890
9891   if (sw_if_index_set == 0)
9892     {
9893       errmsg ("missing interface name or sw_if_index");
9894       return -99;
9895     }
9896
9897   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9898
9899   mp->sw_if_index = ntohl (sw_if_index);
9900   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9901   mp->is_add = is_add;
9902
9903   S (mp);
9904   W (ret);
9905   return ret;
9906 }
9907
9908 static int
9909 api_ip_neighbor_add_del (vat_main_t * vam)
9910 {
9911   unformat_input_t *i = vam->input;
9912   vl_api_ip_neighbor_add_del_t *mp;
9913   u32 sw_if_index;
9914   u8 sw_if_index_set = 0;
9915   u8 is_add = 1;
9916   u8 is_static = 0;
9917   u8 is_no_fib_entry = 0;
9918   u8 mac_address[6];
9919   u8 mac_set = 0;
9920   u8 v4_address_set = 0;
9921   u8 v6_address_set = 0;
9922   ip4_address_t v4address;
9923   ip6_address_t v6address;
9924   int ret;
9925
9926   clib_memset (mac_address, 0, sizeof (mac_address));
9927
9928   /* Parse args required to build the message */
9929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9930     {
9931       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9932         {
9933           mac_set = 1;
9934         }
9935       else if (unformat (i, "del"))
9936         is_add = 0;
9937       else
9938         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9939         sw_if_index_set = 1;
9940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9941         sw_if_index_set = 1;
9942       else if (unformat (i, "is_static"))
9943         is_static = 1;
9944       else if (unformat (i, "no-fib-entry"))
9945         is_no_fib_entry = 1;
9946       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9947         v4_address_set = 1;
9948       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9949         v6_address_set = 1;
9950       else
9951         {
9952           clib_warning ("parse error '%U'", format_unformat_error, i);
9953           return -99;
9954         }
9955     }
9956
9957   if (sw_if_index_set == 0)
9958     {
9959       errmsg ("missing interface name or sw_if_index");
9960       return -99;
9961     }
9962   if (v4_address_set && v6_address_set)
9963     {
9964       errmsg ("both v4 and v6 addresses set");
9965       return -99;
9966     }
9967   if (!v4_address_set && !v6_address_set)
9968     {
9969       errmsg ("no address set");
9970       return -99;
9971     }
9972
9973   /* Construct the API message */
9974   M (IP_NEIGHBOR_ADD_DEL, mp);
9975
9976   mp->sw_if_index = ntohl (sw_if_index);
9977   mp->is_add = is_add;
9978   mp->is_static = is_static;
9979   mp->is_no_adj_fib = is_no_fib_entry;
9980   if (mac_set)
9981     clib_memcpy (mp->mac_address, mac_address, 6);
9982   if (v6_address_set)
9983     {
9984       mp->is_ipv6 = 1;
9985       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9986     }
9987   else
9988     {
9989       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9990       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9991     }
9992
9993   /* send it... */
9994   S (mp);
9995
9996   /* Wait for a reply, return good/bad news  */
9997   W (ret);
9998   return ret;
9999 }
10000
10001 static int
10002 api_create_vlan_subif (vat_main_t * vam)
10003 {
10004   unformat_input_t *i = vam->input;
10005   vl_api_create_vlan_subif_t *mp;
10006   u32 sw_if_index;
10007   u8 sw_if_index_set = 0;
10008   u32 vlan_id;
10009   u8 vlan_id_set = 0;
10010   int ret;
10011
10012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10013     {
10014       if (unformat (i, "sw_if_index %d", &sw_if_index))
10015         sw_if_index_set = 1;
10016       else
10017         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10018         sw_if_index_set = 1;
10019       else if (unformat (i, "vlan %d", &vlan_id))
10020         vlan_id_set = 1;
10021       else
10022         {
10023           clib_warning ("parse error '%U'", format_unformat_error, i);
10024           return -99;
10025         }
10026     }
10027
10028   if (sw_if_index_set == 0)
10029     {
10030       errmsg ("missing interface name or sw_if_index");
10031       return -99;
10032     }
10033
10034   if (vlan_id_set == 0)
10035     {
10036       errmsg ("missing vlan_id");
10037       return -99;
10038     }
10039   M (CREATE_VLAN_SUBIF, mp);
10040
10041   mp->sw_if_index = ntohl (sw_if_index);
10042   mp->vlan_id = ntohl (vlan_id);
10043
10044   S (mp);
10045   W (ret);
10046   return ret;
10047 }
10048
10049 #define foreach_create_subif_bit                \
10050 _(no_tags)                                      \
10051 _(one_tag)                                      \
10052 _(two_tags)                                     \
10053 _(dot1ad)                                       \
10054 _(exact_match)                                  \
10055 _(default_sub)                                  \
10056 _(outer_vlan_id_any)                            \
10057 _(inner_vlan_id_any)
10058
10059 static int
10060 api_create_subif (vat_main_t * vam)
10061 {
10062   unformat_input_t *i = vam->input;
10063   vl_api_create_subif_t *mp;
10064   u32 sw_if_index;
10065   u8 sw_if_index_set = 0;
10066   u32 sub_id;
10067   u8 sub_id_set = 0;
10068   u32 no_tags = 0;
10069   u32 one_tag = 0;
10070   u32 two_tags = 0;
10071   u32 dot1ad = 0;
10072   u32 exact_match = 0;
10073   u32 default_sub = 0;
10074   u32 outer_vlan_id_any = 0;
10075   u32 inner_vlan_id_any = 0;
10076   u32 tmp;
10077   u16 outer_vlan_id = 0;
10078   u16 inner_vlan_id = 0;
10079   int ret;
10080
10081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10082     {
10083       if (unformat (i, "sw_if_index %d", &sw_if_index))
10084         sw_if_index_set = 1;
10085       else
10086         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10087         sw_if_index_set = 1;
10088       else if (unformat (i, "sub_id %d", &sub_id))
10089         sub_id_set = 1;
10090       else if (unformat (i, "outer_vlan_id %d", &tmp))
10091         outer_vlan_id = tmp;
10092       else if (unformat (i, "inner_vlan_id %d", &tmp))
10093         inner_vlan_id = tmp;
10094
10095 #define _(a) else if (unformat (i, #a)) a = 1 ;
10096       foreach_create_subif_bit
10097 #undef _
10098         else
10099         {
10100           clib_warning ("parse error '%U'", format_unformat_error, i);
10101           return -99;
10102         }
10103     }
10104
10105   if (sw_if_index_set == 0)
10106     {
10107       errmsg ("missing interface name or sw_if_index");
10108       return -99;
10109     }
10110
10111   if (sub_id_set == 0)
10112     {
10113       errmsg ("missing sub_id");
10114       return -99;
10115     }
10116   M (CREATE_SUBIF, mp);
10117
10118   mp->sw_if_index = ntohl (sw_if_index);
10119   mp->sub_id = ntohl (sub_id);
10120
10121 #define _(a) mp->a = a;
10122   foreach_create_subif_bit;
10123 #undef _
10124
10125   mp->outer_vlan_id = ntohs (outer_vlan_id);
10126   mp->inner_vlan_id = ntohs (inner_vlan_id);
10127
10128   S (mp);
10129   W (ret);
10130   return ret;
10131 }
10132
10133 static int
10134 api_oam_add_del (vat_main_t * vam)
10135 {
10136   unformat_input_t *i = vam->input;
10137   vl_api_oam_add_del_t *mp;
10138   u32 vrf_id = 0;
10139   u8 is_add = 1;
10140   ip4_address_t src, dst;
10141   u8 src_set = 0;
10142   u8 dst_set = 0;
10143   int ret;
10144
10145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (i, "vrf %d", &vrf_id))
10148         ;
10149       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10150         src_set = 1;
10151       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10152         dst_set = 1;
10153       else if (unformat (i, "del"))
10154         is_add = 0;
10155       else
10156         {
10157           clib_warning ("parse error '%U'", format_unformat_error, i);
10158           return -99;
10159         }
10160     }
10161
10162   if (src_set == 0)
10163     {
10164       errmsg ("missing src addr");
10165       return -99;
10166     }
10167
10168   if (dst_set == 0)
10169     {
10170       errmsg ("missing dst addr");
10171       return -99;
10172     }
10173
10174   M (OAM_ADD_DEL, mp);
10175
10176   mp->vrf_id = ntohl (vrf_id);
10177   mp->is_add = is_add;
10178   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10179   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10180
10181   S (mp);
10182   W (ret);
10183   return ret;
10184 }
10185
10186 static int
10187 api_reset_fib (vat_main_t * vam)
10188 {
10189   unformat_input_t *i = vam->input;
10190   vl_api_reset_fib_t *mp;
10191   u32 vrf_id = 0;
10192   u8 is_ipv6 = 0;
10193   u8 vrf_id_set = 0;
10194
10195   int ret;
10196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10197     {
10198       if (unformat (i, "vrf %d", &vrf_id))
10199         vrf_id_set = 1;
10200       else if (unformat (i, "ipv6"))
10201         is_ipv6 = 1;
10202       else
10203         {
10204           clib_warning ("parse error '%U'", format_unformat_error, i);
10205           return -99;
10206         }
10207     }
10208
10209   if (vrf_id_set == 0)
10210     {
10211       errmsg ("missing vrf id");
10212       return -99;
10213     }
10214
10215   M (RESET_FIB, mp);
10216
10217   mp->vrf_id = ntohl (vrf_id);
10218   mp->is_ipv6 = is_ipv6;
10219
10220   S (mp);
10221   W (ret);
10222   return ret;
10223 }
10224
10225 static int
10226 api_dhcp_proxy_config (vat_main_t * vam)
10227 {
10228   unformat_input_t *i = vam->input;
10229   vl_api_dhcp_proxy_config_t *mp;
10230   u32 rx_vrf_id = 0;
10231   u32 server_vrf_id = 0;
10232   u8 is_add = 1;
10233   u8 v4_address_set = 0;
10234   u8 v6_address_set = 0;
10235   ip4_address_t v4address;
10236   ip6_address_t v6address;
10237   u8 v4_src_address_set = 0;
10238   u8 v6_src_address_set = 0;
10239   ip4_address_t v4srcaddress;
10240   ip6_address_t v6srcaddress;
10241   int ret;
10242
10243   /* Parse args required to build the message */
10244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10245     {
10246       if (unformat (i, "del"))
10247         is_add = 0;
10248       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10249         ;
10250       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10251         ;
10252       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10253         v4_address_set = 1;
10254       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10255         v6_address_set = 1;
10256       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10257         v4_src_address_set = 1;
10258       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10259         v6_src_address_set = 1;
10260       else
10261         break;
10262     }
10263
10264   if (v4_address_set && v6_address_set)
10265     {
10266       errmsg ("both v4 and v6 server addresses set");
10267       return -99;
10268     }
10269   if (!v4_address_set && !v6_address_set)
10270     {
10271       errmsg ("no server addresses set");
10272       return -99;
10273     }
10274
10275   if (v4_src_address_set && v6_src_address_set)
10276     {
10277       errmsg ("both v4 and v6  src addresses set");
10278       return -99;
10279     }
10280   if (!v4_src_address_set && !v6_src_address_set)
10281     {
10282       errmsg ("no src addresses set");
10283       return -99;
10284     }
10285
10286   if (!(v4_src_address_set && v4_address_set) &&
10287       !(v6_src_address_set && v6_address_set))
10288     {
10289       errmsg ("no matching server and src addresses set");
10290       return -99;
10291     }
10292
10293   /* Construct the API message */
10294   M (DHCP_PROXY_CONFIG, mp);
10295
10296   mp->is_add = is_add;
10297   mp->rx_vrf_id = ntohl (rx_vrf_id);
10298   mp->server_vrf_id = ntohl (server_vrf_id);
10299   if (v6_address_set)
10300     {
10301       mp->is_ipv6 = 1;
10302       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10303       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10304     }
10305   else
10306     {
10307       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10308       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10309     }
10310
10311   /* send it... */
10312   S (mp);
10313
10314   /* Wait for a reply, return good/bad news  */
10315   W (ret);
10316   return ret;
10317 }
10318
10319 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10320 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10321
10322 static void
10323 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10324 {
10325   vat_main_t *vam = &vat_main;
10326   u32 i, count = mp->count;
10327   vl_api_dhcp_server_t *s;
10328
10329   if (mp->is_ipv6)
10330     print (vam->ofp,
10331            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10332            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10333            ntohl (mp->rx_vrf_id),
10334            format_ip6_address, mp->dhcp_src_address,
10335            mp->vss_type, mp->vss_vpn_ascii_id,
10336            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10337   else
10338     print (vam->ofp,
10339            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10340            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10341            ntohl (mp->rx_vrf_id),
10342            format_ip4_address, mp->dhcp_src_address,
10343            mp->vss_type, mp->vss_vpn_ascii_id,
10344            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10345
10346   for (i = 0; i < count; i++)
10347     {
10348       s = &mp->servers[i];
10349
10350       if (mp->is_ipv6)
10351         print (vam->ofp,
10352                " Server Table-ID %d, Server Address %U",
10353                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10354       else
10355         print (vam->ofp,
10356                " Server Table-ID %d, Server Address %U",
10357                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10358     }
10359 }
10360
10361 static void vl_api_dhcp_proxy_details_t_handler_json
10362   (vl_api_dhcp_proxy_details_t * mp)
10363 {
10364   vat_main_t *vam = &vat_main;
10365   vat_json_node_t *node = NULL;
10366   u32 i, count = mp->count;
10367   struct in_addr ip4;
10368   struct in6_addr ip6;
10369   vl_api_dhcp_server_t *s;
10370
10371   if (VAT_JSON_ARRAY != vam->json_tree.type)
10372     {
10373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10374       vat_json_init_array (&vam->json_tree);
10375     }
10376   node = vat_json_array_add (&vam->json_tree);
10377
10378   vat_json_init_object (node);
10379   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10380   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10381                              sizeof (mp->vss_type));
10382   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10383                                    mp->vss_vpn_ascii_id);
10384   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10385   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10386
10387   if (mp->is_ipv6)
10388     {
10389       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10390       vat_json_object_add_ip6 (node, "src_address", ip6);
10391     }
10392   else
10393     {
10394       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10395       vat_json_object_add_ip4 (node, "src_address", ip4);
10396     }
10397
10398   for (i = 0; i < count; i++)
10399     {
10400       s = &mp->servers[i];
10401
10402       vat_json_object_add_uint (node, "server-table-id",
10403                                 ntohl (s->server_vrf_id));
10404
10405       if (mp->is_ipv6)
10406         {
10407           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10408           vat_json_object_add_ip4 (node, "src_address", ip4);
10409         }
10410       else
10411         {
10412           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10413           vat_json_object_add_ip6 (node, "server_address", ip6);
10414         }
10415     }
10416 }
10417
10418 static int
10419 api_dhcp_proxy_dump (vat_main_t * vam)
10420 {
10421   unformat_input_t *i = vam->input;
10422   vl_api_control_ping_t *mp_ping;
10423   vl_api_dhcp_proxy_dump_t *mp;
10424   u8 is_ipv6 = 0;
10425   int ret;
10426
10427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10428     {
10429       if (unformat (i, "ipv6"))
10430         is_ipv6 = 1;
10431       else
10432         {
10433           clib_warning ("parse error '%U'", format_unformat_error, i);
10434           return -99;
10435         }
10436     }
10437
10438   M (DHCP_PROXY_DUMP, mp);
10439
10440   mp->is_ip6 = is_ipv6;
10441   S (mp);
10442
10443   /* Use a control ping for synchronization */
10444   MPING (CONTROL_PING, mp_ping);
10445   S (mp_ping);
10446
10447   W (ret);
10448   return ret;
10449 }
10450
10451 static int
10452 api_dhcp_proxy_set_vss (vat_main_t * vam)
10453 {
10454   unformat_input_t *i = vam->input;
10455   vl_api_dhcp_proxy_set_vss_t *mp;
10456   u8 is_ipv6 = 0;
10457   u8 is_add = 1;
10458   u32 tbl_id = ~0;
10459   u8 vss_type = VSS_TYPE_DEFAULT;
10460   u8 *vpn_ascii_id = 0;
10461   u32 oui = 0;
10462   u32 fib_id = 0;
10463   int ret;
10464
10465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10466     {
10467       if (unformat (i, "tbl_id %d", &tbl_id))
10468         ;
10469       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10470         vss_type = VSS_TYPE_ASCII;
10471       else if (unformat (i, "fib_id %d", &fib_id))
10472         vss_type = VSS_TYPE_VPN_ID;
10473       else if (unformat (i, "oui %d", &oui))
10474         vss_type = VSS_TYPE_VPN_ID;
10475       else if (unformat (i, "ipv6"))
10476         is_ipv6 = 1;
10477       else if (unformat (i, "del"))
10478         is_add = 0;
10479       else
10480         break;
10481     }
10482
10483   if (tbl_id == ~0)
10484     {
10485       errmsg ("missing tbl_id ");
10486       vec_free (vpn_ascii_id);
10487       return -99;
10488     }
10489
10490   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10491     {
10492       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10493       vec_free (vpn_ascii_id);
10494       return -99;
10495     }
10496
10497   M (DHCP_PROXY_SET_VSS, mp);
10498   mp->tbl_id = ntohl (tbl_id);
10499   mp->vss_type = vss_type;
10500   if (vpn_ascii_id)
10501     {
10502       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10503       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10504     }
10505   mp->vpn_index = ntohl (fib_id);
10506   mp->oui = ntohl (oui);
10507   mp->is_ipv6 = is_ipv6;
10508   mp->is_add = is_add;
10509
10510   S (mp);
10511   W (ret);
10512
10513   vec_free (vpn_ascii_id);
10514   return ret;
10515 }
10516
10517 static int
10518 api_dhcp_client_config (vat_main_t * vam)
10519 {
10520   unformat_input_t *i = vam->input;
10521   vl_api_dhcp_client_config_t *mp;
10522   u32 sw_if_index;
10523   u8 sw_if_index_set = 0;
10524   u8 is_add = 1;
10525   u8 *hostname = 0;
10526   u8 disable_event = 0;
10527   int ret;
10528
10529   /* Parse args required to build the message */
10530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (unformat (i, "del"))
10533         is_add = 0;
10534       else
10535         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10536         sw_if_index_set = 1;
10537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10538         sw_if_index_set = 1;
10539       else if (unformat (i, "hostname %s", &hostname))
10540         ;
10541       else if (unformat (i, "disable_event"))
10542         disable_event = 1;
10543       else
10544         break;
10545     }
10546
10547   if (sw_if_index_set == 0)
10548     {
10549       errmsg ("missing interface name or sw_if_index");
10550       return -99;
10551     }
10552
10553   if (vec_len (hostname) > 63)
10554     {
10555       errmsg ("hostname too long");
10556     }
10557   vec_add1 (hostname, 0);
10558
10559   /* Construct the API message */
10560   M (DHCP_CLIENT_CONFIG, mp);
10561
10562   mp->is_add = is_add;
10563   mp->client.sw_if_index = htonl (sw_if_index);
10564   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10565   vec_free (hostname);
10566   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10567   mp->client.pid = htonl (getpid ());
10568
10569   /* send it... */
10570   S (mp);
10571
10572   /* Wait for a reply, return good/bad news  */
10573   W (ret);
10574   return ret;
10575 }
10576
10577 static int
10578 api_set_ip_flow_hash (vat_main_t * vam)
10579 {
10580   unformat_input_t *i = vam->input;
10581   vl_api_set_ip_flow_hash_t *mp;
10582   u32 vrf_id = 0;
10583   u8 is_ipv6 = 0;
10584   u8 vrf_id_set = 0;
10585   u8 src = 0;
10586   u8 dst = 0;
10587   u8 sport = 0;
10588   u8 dport = 0;
10589   u8 proto = 0;
10590   u8 reverse = 0;
10591   int ret;
10592
10593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (unformat (i, "vrf %d", &vrf_id))
10596         vrf_id_set = 1;
10597       else if (unformat (i, "ipv6"))
10598         is_ipv6 = 1;
10599       else if (unformat (i, "src"))
10600         src = 1;
10601       else if (unformat (i, "dst"))
10602         dst = 1;
10603       else if (unformat (i, "sport"))
10604         sport = 1;
10605       else if (unformat (i, "dport"))
10606         dport = 1;
10607       else if (unformat (i, "proto"))
10608         proto = 1;
10609       else if (unformat (i, "reverse"))
10610         reverse = 1;
10611
10612       else
10613         {
10614           clib_warning ("parse error '%U'", format_unformat_error, i);
10615           return -99;
10616         }
10617     }
10618
10619   if (vrf_id_set == 0)
10620     {
10621       errmsg ("missing vrf id");
10622       return -99;
10623     }
10624
10625   M (SET_IP_FLOW_HASH, mp);
10626   mp->src = src;
10627   mp->dst = dst;
10628   mp->sport = sport;
10629   mp->dport = dport;
10630   mp->proto = proto;
10631   mp->reverse = reverse;
10632   mp->vrf_id = ntohl (vrf_id);
10633   mp->is_ipv6 = is_ipv6;
10634
10635   S (mp);
10636   W (ret);
10637   return ret;
10638 }
10639
10640 static int
10641 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10642 {
10643   unformat_input_t *i = vam->input;
10644   vl_api_sw_interface_ip6_enable_disable_t *mp;
10645   u32 sw_if_index;
10646   u8 sw_if_index_set = 0;
10647   u8 enable = 0;
10648   int ret;
10649
10650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10651     {
10652       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10653         sw_if_index_set = 1;
10654       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10655         sw_if_index_set = 1;
10656       else if (unformat (i, "enable"))
10657         enable = 1;
10658       else if (unformat (i, "disable"))
10659         enable = 0;
10660       else
10661         {
10662           clib_warning ("parse error '%U'", format_unformat_error, i);
10663           return -99;
10664         }
10665     }
10666
10667   if (sw_if_index_set == 0)
10668     {
10669       errmsg ("missing interface name or sw_if_index");
10670       return -99;
10671     }
10672
10673   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10674
10675   mp->sw_if_index = ntohl (sw_if_index);
10676   mp->enable = enable;
10677
10678   S (mp);
10679   W (ret);
10680   return ret;
10681 }
10682
10683 static int
10684 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10685 {
10686   unformat_input_t *i = vam->input;
10687   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10688   u32 sw_if_index;
10689   u8 sw_if_index_set = 0;
10690   u8 v6_address_set = 0;
10691   ip6_address_t v6address;
10692   int ret;
10693
10694   /* Parse args required to build the message */
10695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10696     {
10697       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10698         sw_if_index_set = 1;
10699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10700         sw_if_index_set = 1;
10701       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10702         v6_address_set = 1;
10703       else
10704         break;
10705     }
10706
10707   if (sw_if_index_set == 0)
10708     {
10709       errmsg ("missing interface name or sw_if_index");
10710       return -99;
10711     }
10712   if (!v6_address_set)
10713     {
10714       errmsg ("no address set");
10715       return -99;
10716     }
10717
10718   /* Construct the API message */
10719   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10723
10724   /* send it... */
10725   S (mp);
10726
10727   /* Wait for a reply, return good/bad news  */
10728   W (ret);
10729   return ret;
10730 }
10731
10732 static int
10733 api_ip6nd_proxy_add_del (vat_main_t * vam)
10734 {
10735   unformat_input_t *i = vam->input;
10736   vl_api_ip6nd_proxy_add_del_t *mp;
10737   u32 sw_if_index = ~0;
10738   u8 v6_address_set = 0;
10739   ip6_address_t v6address;
10740   u8 is_del = 0;
10741   int ret;
10742
10743   /* Parse args required to build the message */
10744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10745     {
10746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10747         ;
10748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10749         ;
10750       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10751         v6_address_set = 1;
10752       if (unformat (i, "del"))
10753         is_del = 1;
10754       else
10755         {
10756           clib_warning ("parse error '%U'", format_unformat_error, i);
10757           return -99;
10758         }
10759     }
10760
10761   if (sw_if_index == ~0)
10762     {
10763       errmsg ("missing interface name or sw_if_index");
10764       return -99;
10765     }
10766   if (!v6_address_set)
10767     {
10768       errmsg ("no address set");
10769       return -99;
10770     }
10771
10772   /* Construct the API message */
10773   M (IP6ND_PROXY_ADD_DEL, mp);
10774
10775   mp->is_del = is_del;
10776   mp->sw_if_index = ntohl (sw_if_index);
10777   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10778
10779   /* send it... */
10780   S (mp);
10781
10782   /* Wait for a reply, return good/bad news  */
10783   W (ret);
10784   return ret;
10785 }
10786
10787 static int
10788 api_ip6nd_proxy_dump (vat_main_t * vam)
10789 {
10790   vl_api_ip6nd_proxy_dump_t *mp;
10791   vl_api_control_ping_t *mp_ping;
10792   int ret;
10793
10794   M (IP6ND_PROXY_DUMP, mp);
10795
10796   S (mp);
10797
10798   /* Use a control ping for synchronization */
10799   MPING (CONTROL_PING, mp_ping);
10800   S (mp_ping);
10801
10802   W (ret);
10803   return ret;
10804 }
10805
10806 static void vl_api_ip6nd_proxy_details_t_handler
10807   (vl_api_ip6nd_proxy_details_t * mp)
10808 {
10809   vat_main_t *vam = &vat_main;
10810
10811   print (vam->ofp, "host %U sw_if_index %d",
10812          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10813 }
10814
10815 static void vl_api_ip6nd_proxy_details_t_handler_json
10816   (vl_api_ip6nd_proxy_details_t * mp)
10817 {
10818   vat_main_t *vam = &vat_main;
10819   struct in6_addr ip6;
10820   vat_json_node_t *node = NULL;
10821
10822   if (VAT_JSON_ARRAY != vam->json_tree.type)
10823     {
10824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10825       vat_json_init_array (&vam->json_tree);
10826     }
10827   node = vat_json_array_add (&vam->json_tree);
10828
10829   vat_json_init_object (node);
10830   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10831
10832   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10833   vat_json_object_add_ip6 (node, "host", ip6);
10834 }
10835
10836 static int
10837 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10838 {
10839   unformat_input_t *i = vam->input;
10840   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10841   u32 sw_if_index;
10842   u8 sw_if_index_set = 0;
10843   u32 address_length = 0;
10844   u8 v6_address_set = 0;
10845   ip6_address_t v6address;
10846   u8 use_default = 0;
10847   u8 no_advertise = 0;
10848   u8 off_link = 0;
10849   u8 no_autoconfig = 0;
10850   u8 no_onlink = 0;
10851   u8 is_no = 0;
10852   u32 val_lifetime = 0;
10853   u32 pref_lifetime = 0;
10854   int ret;
10855
10856   /* Parse args required to build the message */
10857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10858     {
10859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10860         sw_if_index_set = 1;
10861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10862         sw_if_index_set = 1;
10863       else if (unformat (i, "%U/%d",
10864                          unformat_ip6_address, &v6address, &address_length))
10865         v6_address_set = 1;
10866       else if (unformat (i, "val_life %d", &val_lifetime))
10867         ;
10868       else if (unformat (i, "pref_life %d", &pref_lifetime))
10869         ;
10870       else if (unformat (i, "def"))
10871         use_default = 1;
10872       else if (unformat (i, "noadv"))
10873         no_advertise = 1;
10874       else if (unformat (i, "offl"))
10875         off_link = 1;
10876       else if (unformat (i, "noauto"))
10877         no_autoconfig = 1;
10878       else if (unformat (i, "nolink"))
10879         no_onlink = 1;
10880       else if (unformat (i, "isno"))
10881         is_no = 1;
10882       else
10883         {
10884           clib_warning ("parse error '%U'", format_unformat_error, i);
10885           return -99;
10886         }
10887     }
10888
10889   if (sw_if_index_set == 0)
10890     {
10891       errmsg ("missing interface name or sw_if_index");
10892       return -99;
10893     }
10894   if (!v6_address_set)
10895     {
10896       errmsg ("no address set");
10897       return -99;
10898     }
10899
10900   /* Construct the API message */
10901   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10902
10903   mp->sw_if_index = ntohl (sw_if_index);
10904   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10905   mp->address_length = address_length;
10906   mp->use_default = use_default;
10907   mp->no_advertise = no_advertise;
10908   mp->off_link = off_link;
10909   mp->no_autoconfig = no_autoconfig;
10910   mp->no_onlink = no_onlink;
10911   mp->is_no = is_no;
10912   mp->val_lifetime = ntohl (val_lifetime);
10913   mp->pref_lifetime = ntohl (pref_lifetime);
10914
10915   /* send it... */
10916   S (mp);
10917
10918   /* Wait for a reply, return good/bad news  */
10919   W (ret);
10920   return ret;
10921 }
10922
10923 static int
10924 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10925 {
10926   unformat_input_t *i = vam->input;
10927   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10928   u32 sw_if_index;
10929   u8 sw_if_index_set = 0;
10930   u8 suppress = 0;
10931   u8 managed = 0;
10932   u8 other = 0;
10933   u8 ll_option = 0;
10934   u8 send_unicast = 0;
10935   u8 cease = 0;
10936   u8 is_no = 0;
10937   u8 default_router = 0;
10938   u32 max_interval = 0;
10939   u32 min_interval = 0;
10940   u32 lifetime = 0;
10941   u32 initial_count = 0;
10942   u32 initial_interval = 0;
10943   int ret;
10944
10945
10946   /* Parse args required to build the message */
10947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10948     {
10949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10950         sw_if_index_set = 1;
10951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10952         sw_if_index_set = 1;
10953       else if (unformat (i, "maxint %d", &max_interval))
10954         ;
10955       else if (unformat (i, "minint %d", &min_interval))
10956         ;
10957       else if (unformat (i, "life %d", &lifetime))
10958         ;
10959       else if (unformat (i, "count %d", &initial_count))
10960         ;
10961       else if (unformat (i, "interval %d", &initial_interval))
10962         ;
10963       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10964         suppress = 1;
10965       else if (unformat (i, "managed"))
10966         managed = 1;
10967       else if (unformat (i, "other"))
10968         other = 1;
10969       else if (unformat (i, "ll"))
10970         ll_option = 1;
10971       else if (unformat (i, "send"))
10972         send_unicast = 1;
10973       else if (unformat (i, "cease"))
10974         cease = 1;
10975       else if (unformat (i, "isno"))
10976         is_no = 1;
10977       else if (unformat (i, "def"))
10978         default_router = 1;
10979       else
10980         {
10981           clib_warning ("parse error '%U'", format_unformat_error, i);
10982           return -99;
10983         }
10984     }
10985
10986   if (sw_if_index_set == 0)
10987     {
10988       errmsg ("missing interface name or sw_if_index");
10989       return -99;
10990     }
10991
10992   /* Construct the API message */
10993   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10994
10995   mp->sw_if_index = ntohl (sw_if_index);
10996   mp->max_interval = ntohl (max_interval);
10997   mp->min_interval = ntohl (min_interval);
10998   mp->lifetime = ntohl (lifetime);
10999   mp->initial_count = ntohl (initial_count);
11000   mp->initial_interval = ntohl (initial_interval);
11001   mp->suppress = suppress;
11002   mp->managed = managed;
11003   mp->other = other;
11004   mp->ll_option = ll_option;
11005   mp->send_unicast = send_unicast;
11006   mp->cease = cease;
11007   mp->is_no = is_no;
11008   mp->default_router = default_router;
11009
11010   /* send it... */
11011   S (mp);
11012
11013   /* Wait for a reply, return good/bad news  */
11014   W (ret);
11015   return ret;
11016 }
11017
11018 static int
11019 api_set_arp_neighbor_limit (vat_main_t * vam)
11020 {
11021   unformat_input_t *i = vam->input;
11022   vl_api_set_arp_neighbor_limit_t *mp;
11023   u32 arp_nbr_limit;
11024   u8 limit_set = 0;
11025   u8 is_ipv6 = 0;
11026   int ret;
11027
11028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11031         limit_set = 1;
11032       else if (unformat (i, "ipv6"))
11033         is_ipv6 = 1;
11034       else
11035         {
11036           clib_warning ("parse error '%U'", format_unformat_error, i);
11037           return -99;
11038         }
11039     }
11040
11041   if (limit_set == 0)
11042     {
11043       errmsg ("missing limit value");
11044       return -99;
11045     }
11046
11047   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11048
11049   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11050   mp->is_ipv6 = is_ipv6;
11051
11052   S (mp);
11053   W (ret);
11054   return ret;
11055 }
11056
11057 static int
11058 api_l2_patch_add_del (vat_main_t * vam)
11059 {
11060   unformat_input_t *i = vam->input;
11061   vl_api_l2_patch_add_del_t *mp;
11062   u32 rx_sw_if_index;
11063   u8 rx_sw_if_index_set = 0;
11064   u32 tx_sw_if_index;
11065   u8 tx_sw_if_index_set = 0;
11066   u8 is_add = 1;
11067   int ret;
11068
11069   /* Parse args required to build the message */
11070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11073         rx_sw_if_index_set = 1;
11074       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11075         tx_sw_if_index_set = 1;
11076       else if (unformat (i, "rx"))
11077         {
11078           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11079             {
11080               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11081                             &rx_sw_if_index))
11082                 rx_sw_if_index_set = 1;
11083             }
11084           else
11085             break;
11086         }
11087       else if (unformat (i, "tx"))
11088         {
11089           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11090             {
11091               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11092                             &tx_sw_if_index))
11093                 tx_sw_if_index_set = 1;
11094             }
11095           else
11096             break;
11097         }
11098       else if (unformat (i, "del"))
11099         is_add = 0;
11100       else
11101         break;
11102     }
11103
11104   if (rx_sw_if_index_set == 0)
11105     {
11106       errmsg ("missing rx interface name or rx_sw_if_index");
11107       return -99;
11108     }
11109
11110   if (tx_sw_if_index_set == 0)
11111     {
11112       errmsg ("missing tx interface name or tx_sw_if_index");
11113       return -99;
11114     }
11115
11116   M (L2_PATCH_ADD_DEL, mp);
11117
11118   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11119   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11120   mp->is_add = is_add;
11121
11122   S (mp);
11123   W (ret);
11124   return ret;
11125 }
11126
11127 u8 is_del;
11128 u8 localsid_addr[16];
11129 u8 end_psp;
11130 u8 behavior;
11131 u32 sw_if_index;
11132 u32 vlan_index;
11133 u32 fib_table;
11134 u8 nh_addr[16];
11135
11136 static int
11137 api_sr_localsid_add_del (vat_main_t * vam)
11138 {
11139   unformat_input_t *i = vam->input;
11140   vl_api_sr_localsid_add_del_t *mp;
11141
11142   u8 is_del;
11143   ip6_address_t localsid;
11144   u8 end_psp = 0;
11145   u8 behavior = ~0;
11146   u32 sw_if_index;
11147   u32 fib_table = ~(u32) 0;
11148   ip6_address_t nh_addr6;
11149   ip4_address_t nh_addr4;
11150   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11151   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11152
11153   bool nexthop_set = 0;
11154
11155   int ret;
11156
11157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11158     {
11159       if (unformat (i, "del"))
11160         is_del = 1;
11161       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11162       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11163         nexthop_set = 1;
11164       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11165         nexthop_set = 1;
11166       else if (unformat (i, "behavior %u", &behavior));
11167       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11168       else if (unformat (i, "fib-table %u", &fib_table));
11169       else if (unformat (i, "end.psp %u", &behavior));
11170       else
11171         break;
11172     }
11173
11174   M (SR_LOCALSID_ADD_DEL, mp);
11175
11176   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11177   if (nexthop_set)
11178     {
11179       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11180       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11181     }
11182   mp->behavior = behavior;
11183   mp->sw_if_index = ntohl (sw_if_index);
11184   mp->fib_table = ntohl (fib_table);
11185   mp->end_psp = end_psp;
11186   mp->is_del = is_del;
11187
11188   S (mp);
11189   W (ret);
11190   return ret;
11191 }
11192
11193 static int
11194 api_ioam_enable (vat_main_t * vam)
11195 {
11196   unformat_input_t *input = vam->input;
11197   vl_api_ioam_enable_t *mp;
11198   u32 id = 0;
11199   int has_trace_option = 0;
11200   int has_pot_option = 0;
11201   int has_seqno_option = 0;
11202   int has_analyse_option = 0;
11203   int ret;
11204
11205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11206     {
11207       if (unformat (input, "trace"))
11208         has_trace_option = 1;
11209       else if (unformat (input, "pot"))
11210         has_pot_option = 1;
11211       else if (unformat (input, "seqno"))
11212         has_seqno_option = 1;
11213       else if (unformat (input, "analyse"))
11214         has_analyse_option = 1;
11215       else
11216         break;
11217     }
11218   M (IOAM_ENABLE, mp);
11219   mp->id = htons (id);
11220   mp->seqno = has_seqno_option;
11221   mp->analyse = has_analyse_option;
11222   mp->pot_enable = has_pot_option;
11223   mp->trace_enable = has_trace_option;
11224
11225   S (mp);
11226   W (ret);
11227   return ret;
11228 }
11229
11230
11231 static int
11232 api_ioam_disable (vat_main_t * vam)
11233 {
11234   vl_api_ioam_disable_t *mp;
11235   int ret;
11236
11237   M (IOAM_DISABLE, mp);
11238   S (mp);
11239   W (ret);
11240   return ret;
11241 }
11242
11243 #define foreach_tcp_proto_field                 \
11244 _(src_port)                                     \
11245 _(dst_port)
11246
11247 #define foreach_udp_proto_field                 \
11248 _(src_port)                                     \
11249 _(dst_port)
11250
11251 #define foreach_ip4_proto_field                 \
11252 _(src_address)                                  \
11253 _(dst_address)                                  \
11254 _(tos)                                          \
11255 _(length)                                       \
11256 _(fragment_id)                                  \
11257 _(ttl)                                          \
11258 _(protocol)                                     \
11259 _(checksum)
11260
11261 typedef struct
11262 {
11263   u16 src_port, dst_port;
11264 } tcpudp_header_t;
11265
11266 #if VPP_API_TEST_BUILTIN == 0
11267 uword
11268 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11269 {
11270   u8 **maskp = va_arg (*args, u8 **);
11271   u8 *mask = 0;
11272   u8 found_something = 0;
11273   tcp_header_t *tcp;
11274
11275 #define _(a) u8 a=0;
11276   foreach_tcp_proto_field;
11277 #undef _
11278
11279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11280     {
11281       if (0);
11282 #define _(a) else if (unformat (input, #a)) a=1;
11283       foreach_tcp_proto_field
11284 #undef _
11285         else
11286         break;
11287     }
11288
11289 #define _(a) found_something += a;
11290   foreach_tcp_proto_field;
11291 #undef _
11292
11293   if (found_something == 0)
11294     return 0;
11295
11296   vec_validate (mask, sizeof (*tcp) - 1);
11297
11298   tcp = (tcp_header_t *) mask;
11299
11300 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11301   foreach_tcp_proto_field;
11302 #undef _
11303
11304   *maskp = mask;
11305   return 1;
11306 }
11307
11308 uword
11309 unformat_udp_mask (unformat_input_t * input, va_list * args)
11310 {
11311   u8 **maskp = va_arg (*args, u8 **);
11312   u8 *mask = 0;
11313   u8 found_something = 0;
11314   udp_header_t *udp;
11315
11316 #define _(a) u8 a=0;
11317   foreach_udp_proto_field;
11318 #undef _
11319
11320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11321     {
11322       if (0);
11323 #define _(a) else if (unformat (input, #a)) a=1;
11324       foreach_udp_proto_field
11325 #undef _
11326         else
11327         break;
11328     }
11329
11330 #define _(a) found_something += a;
11331   foreach_udp_proto_field;
11332 #undef _
11333
11334   if (found_something == 0)
11335     return 0;
11336
11337   vec_validate (mask, sizeof (*udp) - 1);
11338
11339   udp = (udp_header_t *) mask;
11340
11341 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11342   foreach_udp_proto_field;
11343 #undef _
11344
11345   *maskp = mask;
11346   return 1;
11347 }
11348
11349 uword
11350 unformat_l4_mask (unformat_input_t * input, va_list * args)
11351 {
11352   u8 **maskp = va_arg (*args, u8 **);
11353   u16 src_port = 0, dst_port = 0;
11354   tcpudp_header_t *tcpudp;
11355
11356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11357     {
11358       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11359         return 1;
11360       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11361         return 1;
11362       else if (unformat (input, "src_port"))
11363         src_port = 0xFFFF;
11364       else if (unformat (input, "dst_port"))
11365         dst_port = 0xFFFF;
11366       else
11367         return 0;
11368     }
11369
11370   if (!src_port && !dst_port)
11371     return 0;
11372
11373   u8 *mask = 0;
11374   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11375
11376   tcpudp = (tcpudp_header_t *) mask;
11377   tcpudp->src_port = src_port;
11378   tcpudp->dst_port = dst_port;
11379
11380   *maskp = mask;
11381
11382   return 1;
11383 }
11384
11385 uword
11386 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11387 {
11388   u8 **maskp = va_arg (*args, u8 **);
11389   u8 *mask = 0;
11390   u8 found_something = 0;
11391   ip4_header_t *ip;
11392
11393 #define _(a) u8 a=0;
11394   foreach_ip4_proto_field;
11395 #undef _
11396   u8 version = 0;
11397   u8 hdr_length = 0;
11398
11399
11400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11401     {
11402       if (unformat (input, "version"))
11403         version = 1;
11404       else if (unformat (input, "hdr_length"))
11405         hdr_length = 1;
11406       else if (unformat (input, "src"))
11407         src_address = 1;
11408       else if (unformat (input, "dst"))
11409         dst_address = 1;
11410       else if (unformat (input, "proto"))
11411         protocol = 1;
11412
11413 #define _(a) else if (unformat (input, #a)) a=1;
11414       foreach_ip4_proto_field
11415 #undef _
11416         else
11417         break;
11418     }
11419
11420 #define _(a) found_something += a;
11421   foreach_ip4_proto_field;
11422 #undef _
11423
11424   if (found_something == 0)
11425     return 0;
11426
11427   vec_validate (mask, sizeof (*ip) - 1);
11428
11429   ip = (ip4_header_t *) mask;
11430
11431 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11432   foreach_ip4_proto_field;
11433 #undef _
11434
11435   ip->ip_version_and_header_length = 0;
11436
11437   if (version)
11438     ip->ip_version_and_header_length |= 0xF0;
11439
11440   if (hdr_length)
11441     ip->ip_version_and_header_length |= 0x0F;
11442
11443   *maskp = mask;
11444   return 1;
11445 }
11446
11447 #define foreach_ip6_proto_field                 \
11448 _(src_address)                                  \
11449 _(dst_address)                                  \
11450 _(payload_length)                               \
11451 _(hop_limit)                                    \
11452 _(protocol)
11453
11454 uword
11455 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11456 {
11457   u8 **maskp = va_arg (*args, u8 **);
11458   u8 *mask = 0;
11459   u8 found_something = 0;
11460   ip6_header_t *ip;
11461   u32 ip_version_traffic_class_and_flow_label;
11462
11463 #define _(a) u8 a=0;
11464   foreach_ip6_proto_field;
11465 #undef _
11466   u8 version = 0;
11467   u8 traffic_class = 0;
11468   u8 flow_label = 0;
11469
11470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11471     {
11472       if (unformat (input, "version"))
11473         version = 1;
11474       else if (unformat (input, "traffic-class"))
11475         traffic_class = 1;
11476       else if (unformat (input, "flow-label"))
11477         flow_label = 1;
11478       else if (unformat (input, "src"))
11479         src_address = 1;
11480       else if (unformat (input, "dst"))
11481         dst_address = 1;
11482       else if (unformat (input, "proto"))
11483         protocol = 1;
11484
11485 #define _(a) else if (unformat (input, #a)) a=1;
11486       foreach_ip6_proto_field
11487 #undef _
11488         else
11489         break;
11490     }
11491
11492 #define _(a) found_something += a;
11493   foreach_ip6_proto_field;
11494 #undef _
11495
11496   if (found_something == 0)
11497     return 0;
11498
11499   vec_validate (mask, sizeof (*ip) - 1);
11500
11501   ip = (ip6_header_t *) mask;
11502
11503 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11504   foreach_ip6_proto_field;
11505 #undef _
11506
11507   ip_version_traffic_class_and_flow_label = 0;
11508
11509   if (version)
11510     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11511
11512   if (traffic_class)
11513     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11514
11515   if (flow_label)
11516     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11517
11518   ip->ip_version_traffic_class_and_flow_label =
11519     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11520
11521   *maskp = mask;
11522   return 1;
11523 }
11524
11525 uword
11526 unformat_l3_mask (unformat_input_t * input, va_list * args)
11527 {
11528   u8 **maskp = va_arg (*args, u8 **);
11529
11530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11531     {
11532       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11533         return 1;
11534       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11535         return 1;
11536       else
11537         break;
11538     }
11539   return 0;
11540 }
11541
11542 uword
11543 unformat_l2_mask (unformat_input_t * input, va_list * args)
11544 {
11545   u8 **maskp = va_arg (*args, u8 **);
11546   u8 *mask = 0;
11547   u8 src = 0;
11548   u8 dst = 0;
11549   u8 proto = 0;
11550   u8 tag1 = 0;
11551   u8 tag2 = 0;
11552   u8 ignore_tag1 = 0;
11553   u8 ignore_tag2 = 0;
11554   u8 cos1 = 0;
11555   u8 cos2 = 0;
11556   u8 dot1q = 0;
11557   u8 dot1ad = 0;
11558   int len = 14;
11559
11560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11561     {
11562       if (unformat (input, "src"))
11563         src = 1;
11564       else if (unformat (input, "dst"))
11565         dst = 1;
11566       else if (unformat (input, "proto"))
11567         proto = 1;
11568       else if (unformat (input, "tag1"))
11569         tag1 = 1;
11570       else if (unformat (input, "tag2"))
11571         tag2 = 1;
11572       else if (unformat (input, "ignore-tag1"))
11573         ignore_tag1 = 1;
11574       else if (unformat (input, "ignore-tag2"))
11575         ignore_tag2 = 1;
11576       else if (unformat (input, "cos1"))
11577         cos1 = 1;
11578       else if (unformat (input, "cos2"))
11579         cos2 = 1;
11580       else if (unformat (input, "dot1q"))
11581         dot1q = 1;
11582       else if (unformat (input, "dot1ad"))
11583         dot1ad = 1;
11584       else
11585         break;
11586     }
11587   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11588        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11589     return 0;
11590
11591   if (tag1 || ignore_tag1 || cos1 || dot1q)
11592     len = 18;
11593   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11594     len = 22;
11595
11596   vec_validate (mask, len - 1);
11597
11598   if (dst)
11599     clib_memset (mask, 0xff, 6);
11600
11601   if (src)
11602     clib_memset (mask + 6, 0xff, 6);
11603
11604   if (tag2 || dot1ad)
11605     {
11606       /* inner vlan tag */
11607       if (tag2)
11608         {
11609           mask[19] = 0xff;
11610           mask[18] = 0x0f;
11611         }
11612       if (cos2)
11613         mask[18] |= 0xe0;
11614       if (proto)
11615         mask[21] = mask[20] = 0xff;
11616       if (tag1)
11617         {
11618           mask[15] = 0xff;
11619           mask[14] = 0x0f;
11620         }
11621       if (cos1)
11622         mask[14] |= 0xe0;
11623       *maskp = mask;
11624       return 1;
11625     }
11626   if (tag1 | dot1q)
11627     {
11628       if (tag1)
11629         {
11630           mask[15] = 0xff;
11631           mask[14] = 0x0f;
11632         }
11633       if (cos1)
11634         mask[14] |= 0xe0;
11635       if (proto)
11636         mask[16] = mask[17] = 0xff;
11637
11638       *maskp = mask;
11639       return 1;
11640     }
11641   if (cos2)
11642     mask[18] |= 0xe0;
11643   if (cos1)
11644     mask[14] |= 0xe0;
11645   if (proto)
11646     mask[12] = mask[13] = 0xff;
11647
11648   *maskp = mask;
11649   return 1;
11650 }
11651
11652 uword
11653 unformat_classify_mask (unformat_input_t * input, va_list * args)
11654 {
11655   u8 **maskp = va_arg (*args, u8 **);
11656   u32 *skipp = va_arg (*args, u32 *);
11657   u32 *matchp = va_arg (*args, u32 *);
11658   u32 match;
11659   u8 *mask = 0;
11660   u8 *l2 = 0;
11661   u8 *l3 = 0;
11662   u8 *l4 = 0;
11663   int i;
11664
11665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11666     {
11667       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11668         ;
11669       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11670         ;
11671       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11672         ;
11673       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11674         ;
11675       else
11676         break;
11677     }
11678
11679   if (l4 && !l3)
11680     {
11681       vec_free (mask);
11682       vec_free (l2);
11683       vec_free (l4);
11684       return 0;
11685     }
11686
11687   if (mask || l2 || l3 || l4)
11688     {
11689       if (l2 || l3 || l4)
11690         {
11691           /* "With a free Ethernet header in every package" */
11692           if (l2 == 0)
11693             vec_validate (l2, 13);
11694           mask = l2;
11695           if (vec_len (l3))
11696             {
11697               vec_append (mask, l3);
11698               vec_free (l3);
11699             }
11700           if (vec_len (l4))
11701             {
11702               vec_append (mask, l4);
11703               vec_free (l4);
11704             }
11705         }
11706
11707       /* Scan forward looking for the first significant mask octet */
11708       for (i = 0; i < vec_len (mask); i++)
11709         if (mask[i])
11710           break;
11711
11712       /* compute (skip, match) params */
11713       *skipp = i / sizeof (u32x4);
11714       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11715
11716       /* Pad mask to an even multiple of the vector size */
11717       while (vec_len (mask) % sizeof (u32x4))
11718         vec_add1 (mask, 0);
11719
11720       match = vec_len (mask) / sizeof (u32x4);
11721
11722       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11723         {
11724           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11725           if (*tmp || *(tmp + 1))
11726             break;
11727           match--;
11728         }
11729       if (match == 0)
11730         clib_warning ("BUG: match 0");
11731
11732       _vec_len (mask) = match * sizeof (u32x4);
11733
11734       *matchp = match;
11735       *maskp = mask;
11736
11737       return 1;
11738     }
11739
11740   return 0;
11741 }
11742 #endif /* VPP_API_TEST_BUILTIN */
11743
11744 #define foreach_l2_next                         \
11745 _(drop, DROP)                                   \
11746 _(ethernet, ETHERNET_INPUT)                     \
11747 _(ip4, IP4_INPUT)                               \
11748 _(ip6, IP6_INPUT)
11749
11750 uword
11751 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11752 {
11753   u32 *miss_next_indexp = va_arg (*args, u32 *);
11754   u32 next_index = 0;
11755   u32 tmp;
11756
11757 #define _(n,N) \
11758   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11759   foreach_l2_next;
11760 #undef _
11761
11762   if (unformat (input, "%d", &tmp))
11763     {
11764       next_index = tmp;
11765       goto out;
11766     }
11767
11768   return 0;
11769
11770 out:
11771   *miss_next_indexp = next_index;
11772   return 1;
11773 }
11774
11775 #define foreach_ip_next                         \
11776 _(drop, DROP)                                   \
11777 _(local, LOCAL)                                 \
11778 _(rewrite, REWRITE)
11779
11780 uword
11781 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11782 {
11783   u32 *miss_next_indexp = va_arg (*args, u32 *);
11784   u32 next_index = 0;
11785   u32 tmp;
11786
11787 #define _(n,N) \
11788   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11789   foreach_ip_next;
11790 #undef _
11791
11792   if (unformat (input, "%d", &tmp))
11793     {
11794       next_index = tmp;
11795       goto out;
11796     }
11797
11798   return 0;
11799
11800 out:
11801   *miss_next_indexp = next_index;
11802   return 1;
11803 }
11804
11805 #define foreach_acl_next                        \
11806 _(deny, DENY)
11807
11808 uword
11809 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11810 {
11811   u32 *miss_next_indexp = va_arg (*args, u32 *);
11812   u32 next_index = 0;
11813   u32 tmp;
11814
11815 #define _(n,N) \
11816   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11817   foreach_acl_next;
11818 #undef _
11819
11820   if (unformat (input, "permit"))
11821     {
11822       next_index = ~0;
11823       goto out;
11824     }
11825   else if (unformat (input, "%d", &tmp))
11826     {
11827       next_index = tmp;
11828       goto out;
11829     }
11830
11831   return 0;
11832
11833 out:
11834   *miss_next_indexp = next_index;
11835   return 1;
11836 }
11837
11838 uword
11839 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11840 {
11841   u32 *r = va_arg (*args, u32 *);
11842
11843   if (unformat (input, "conform-color"))
11844     *r = POLICE_CONFORM;
11845   else if (unformat (input, "exceed-color"))
11846     *r = POLICE_EXCEED;
11847   else
11848     return 0;
11849
11850   return 1;
11851 }
11852
11853 static int
11854 api_classify_add_del_table (vat_main_t * vam)
11855 {
11856   unformat_input_t *i = vam->input;
11857   vl_api_classify_add_del_table_t *mp;
11858
11859   u32 nbuckets = 2;
11860   u32 skip = ~0;
11861   u32 match = ~0;
11862   int is_add = 1;
11863   int del_chain = 0;
11864   u32 table_index = ~0;
11865   u32 next_table_index = ~0;
11866   u32 miss_next_index = ~0;
11867   u32 memory_size = 32 << 20;
11868   u8 *mask = 0;
11869   u32 current_data_flag = 0;
11870   int current_data_offset = 0;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "del"))
11876         is_add = 0;
11877       else if (unformat (i, "del-chain"))
11878         {
11879           is_add = 0;
11880           del_chain = 1;
11881         }
11882       else if (unformat (i, "buckets %d", &nbuckets))
11883         ;
11884       else if (unformat (i, "memory_size %d", &memory_size))
11885         ;
11886       else if (unformat (i, "skip %d", &skip))
11887         ;
11888       else if (unformat (i, "match %d", &match))
11889         ;
11890       else if (unformat (i, "table %d", &table_index))
11891         ;
11892       else if (unformat (i, "mask %U", unformat_classify_mask,
11893                          &mask, &skip, &match))
11894         ;
11895       else if (unformat (i, "next-table %d", &next_table_index))
11896         ;
11897       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11898                          &miss_next_index))
11899         ;
11900       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11901                          &miss_next_index))
11902         ;
11903       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11904                          &miss_next_index))
11905         ;
11906       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11907         ;
11908       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11909         ;
11910       else
11911         break;
11912     }
11913
11914   if (is_add && mask == 0)
11915     {
11916       errmsg ("Mask required");
11917       return -99;
11918     }
11919
11920   if (is_add && skip == ~0)
11921     {
11922       errmsg ("skip count required");
11923       return -99;
11924     }
11925
11926   if (is_add && match == ~0)
11927     {
11928       errmsg ("match count required");
11929       return -99;
11930     }
11931
11932   if (!is_add && table_index == ~0)
11933     {
11934       errmsg ("table index required for delete");
11935       return -99;
11936     }
11937
11938   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11939
11940   mp->is_add = is_add;
11941   mp->del_chain = del_chain;
11942   mp->table_index = ntohl (table_index);
11943   mp->nbuckets = ntohl (nbuckets);
11944   mp->memory_size = ntohl (memory_size);
11945   mp->skip_n_vectors = ntohl (skip);
11946   mp->match_n_vectors = ntohl (match);
11947   mp->next_table_index = ntohl (next_table_index);
11948   mp->miss_next_index = ntohl (miss_next_index);
11949   mp->current_data_flag = ntohl (current_data_flag);
11950   mp->current_data_offset = ntohl (current_data_offset);
11951   mp->mask_len = ntohl (vec_len (mask));
11952   clib_memcpy (mp->mask, mask, vec_len (mask));
11953
11954   vec_free (mask);
11955
11956   S (mp);
11957   W (ret);
11958   return ret;
11959 }
11960
11961 #if VPP_API_TEST_BUILTIN == 0
11962 uword
11963 unformat_l4_match (unformat_input_t * input, va_list * args)
11964 {
11965   u8 **matchp = va_arg (*args, u8 **);
11966
11967   u8 *proto_header = 0;
11968   int src_port = 0;
11969   int dst_port = 0;
11970
11971   tcpudp_header_t h;
11972
11973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11974     {
11975       if (unformat (input, "src_port %d", &src_port))
11976         ;
11977       else if (unformat (input, "dst_port %d", &dst_port))
11978         ;
11979       else
11980         return 0;
11981     }
11982
11983   h.src_port = clib_host_to_net_u16 (src_port);
11984   h.dst_port = clib_host_to_net_u16 (dst_port);
11985   vec_validate (proto_header, sizeof (h) - 1);
11986   memcpy (proto_header, &h, sizeof (h));
11987
11988   *matchp = proto_header;
11989
11990   return 1;
11991 }
11992
11993 uword
11994 unformat_ip4_match (unformat_input_t * input, va_list * args)
11995 {
11996   u8 **matchp = va_arg (*args, u8 **);
11997   u8 *match = 0;
11998   ip4_header_t *ip;
11999   int version = 0;
12000   u32 version_val;
12001   int hdr_length = 0;
12002   u32 hdr_length_val;
12003   int src = 0, dst = 0;
12004   ip4_address_t src_val, dst_val;
12005   int proto = 0;
12006   u32 proto_val;
12007   int tos = 0;
12008   u32 tos_val;
12009   int length = 0;
12010   u32 length_val;
12011   int fragment_id = 0;
12012   u32 fragment_id_val;
12013   int ttl = 0;
12014   int ttl_val;
12015   int checksum = 0;
12016   u32 checksum_val;
12017
12018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12019     {
12020       if (unformat (input, "version %d", &version_val))
12021         version = 1;
12022       else if (unformat (input, "hdr_length %d", &hdr_length_val))
12023         hdr_length = 1;
12024       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
12025         src = 1;
12026       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12027         dst = 1;
12028       else if (unformat (input, "proto %d", &proto_val))
12029         proto = 1;
12030       else if (unformat (input, "tos %d", &tos_val))
12031         tos = 1;
12032       else if (unformat (input, "length %d", &length_val))
12033         length = 1;
12034       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12035         fragment_id = 1;
12036       else if (unformat (input, "ttl %d", &ttl_val))
12037         ttl = 1;
12038       else if (unformat (input, "checksum %d", &checksum_val))
12039         checksum = 1;
12040       else
12041         break;
12042     }
12043
12044   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12045       + ttl + checksum == 0)
12046     return 0;
12047
12048   /*
12049    * Aligned because we use the real comparison functions
12050    */
12051   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12052
12053   ip = (ip4_header_t *) match;
12054
12055   /* These are realistically matched in practice */
12056   if (src)
12057     ip->src_address.as_u32 = src_val.as_u32;
12058
12059   if (dst)
12060     ip->dst_address.as_u32 = dst_val.as_u32;
12061
12062   if (proto)
12063     ip->protocol = proto_val;
12064
12065
12066   /* These are not, but they're included for completeness */
12067   if (version)
12068     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12069
12070   if (hdr_length)
12071     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12072
12073   if (tos)
12074     ip->tos = tos_val;
12075
12076   if (length)
12077     ip->length = clib_host_to_net_u16 (length_val);
12078
12079   if (ttl)
12080     ip->ttl = ttl_val;
12081
12082   if (checksum)
12083     ip->checksum = clib_host_to_net_u16 (checksum_val);
12084
12085   *matchp = match;
12086   return 1;
12087 }
12088
12089 uword
12090 unformat_ip6_match (unformat_input_t * input, va_list * args)
12091 {
12092   u8 **matchp = va_arg (*args, u8 **);
12093   u8 *match = 0;
12094   ip6_header_t *ip;
12095   int version = 0;
12096   u32 version_val;
12097   u8 traffic_class = 0;
12098   u32 traffic_class_val = 0;
12099   u8 flow_label = 0;
12100   u8 flow_label_val;
12101   int src = 0, dst = 0;
12102   ip6_address_t src_val, dst_val;
12103   int proto = 0;
12104   u32 proto_val;
12105   int payload_length = 0;
12106   u32 payload_length_val;
12107   int hop_limit = 0;
12108   int hop_limit_val;
12109   u32 ip_version_traffic_class_and_flow_label;
12110
12111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12112     {
12113       if (unformat (input, "version %d", &version_val))
12114         version = 1;
12115       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12116         traffic_class = 1;
12117       else if (unformat (input, "flow_label %d", &flow_label_val))
12118         flow_label = 1;
12119       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12120         src = 1;
12121       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12122         dst = 1;
12123       else if (unformat (input, "proto %d", &proto_val))
12124         proto = 1;
12125       else if (unformat (input, "payload_length %d", &payload_length_val))
12126         payload_length = 1;
12127       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12128         hop_limit = 1;
12129       else
12130         break;
12131     }
12132
12133   if (version + traffic_class + flow_label + src + dst + proto +
12134       payload_length + hop_limit == 0)
12135     return 0;
12136
12137   /*
12138    * Aligned because we use the real comparison functions
12139    */
12140   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12141
12142   ip = (ip6_header_t *) match;
12143
12144   if (src)
12145     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12146
12147   if (dst)
12148     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12149
12150   if (proto)
12151     ip->protocol = proto_val;
12152
12153   ip_version_traffic_class_and_flow_label = 0;
12154
12155   if (version)
12156     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12157
12158   if (traffic_class)
12159     ip_version_traffic_class_and_flow_label |=
12160       (traffic_class_val & 0xFF) << 20;
12161
12162   if (flow_label)
12163     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12164
12165   ip->ip_version_traffic_class_and_flow_label =
12166     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12167
12168   if (payload_length)
12169     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12170
12171   if (hop_limit)
12172     ip->hop_limit = hop_limit_val;
12173
12174   *matchp = match;
12175   return 1;
12176 }
12177
12178 uword
12179 unformat_l3_match (unformat_input_t * input, va_list * args)
12180 {
12181   u8 **matchp = va_arg (*args, u8 **);
12182
12183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12184     {
12185       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12186         return 1;
12187       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12188         return 1;
12189       else
12190         break;
12191     }
12192   return 0;
12193 }
12194
12195 uword
12196 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12197 {
12198   u8 *tagp = va_arg (*args, u8 *);
12199   u32 tag;
12200
12201   if (unformat (input, "%d", &tag))
12202     {
12203       tagp[0] = (tag >> 8) & 0x0F;
12204       tagp[1] = tag & 0xFF;
12205       return 1;
12206     }
12207
12208   return 0;
12209 }
12210
12211 uword
12212 unformat_l2_match (unformat_input_t * input, va_list * args)
12213 {
12214   u8 **matchp = va_arg (*args, u8 **);
12215   u8 *match = 0;
12216   u8 src = 0;
12217   u8 src_val[6];
12218   u8 dst = 0;
12219   u8 dst_val[6];
12220   u8 proto = 0;
12221   u16 proto_val;
12222   u8 tag1 = 0;
12223   u8 tag1_val[2];
12224   u8 tag2 = 0;
12225   u8 tag2_val[2];
12226   int len = 14;
12227   u8 ignore_tag1 = 0;
12228   u8 ignore_tag2 = 0;
12229   u8 cos1 = 0;
12230   u8 cos2 = 0;
12231   u32 cos1_val = 0;
12232   u32 cos2_val = 0;
12233
12234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12235     {
12236       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12237         src = 1;
12238       else
12239         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12240         dst = 1;
12241       else if (unformat (input, "proto %U",
12242                          unformat_ethernet_type_host_byte_order, &proto_val))
12243         proto = 1;
12244       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12245         tag1 = 1;
12246       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12247         tag2 = 1;
12248       else if (unformat (input, "ignore-tag1"))
12249         ignore_tag1 = 1;
12250       else if (unformat (input, "ignore-tag2"))
12251         ignore_tag2 = 1;
12252       else if (unformat (input, "cos1 %d", &cos1_val))
12253         cos1 = 1;
12254       else if (unformat (input, "cos2 %d", &cos2_val))
12255         cos2 = 1;
12256       else
12257         break;
12258     }
12259   if ((src + dst + proto + tag1 + tag2 +
12260        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12261     return 0;
12262
12263   if (tag1 || ignore_tag1 || cos1)
12264     len = 18;
12265   if (tag2 || ignore_tag2 || cos2)
12266     len = 22;
12267
12268   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12269
12270   if (dst)
12271     clib_memcpy (match, dst_val, 6);
12272
12273   if (src)
12274     clib_memcpy (match + 6, src_val, 6);
12275
12276   if (tag2)
12277     {
12278       /* inner vlan tag */
12279       match[19] = tag2_val[1];
12280       match[18] = tag2_val[0];
12281       if (cos2)
12282         match[18] |= (cos2_val & 0x7) << 5;
12283       if (proto)
12284         {
12285           match[21] = proto_val & 0xff;
12286           match[20] = proto_val >> 8;
12287         }
12288       if (tag1)
12289         {
12290           match[15] = tag1_val[1];
12291           match[14] = tag1_val[0];
12292         }
12293       if (cos1)
12294         match[14] |= (cos1_val & 0x7) << 5;
12295       *matchp = match;
12296       return 1;
12297     }
12298   if (tag1)
12299     {
12300       match[15] = tag1_val[1];
12301       match[14] = tag1_val[0];
12302       if (proto)
12303         {
12304           match[17] = proto_val & 0xff;
12305           match[16] = proto_val >> 8;
12306         }
12307       if (cos1)
12308         match[14] |= (cos1_val & 0x7) << 5;
12309
12310       *matchp = match;
12311       return 1;
12312     }
12313   if (cos2)
12314     match[18] |= (cos2_val & 0x7) << 5;
12315   if (cos1)
12316     match[14] |= (cos1_val & 0x7) << 5;
12317   if (proto)
12318     {
12319       match[13] = proto_val & 0xff;
12320       match[12] = proto_val >> 8;
12321     }
12322
12323   *matchp = match;
12324   return 1;
12325 }
12326
12327 uword
12328 unformat_qos_source (unformat_input_t * input, va_list * args)
12329 {
12330   int *qs = va_arg (*args, int *);
12331
12332   if (unformat (input, "ip"))
12333     *qs = QOS_SOURCE_IP;
12334   else if (unformat (input, "mpls"))
12335     *qs = QOS_SOURCE_MPLS;
12336   else if (unformat (input, "ext"))
12337     *qs = QOS_SOURCE_EXT;
12338   else if (unformat (input, "vlan"))
12339     *qs = QOS_SOURCE_VLAN;
12340   else
12341     return 0;
12342
12343   return 1;
12344 }
12345 #endif
12346
12347 uword
12348 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12349 {
12350   u8 **matchp = va_arg (*args, u8 **);
12351   u32 skip_n_vectors = va_arg (*args, u32);
12352   u32 match_n_vectors = va_arg (*args, u32);
12353
12354   u8 *match = 0;
12355   u8 *l2 = 0;
12356   u8 *l3 = 0;
12357   u8 *l4 = 0;
12358
12359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12360     {
12361       if (unformat (input, "hex %U", unformat_hex_string, &match))
12362         ;
12363       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12364         ;
12365       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12366         ;
12367       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12368         ;
12369       else
12370         break;
12371     }
12372
12373   if (l4 && !l3)
12374     {
12375       vec_free (match);
12376       vec_free (l2);
12377       vec_free (l4);
12378       return 0;
12379     }
12380
12381   if (match || l2 || l3 || l4)
12382     {
12383       if (l2 || l3 || l4)
12384         {
12385           /* "Win a free Ethernet header in every packet" */
12386           if (l2 == 0)
12387             vec_validate_aligned (l2, 13, sizeof (u32x4));
12388           match = l2;
12389           if (vec_len (l3))
12390             {
12391               vec_append_aligned (match, l3, sizeof (u32x4));
12392               vec_free (l3);
12393             }
12394           if (vec_len (l4))
12395             {
12396               vec_append_aligned (match, l4, sizeof (u32x4));
12397               vec_free (l4);
12398             }
12399         }
12400
12401       /* Make sure the vector is big enough even if key is all 0's */
12402       vec_validate_aligned
12403         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12404          sizeof (u32x4));
12405
12406       /* Set size, include skipped vectors */
12407       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12408
12409       *matchp = match;
12410
12411       return 1;
12412     }
12413
12414   return 0;
12415 }
12416
12417 static int
12418 api_classify_add_del_session (vat_main_t * vam)
12419 {
12420   unformat_input_t *i = vam->input;
12421   vl_api_classify_add_del_session_t *mp;
12422   int is_add = 1;
12423   u32 table_index = ~0;
12424   u32 hit_next_index = ~0;
12425   u32 opaque_index = ~0;
12426   u8 *match = 0;
12427   i32 advance = 0;
12428   u32 skip_n_vectors = 0;
12429   u32 match_n_vectors = 0;
12430   u32 action = 0;
12431   u32 metadata = 0;
12432   int ret;
12433
12434   /*
12435    * Warning: you have to supply skip_n and match_n
12436    * because the API client cant simply look at the classify
12437    * table object.
12438    */
12439
12440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12441     {
12442       if (unformat (i, "del"))
12443         is_add = 0;
12444       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12445                          &hit_next_index))
12446         ;
12447       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12448                          &hit_next_index))
12449         ;
12450       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12451                          &hit_next_index))
12452         ;
12453       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12454         ;
12455       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12456         ;
12457       else if (unformat (i, "opaque-index %d", &opaque_index))
12458         ;
12459       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12460         ;
12461       else if (unformat (i, "match_n %d", &match_n_vectors))
12462         ;
12463       else if (unformat (i, "match %U", api_unformat_classify_match,
12464                          &match, skip_n_vectors, match_n_vectors))
12465         ;
12466       else if (unformat (i, "advance %d", &advance))
12467         ;
12468       else if (unformat (i, "table-index %d", &table_index))
12469         ;
12470       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12471         action = 1;
12472       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12473         action = 2;
12474       else if (unformat (i, "action %d", &action))
12475         ;
12476       else if (unformat (i, "metadata %d", &metadata))
12477         ;
12478       else
12479         break;
12480     }
12481
12482   if (table_index == ~0)
12483     {
12484       errmsg ("Table index required");
12485       return -99;
12486     }
12487
12488   if (is_add && match == 0)
12489     {
12490       errmsg ("Match value required");
12491       return -99;
12492     }
12493
12494   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12495
12496   mp->is_add = is_add;
12497   mp->table_index = ntohl (table_index);
12498   mp->hit_next_index = ntohl (hit_next_index);
12499   mp->opaque_index = ntohl (opaque_index);
12500   mp->advance = ntohl (advance);
12501   mp->action = action;
12502   mp->metadata = ntohl (metadata);
12503   mp->match_len = ntohl (vec_len (match));
12504   clib_memcpy (mp->match, match, vec_len (match));
12505   vec_free (match);
12506
12507   S (mp);
12508   W (ret);
12509   return ret;
12510 }
12511
12512 static int
12513 api_classify_set_interface_ip_table (vat_main_t * vam)
12514 {
12515   unformat_input_t *i = vam->input;
12516   vl_api_classify_set_interface_ip_table_t *mp;
12517   u32 sw_if_index;
12518   int sw_if_index_set;
12519   u32 table_index = ~0;
12520   u8 is_ipv6 = 0;
12521   int ret;
12522
12523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12524     {
12525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12526         sw_if_index_set = 1;
12527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12528         sw_if_index_set = 1;
12529       else if (unformat (i, "table %d", &table_index))
12530         ;
12531       else
12532         {
12533           clib_warning ("parse error '%U'", format_unformat_error, i);
12534           return -99;
12535         }
12536     }
12537
12538   if (sw_if_index_set == 0)
12539     {
12540       errmsg ("missing interface name or sw_if_index");
12541       return -99;
12542     }
12543
12544
12545   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12546
12547   mp->sw_if_index = ntohl (sw_if_index);
12548   mp->table_index = ntohl (table_index);
12549   mp->is_ipv6 = is_ipv6;
12550
12551   S (mp);
12552   W (ret);
12553   return ret;
12554 }
12555
12556 static int
12557 api_classify_set_interface_l2_tables (vat_main_t * vam)
12558 {
12559   unformat_input_t *i = vam->input;
12560   vl_api_classify_set_interface_l2_tables_t *mp;
12561   u32 sw_if_index;
12562   int sw_if_index_set;
12563   u32 ip4_table_index = ~0;
12564   u32 ip6_table_index = ~0;
12565   u32 other_table_index = ~0;
12566   u32 is_input = 1;
12567   int ret;
12568
12569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12570     {
12571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12572         sw_if_index_set = 1;
12573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12574         sw_if_index_set = 1;
12575       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12576         ;
12577       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12578         ;
12579       else if (unformat (i, "other-table %d", &other_table_index))
12580         ;
12581       else if (unformat (i, "is-input %d", &is_input))
12582         ;
12583       else
12584         {
12585           clib_warning ("parse error '%U'", format_unformat_error, i);
12586           return -99;
12587         }
12588     }
12589
12590   if (sw_if_index_set == 0)
12591     {
12592       errmsg ("missing interface name or sw_if_index");
12593       return -99;
12594     }
12595
12596
12597   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12598
12599   mp->sw_if_index = ntohl (sw_if_index);
12600   mp->ip4_table_index = ntohl (ip4_table_index);
12601   mp->ip6_table_index = ntohl (ip6_table_index);
12602   mp->other_table_index = ntohl (other_table_index);
12603   mp->is_input = (u8) is_input;
12604
12605   S (mp);
12606   W (ret);
12607   return ret;
12608 }
12609
12610 static int
12611 api_set_ipfix_exporter (vat_main_t * vam)
12612 {
12613   unformat_input_t *i = vam->input;
12614   vl_api_set_ipfix_exporter_t *mp;
12615   ip4_address_t collector_address;
12616   u8 collector_address_set = 0;
12617   u32 collector_port = ~0;
12618   ip4_address_t src_address;
12619   u8 src_address_set = 0;
12620   u32 vrf_id = ~0;
12621   u32 path_mtu = ~0;
12622   u32 template_interval = ~0;
12623   u8 udp_checksum = 0;
12624   int ret;
12625
12626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12627     {
12628       if (unformat (i, "collector_address %U", unformat_ip4_address,
12629                     &collector_address))
12630         collector_address_set = 1;
12631       else if (unformat (i, "collector_port %d", &collector_port))
12632         ;
12633       else if (unformat (i, "src_address %U", unformat_ip4_address,
12634                          &src_address))
12635         src_address_set = 1;
12636       else if (unformat (i, "vrf_id %d", &vrf_id))
12637         ;
12638       else if (unformat (i, "path_mtu %d", &path_mtu))
12639         ;
12640       else if (unformat (i, "template_interval %d", &template_interval))
12641         ;
12642       else if (unformat (i, "udp_checksum"))
12643         udp_checksum = 1;
12644       else
12645         break;
12646     }
12647
12648   if (collector_address_set == 0)
12649     {
12650       errmsg ("collector_address required");
12651       return -99;
12652     }
12653
12654   if (src_address_set == 0)
12655     {
12656       errmsg ("src_address required");
12657       return -99;
12658     }
12659
12660   M (SET_IPFIX_EXPORTER, mp);
12661
12662   memcpy (mp->collector_address, collector_address.data,
12663           sizeof (collector_address.data));
12664   mp->collector_port = htons ((u16) collector_port);
12665   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12666   mp->vrf_id = htonl (vrf_id);
12667   mp->path_mtu = htonl (path_mtu);
12668   mp->template_interval = htonl (template_interval);
12669   mp->udp_checksum = udp_checksum;
12670
12671   S (mp);
12672   W (ret);
12673   return ret;
12674 }
12675
12676 static int
12677 api_set_ipfix_classify_stream (vat_main_t * vam)
12678 {
12679   unformat_input_t *i = vam->input;
12680   vl_api_set_ipfix_classify_stream_t *mp;
12681   u32 domain_id = 0;
12682   u32 src_port = UDP_DST_PORT_ipfix;
12683   int ret;
12684
12685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12686     {
12687       if (unformat (i, "domain %d", &domain_id))
12688         ;
12689       else if (unformat (i, "src_port %d", &src_port))
12690         ;
12691       else
12692         {
12693           errmsg ("unknown input `%U'", format_unformat_error, i);
12694           return -99;
12695         }
12696     }
12697
12698   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12699
12700   mp->domain_id = htonl (domain_id);
12701   mp->src_port = htons ((u16) src_port);
12702
12703   S (mp);
12704   W (ret);
12705   return ret;
12706 }
12707
12708 static int
12709 api_ipfix_classify_table_add_del (vat_main_t * vam)
12710 {
12711   unformat_input_t *i = vam->input;
12712   vl_api_ipfix_classify_table_add_del_t *mp;
12713   int is_add = -1;
12714   u32 classify_table_index = ~0;
12715   u8 ip_version = 0;
12716   u8 transport_protocol = 255;
12717   int ret;
12718
12719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12720     {
12721       if (unformat (i, "add"))
12722         is_add = 1;
12723       else if (unformat (i, "del"))
12724         is_add = 0;
12725       else if (unformat (i, "table %d", &classify_table_index))
12726         ;
12727       else if (unformat (i, "ip4"))
12728         ip_version = 4;
12729       else if (unformat (i, "ip6"))
12730         ip_version = 6;
12731       else if (unformat (i, "tcp"))
12732         transport_protocol = 6;
12733       else if (unformat (i, "udp"))
12734         transport_protocol = 17;
12735       else
12736         {
12737           errmsg ("unknown input `%U'", format_unformat_error, i);
12738           return -99;
12739         }
12740     }
12741
12742   if (is_add == -1)
12743     {
12744       errmsg ("expecting: add|del");
12745       return -99;
12746     }
12747   if (classify_table_index == ~0)
12748     {
12749       errmsg ("classifier table not specified");
12750       return -99;
12751     }
12752   if (ip_version == 0)
12753     {
12754       errmsg ("IP version not specified");
12755       return -99;
12756     }
12757
12758   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12759
12760   mp->is_add = is_add;
12761   mp->table_id = htonl (classify_table_index);
12762   mp->ip_version = ip_version;
12763   mp->transport_protocol = transport_protocol;
12764
12765   S (mp);
12766   W (ret);
12767   return ret;
12768 }
12769
12770 static int
12771 api_get_node_index (vat_main_t * vam)
12772 {
12773   unformat_input_t *i = vam->input;
12774   vl_api_get_node_index_t *mp;
12775   u8 *name = 0;
12776   int ret;
12777
12778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12779     {
12780       if (unformat (i, "node %s", &name))
12781         ;
12782       else
12783         break;
12784     }
12785   if (name == 0)
12786     {
12787       errmsg ("node name required");
12788       return -99;
12789     }
12790   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12791     {
12792       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12793       return -99;
12794     }
12795
12796   M (GET_NODE_INDEX, mp);
12797   clib_memcpy (mp->node_name, name, vec_len (name));
12798   vec_free (name);
12799
12800   S (mp);
12801   W (ret);
12802   return ret;
12803 }
12804
12805 static int
12806 api_get_next_index (vat_main_t * vam)
12807 {
12808   unformat_input_t *i = vam->input;
12809   vl_api_get_next_index_t *mp;
12810   u8 *node_name = 0, *next_node_name = 0;
12811   int ret;
12812
12813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12814     {
12815       if (unformat (i, "node-name %s", &node_name))
12816         ;
12817       else if (unformat (i, "next-node-name %s", &next_node_name))
12818         break;
12819     }
12820
12821   if (node_name == 0)
12822     {
12823       errmsg ("node name required");
12824       return -99;
12825     }
12826   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12827     {
12828       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12829       return -99;
12830     }
12831
12832   if (next_node_name == 0)
12833     {
12834       errmsg ("next node name required");
12835       return -99;
12836     }
12837   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12838     {
12839       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12840       return -99;
12841     }
12842
12843   M (GET_NEXT_INDEX, mp);
12844   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12845   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12846   vec_free (node_name);
12847   vec_free (next_node_name);
12848
12849   S (mp);
12850   W (ret);
12851   return ret;
12852 }
12853
12854 static int
12855 api_add_node_next (vat_main_t * vam)
12856 {
12857   unformat_input_t *i = vam->input;
12858   vl_api_add_node_next_t *mp;
12859   u8 *name = 0;
12860   u8 *next = 0;
12861   int ret;
12862
12863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12864     {
12865       if (unformat (i, "node %s", &name))
12866         ;
12867       else if (unformat (i, "next %s", &next))
12868         ;
12869       else
12870         break;
12871     }
12872   if (name == 0)
12873     {
12874       errmsg ("node name required");
12875       return -99;
12876     }
12877   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12878     {
12879       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12880       return -99;
12881     }
12882   if (next == 0)
12883     {
12884       errmsg ("next node required");
12885       return -99;
12886     }
12887   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12888     {
12889       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12890       return -99;
12891     }
12892
12893   M (ADD_NODE_NEXT, mp);
12894   clib_memcpy (mp->node_name, name, vec_len (name));
12895   clib_memcpy (mp->next_name, next, vec_len (next));
12896   vec_free (name);
12897   vec_free (next);
12898
12899   S (mp);
12900   W (ret);
12901   return ret;
12902 }
12903
12904 static int
12905 api_l2tpv3_create_tunnel (vat_main_t * vam)
12906 {
12907   unformat_input_t *i = vam->input;
12908   ip6_address_t client_address, our_address;
12909   int client_address_set = 0;
12910   int our_address_set = 0;
12911   u32 local_session_id = 0;
12912   u32 remote_session_id = 0;
12913   u64 local_cookie = 0;
12914   u64 remote_cookie = 0;
12915   u8 l2_sublayer_present = 0;
12916   vl_api_l2tpv3_create_tunnel_t *mp;
12917   int ret;
12918
12919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12920     {
12921       if (unformat (i, "client_address %U", unformat_ip6_address,
12922                     &client_address))
12923         client_address_set = 1;
12924       else if (unformat (i, "our_address %U", unformat_ip6_address,
12925                          &our_address))
12926         our_address_set = 1;
12927       else if (unformat (i, "local_session_id %d", &local_session_id))
12928         ;
12929       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12930         ;
12931       else if (unformat (i, "local_cookie %lld", &local_cookie))
12932         ;
12933       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12934         ;
12935       else if (unformat (i, "l2-sublayer-present"))
12936         l2_sublayer_present = 1;
12937       else
12938         break;
12939     }
12940
12941   if (client_address_set == 0)
12942     {
12943       errmsg ("client_address required");
12944       return -99;
12945     }
12946
12947   if (our_address_set == 0)
12948     {
12949       errmsg ("our_address required");
12950       return -99;
12951     }
12952
12953   M (L2TPV3_CREATE_TUNNEL, mp);
12954
12955   clib_memcpy (mp->client_address, client_address.as_u8,
12956                sizeof (mp->client_address));
12957
12958   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12959
12960   mp->local_session_id = ntohl (local_session_id);
12961   mp->remote_session_id = ntohl (remote_session_id);
12962   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12963   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12964   mp->l2_sublayer_present = l2_sublayer_present;
12965   mp->is_ipv6 = 1;
12966
12967   S (mp);
12968   W (ret);
12969   return ret;
12970 }
12971
12972 static int
12973 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12974 {
12975   unformat_input_t *i = vam->input;
12976   u32 sw_if_index;
12977   u8 sw_if_index_set = 0;
12978   u64 new_local_cookie = 0;
12979   u64 new_remote_cookie = 0;
12980   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12981   int ret;
12982
12983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12984     {
12985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12986         sw_if_index_set = 1;
12987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12988         sw_if_index_set = 1;
12989       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12990         ;
12991       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12992         ;
12993       else
12994         break;
12995     }
12996
12997   if (sw_if_index_set == 0)
12998     {
12999       errmsg ("missing interface name or sw_if_index");
13000       return -99;
13001     }
13002
13003   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
13004
13005   mp->sw_if_index = ntohl (sw_if_index);
13006   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
13007   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
13008
13009   S (mp);
13010   W (ret);
13011   return ret;
13012 }
13013
13014 static int
13015 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
13016 {
13017   unformat_input_t *i = vam->input;
13018   vl_api_l2tpv3_interface_enable_disable_t *mp;
13019   u32 sw_if_index;
13020   u8 sw_if_index_set = 0;
13021   u8 enable_disable = 1;
13022   int ret;
13023
13024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13025     {
13026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13027         sw_if_index_set = 1;
13028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13029         sw_if_index_set = 1;
13030       else if (unformat (i, "enable"))
13031         enable_disable = 1;
13032       else if (unformat (i, "disable"))
13033         enable_disable = 0;
13034       else
13035         break;
13036     }
13037
13038   if (sw_if_index_set == 0)
13039     {
13040       errmsg ("missing interface name or sw_if_index");
13041       return -99;
13042     }
13043
13044   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13045
13046   mp->sw_if_index = ntohl (sw_if_index);
13047   mp->enable_disable = enable_disable;
13048
13049   S (mp);
13050   W (ret);
13051   return ret;
13052 }
13053
13054 static int
13055 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13056 {
13057   unformat_input_t *i = vam->input;
13058   vl_api_l2tpv3_set_lookup_key_t *mp;
13059   u8 key = ~0;
13060   int ret;
13061
13062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (i, "lookup_v6_src"))
13065         key = L2T_LOOKUP_SRC_ADDRESS;
13066       else if (unformat (i, "lookup_v6_dst"))
13067         key = L2T_LOOKUP_DST_ADDRESS;
13068       else if (unformat (i, "lookup_session_id"))
13069         key = L2T_LOOKUP_SESSION_ID;
13070       else
13071         break;
13072     }
13073
13074   if (key == (u8) ~ 0)
13075     {
13076       errmsg ("l2tp session lookup key unset");
13077       return -99;
13078     }
13079
13080   M (L2TPV3_SET_LOOKUP_KEY, mp);
13081
13082   mp->key = key;
13083
13084   S (mp);
13085   W (ret);
13086   return ret;
13087 }
13088
13089 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13090   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13091 {
13092   vat_main_t *vam = &vat_main;
13093
13094   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13095          format_ip6_address, mp->our_address,
13096          format_ip6_address, mp->client_address,
13097          clib_net_to_host_u32 (mp->sw_if_index));
13098
13099   print (vam->ofp,
13100          "   local cookies %016llx %016llx remote cookie %016llx",
13101          clib_net_to_host_u64 (mp->local_cookie[0]),
13102          clib_net_to_host_u64 (mp->local_cookie[1]),
13103          clib_net_to_host_u64 (mp->remote_cookie));
13104
13105   print (vam->ofp, "   local session-id %d remote session-id %d",
13106          clib_net_to_host_u32 (mp->local_session_id),
13107          clib_net_to_host_u32 (mp->remote_session_id));
13108
13109   print (vam->ofp, "   l2 specific sublayer %s\n",
13110          mp->l2_sublayer_present ? "preset" : "absent");
13111
13112 }
13113
13114 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13115   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13116 {
13117   vat_main_t *vam = &vat_main;
13118   vat_json_node_t *node = NULL;
13119   struct in6_addr addr;
13120
13121   if (VAT_JSON_ARRAY != vam->json_tree.type)
13122     {
13123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13124       vat_json_init_array (&vam->json_tree);
13125     }
13126   node = vat_json_array_add (&vam->json_tree);
13127
13128   vat_json_init_object (node);
13129
13130   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13131   vat_json_object_add_ip6 (node, "our_address", addr);
13132   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13133   vat_json_object_add_ip6 (node, "client_address", addr);
13134
13135   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13136   vat_json_init_array (lc);
13137   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13138   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13139   vat_json_object_add_uint (node, "remote_cookie",
13140                             clib_net_to_host_u64 (mp->remote_cookie));
13141
13142   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13143   vat_json_object_add_uint (node, "local_session_id",
13144                             clib_net_to_host_u32 (mp->local_session_id));
13145   vat_json_object_add_uint (node, "remote_session_id",
13146                             clib_net_to_host_u32 (mp->remote_session_id));
13147   vat_json_object_add_string_copy (node, "l2_sublayer",
13148                                    mp->l2_sublayer_present ? (u8 *) "present"
13149                                    : (u8 *) "absent");
13150 }
13151
13152 static int
13153 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13154 {
13155   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13156   vl_api_control_ping_t *mp_ping;
13157   int ret;
13158
13159   /* Get list of l2tpv3-tunnel interfaces */
13160   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13161   S (mp);
13162
13163   /* Use a control ping for synchronization */
13164   MPING (CONTROL_PING, mp_ping);
13165   S (mp_ping);
13166
13167   W (ret);
13168   return ret;
13169 }
13170
13171
13172 static void vl_api_sw_interface_tap_details_t_handler
13173   (vl_api_sw_interface_tap_details_t * mp)
13174 {
13175   vat_main_t *vam = &vat_main;
13176
13177   print (vam->ofp, "%-16s %d",
13178          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13179 }
13180
13181 static void vl_api_sw_interface_tap_details_t_handler_json
13182   (vl_api_sw_interface_tap_details_t * mp)
13183 {
13184   vat_main_t *vam = &vat_main;
13185   vat_json_node_t *node = NULL;
13186
13187   if (VAT_JSON_ARRAY != vam->json_tree.type)
13188     {
13189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13190       vat_json_init_array (&vam->json_tree);
13191     }
13192   node = vat_json_array_add (&vam->json_tree);
13193
13194   vat_json_init_object (node);
13195   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13196   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13197 }
13198
13199 static int
13200 api_sw_interface_tap_dump (vat_main_t * vam)
13201 {
13202   vl_api_sw_interface_tap_dump_t *mp;
13203   vl_api_control_ping_t *mp_ping;
13204   int ret;
13205
13206   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13207   /* Get list of tap interfaces */
13208   M (SW_INTERFACE_TAP_DUMP, mp);
13209   S (mp);
13210
13211   /* Use a control ping for synchronization */
13212   MPING (CONTROL_PING, mp_ping);
13213   S (mp_ping);
13214
13215   W (ret);
13216   return ret;
13217 }
13218
13219 static void vl_api_sw_interface_tap_v2_details_t_handler
13220   (vl_api_sw_interface_tap_v2_details_t * mp)
13221 {
13222   vat_main_t *vam = &vat_main;
13223
13224   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13225                     mp->host_ip4_prefix_len);
13226   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13227                     mp->host_ip6_prefix_len);
13228
13229   print (vam->ofp,
13230          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13231          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13232          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13233          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13234          mp->host_bridge, ip4, ip6);
13235
13236   vec_free (ip4);
13237   vec_free (ip6);
13238 }
13239
13240 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13241   (vl_api_sw_interface_tap_v2_details_t * mp)
13242 {
13243   vat_main_t *vam = &vat_main;
13244   vat_json_node_t *node = NULL;
13245
13246   if (VAT_JSON_ARRAY != vam->json_tree.type)
13247     {
13248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13249       vat_json_init_array (&vam->json_tree);
13250     }
13251   node = vat_json_array_add (&vam->json_tree);
13252
13253   vat_json_init_object (node);
13254   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13255   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13256   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13257   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13258   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13259   vat_json_object_add_string_copy (node, "host_mac_addr",
13260                                    format (0, "%U", format_ethernet_address,
13261                                            &mp->host_mac_addr));
13262   vat_json_object_add_string_copy (node, "host_namespace",
13263                                    mp->host_namespace);
13264   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13265   vat_json_object_add_string_copy (node, "host_ip4_addr",
13266                                    format (0, "%U/%d", format_ip4_address,
13267                                            mp->host_ip4_addr,
13268                                            mp->host_ip4_prefix_len));
13269   vat_json_object_add_string_copy (node, "host_ip6_addr",
13270                                    format (0, "%U/%d", format_ip6_address,
13271                                            mp->host_ip6_addr,
13272                                            mp->host_ip6_prefix_len));
13273
13274 }
13275
13276 static int
13277 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13278 {
13279   vl_api_sw_interface_tap_v2_dump_t *mp;
13280   vl_api_control_ping_t *mp_ping;
13281   int ret;
13282
13283   print (vam->ofp,
13284          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13285          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13286          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13287          "host_ip6_addr");
13288
13289   /* Get list of tap interfaces */
13290   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13291   S (mp);
13292
13293   /* Use a control ping for synchronization */
13294   MPING (CONTROL_PING, mp_ping);
13295   S (mp_ping);
13296
13297   W (ret);
13298   return ret;
13299 }
13300
13301 static int
13302 api_vxlan_offload_rx (vat_main_t * vam)
13303 {
13304   unformat_input_t *line_input = vam->input;
13305   vl_api_vxlan_offload_rx_t *mp;
13306   u32 hw_if_index = ~0, rx_if_index = ~0;
13307   u8 is_add = 1;
13308   int ret;
13309
13310   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (line_input, "del"))
13313         is_add = 0;
13314       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13315                          &hw_if_index))
13316         ;
13317       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13318         ;
13319       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13320                          &rx_if_index))
13321         ;
13322       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13323         ;
13324       else
13325         {
13326           errmsg ("parse error '%U'", format_unformat_error, line_input);
13327           return -99;
13328         }
13329     }
13330
13331   if (hw_if_index == ~0)
13332     {
13333       errmsg ("no hw interface");
13334       return -99;
13335     }
13336
13337   if (rx_if_index == ~0)
13338     {
13339       errmsg ("no rx tunnel");
13340       return -99;
13341     }
13342
13343   M (VXLAN_OFFLOAD_RX, mp);
13344
13345   mp->hw_if_index = ntohl (hw_if_index);
13346   mp->sw_if_index = ntohl (rx_if_index);
13347   mp->enable = is_add;
13348
13349   S (mp);
13350   W (ret);
13351   return ret;
13352 }
13353
13354 static uword unformat_vxlan_decap_next
13355   (unformat_input_t * input, va_list * args)
13356 {
13357   u32 *result = va_arg (*args, u32 *);
13358   u32 tmp;
13359
13360   if (unformat (input, "l2"))
13361     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13362   else if (unformat (input, "%d", &tmp))
13363     *result = tmp;
13364   else
13365     return 0;
13366   return 1;
13367 }
13368
13369 static int
13370 api_vxlan_add_del_tunnel (vat_main_t * vam)
13371 {
13372   unformat_input_t *line_input = vam->input;
13373   vl_api_vxlan_add_del_tunnel_t *mp;
13374   ip46_address_t src, dst;
13375   u8 is_add = 1;
13376   u8 ipv4_set = 0, ipv6_set = 0;
13377   u8 src_set = 0;
13378   u8 dst_set = 0;
13379   u8 grp_set = 0;
13380   u32 instance = ~0;
13381   u32 mcast_sw_if_index = ~0;
13382   u32 encap_vrf_id = 0;
13383   u32 decap_next_index = ~0;
13384   u32 vni = 0;
13385   int ret;
13386
13387   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13388   clib_memset (&src, 0, sizeof src);
13389   clib_memset (&dst, 0, sizeof dst);
13390
13391   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13392     {
13393       if (unformat (line_input, "del"))
13394         is_add = 0;
13395       else if (unformat (line_input, "instance %d", &instance))
13396         ;
13397       else
13398         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13399         {
13400           ipv4_set = 1;
13401           src_set = 1;
13402         }
13403       else
13404         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13405         {
13406           ipv4_set = 1;
13407           dst_set = 1;
13408         }
13409       else
13410         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13411         {
13412           ipv6_set = 1;
13413           src_set = 1;
13414         }
13415       else
13416         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13417         {
13418           ipv6_set = 1;
13419           dst_set = 1;
13420         }
13421       else if (unformat (line_input, "group %U %U",
13422                          unformat_ip4_address, &dst.ip4,
13423                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13424         {
13425           grp_set = dst_set = 1;
13426           ipv4_set = 1;
13427         }
13428       else if (unformat (line_input, "group %U",
13429                          unformat_ip4_address, &dst.ip4))
13430         {
13431           grp_set = dst_set = 1;
13432           ipv4_set = 1;
13433         }
13434       else if (unformat (line_input, "group %U %U",
13435                          unformat_ip6_address, &dst.ip6,
13436                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13437         {
13438           grp_set = dst_set = 1;
13439           ipv6_set = 1;
13440         }
13441       else if (unformat (line_input, "group %U",
13442                          unformat_ip6_address, &dst.ip6))
13443         {
13444           grp_set = dst_set = 1;
13445           ipv6_set = 1;
13446         }
13447       else
13448         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13449         ;
13450       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13451         ;
13452       else if (unformat (line_input, "decap-next %U",
13453                          unformat_vxlan_decap_next, &decap_next_index))
13454         ;
13455       else if (unformat (line_input, "vni %d", &vni))
13456         ;
13457       else
13458         {
13459           errmsg ("parse error '%U'", format_unformat_error, line_input);
13460           return -99;
13461         }
13462     }
13463
13464   if (src_set == 0)
13465     {
13466       errmsg ("tunnel src address not specified");
13467       return -99;
13468     }
13469   if (dst_set == 0)
13470     {
13471       errmsg ("tunnel dst address not specified");
13472       return -99;
13473     }
13474
13475   if (grp_set && !ip46_address_is_multicast (&dst))
13476     {
13477       errmsg ("tunnel group address not multicast");
13478       return -99;
13479     }
13480   if (grp_set && mcast_sw_if_index == ~0)
13481     {
13482       errmsg ("tunnel nonexistent multicast device");
13483       return -99;
13484     }
13485   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13486     {
13487       errmsg ("tunnel dst address must be unicast");
13488       return -99;
13489     }
13490
13491
13492   if (ipv4_set && ipv6_set)
13493     {
13494       errmsg ("both IPv4 and IPv6 addresses specified");
13495       return -99;
13496     }
13497
13498   if ((vni == 0) || (vni >> 24))
13499     {
13500       errmsg ("vni not specified or out of range");
13501       return -99;
13502     }
13503
13504   M (VXLAN_ADD_DEL_TUNNEL, mp);
13505
13506   if (ipv6_set)
13507     {
13508       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13509       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13510     }
13511   else
13512     {
13513       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13514       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13515     }
13516
13517   mp->instance = htonl (instance);
13518   mp->encap_vrf_id = ntohl (encap_vrf_id);
13519   mp->decap_next_index = ntohl (decap_next_index);
13520   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13521   mp->vni = ntohl (vni);
13522   mp->is_add = is_add;
13523   mp->is_ipv6 = ipv6_set;
13524
13525   S (mp);
13526   W (ret);
13527   return ret;
13528 }
13529
13530 static void vl_api_vxlan_tunnel_details_t_handler
13531   (vl_api_vxlan_tunnel_details_t * mp)
13532 {
13533   vat_main_t *vam = &vat_main;
13534   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13535   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13536
13537   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13538          ntohl (mp->sw_if_index),
13539          ntohl (mp->instance),
13540          format_ip46_address, &src, IP46_TYPE_ANY,
13541          format_ip46_address, &dst, IP46_TYPE_ANY,
13542          ntohl (mp->encap_vrf_id),
13543          ntohl (mp->decap_next_index), ntohl (mp->vni),
13544          ntohl (mp->mcast_sw_if_index));
13545 }
13546
13547 static void vl_api_vxlan_tunnel_details_t_handler_json
13548   (vl_api_vxlan_tunnel_details_t * mp)
13549 {
13550   vat_main_t *vam = &vat_main;
13551   vat_json_node_t *node = NULL;
13552
13553   if (VAT_JSON_ARRAY != vam->json_tree.type)
13554     {
13555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13556       vat_json_init_array (&vam->json_tree);
13557     }
13558   node = vat_json_array_add (&vam->json_tree);
13559
13560   vat_json_init_object (node);
13561   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13562
13563   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13564
13565   if (mp->is_ipv6)
13566     {
13567       struct in6_addr ip6;
13568
13569       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13570       vat_json_object_add_ip6 (node, "src_address", ip6);
13571       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13572       vat_json_object_add_ip6 (node, "dst_address", ip6);
13573     }
13574   else
13575     {
13576       struct in_addr ip4;
13577
13578       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13579       vat_json_object_add_ip4 (node, "src_address", ip4);
13580       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13581       vat_json_object_add_ip4 (node, "dst_address", ip4);
13582     }
13583   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13584   vat_json_object_add_uint (node, "decap_next_index",
13585                             ntohl (mp->decap_next_index));
13586   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13587   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13588   vat_json_object_add_uint (node, "mcast_sw_if_index",
13589                             ntohl (mp->mcast_sw_if_index));
13590 }
13591
13592 static int
13593 api_vxlan_tunnel_dump (vat_main_t * vam)
13594 {
13595   unformat_input_t *i = vam->input;
13596   vl_api_vxlan_tunnel_dump_t *mp;
13597   vl_api_control_ping_t *mp_ping;
13598   u32 sw_if_index;
13599   u8 sw_if_index_set = 0;
13600   int ret;
13601
13602   /* Parse args required to build the message */
13603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13604     {
13605       if (unformat (i, "sw_if_index %d", &sw_if_index))
13606         sw_if_index_set = 1;
13607       else
13608         break;
13609     }
13610
13611   if (sw_if_index_set == 0)
13612     {
13613       sw_if_index = ~0;
13614     }
13615
13616   if (!vam->json_output)
13617     {
13618       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13619              "sw_if_index", "instance", "src_address", "dst_address",
13620              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13621     }
13622
13623   /* Get list of vxlan-tunnel interfaces */
13624   M (VXLAN_TUNNEL_DUMP, mp);
13625
13626   mp->sw_if_index = htonl (sw_if_index);
13627
13628   S (mp);
13629
13630   /* Use a control ping for synchronization */
13631   MPING (CONTROL_PING, mp_ping);
13632   S (mp_ping);
13633
13634   W (ret);
13635   return ret;
13636 }
13637
13638 static uword unformat_geneve_decap_next
13639   (unformat_input_t * input, va_list * args)
13640 {
13641   u32 *result = va_arg (*args, u32 *);
13642   u32 tmp;
13643
13644   if (unformat (input, "l2"))
13645     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13646   else if (unformat (input, "%d", &tmp))
13647     *result = tmp;
13648   else
13649     return 0;
13650   return 1;
13651 }
13652
13653 static int
13654 api_geneve_add_del_tunnel (vat_main_t * vam)
13655 {
13656   unformat_input_t *line_input = vam->input;
13657   vl_api_geneve_add_del_tunnel_t *mp;
13658   ip46_address_t src, dst;
13659   u8 is_add = 1;
13660   u8 ipv4_set = 0, ipv6_set = 0;
13661   u8 src_set = 0;
13662   u8 dst_set = 0;
13663   u8 grp_set = 0;
13664   u32 mcast_sw_if_index = ~0;
13665   u32 encap_vrf_id = 0;
13666   u32 decap_next_index = ~0;
13667   u32 vni = 0;
13668   int ret;
13669
13670   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13671   clib_memset (&src, 0, sizeof src);
13672   clib_memset (&dst, 0, sizeof dst);
13673
13674   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13675     {
13676       if (unformat (line_input, "del"))
13677         is_add = 0;
13678       else
13679         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13680         {
13681           ipv4_set = 1;
13682           src_set = 1;
13683         }
13684       else
13685         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13686         {
13687           ipv4_set = 1;
13688           dst_set = 1;
13689         }
13690       else
13691         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13692         {
13693           ipv6_set = 1;
13694           src_set = 1;
13695         }
13696       else
13697         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13698         {
13699           ipv6_set = 1;
13700           dst_set = 1;
13701         }
13702       else if (unformat (line_input, "group %U %U",
13703                          unformat_ip4_address, &dst.ip4,
13704                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13705         {
13706           grp_set = dst_set = 1;
13707           ipv4_set = 1;
13708         }
13709       else if (unformat (line_input, "group %U",
13710                          unformat_ip4_address, &dst.ip4))
13711         {
13712           grp_set = dst_set = 1;
13713           ipv4_set = 1;
13714         }
13715       else if (unformat (line_input, "group %U %U",
13716                          unformat_ip6_address, &dst.ip6,
13717                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13718         {
13719           grp_set = dst_set = 1;
13720           ipv6_set = 1;
13721         }
13722       else if (unformat (line_input, "group %U",
13723                          unformat_ip6_address, &dst.ip6))
13724         {
13725           grp_set = dst_set = 1;
13726           ipv6_set = 1;
13727         }
13728       else
13729         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13730         ;
13731       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13732         ;
13733       else if (unformat (line_input, "decap-next %U",
13734                          unformat_geneve_decap_next, &decap_next_index))
13735         ;
13736       else if (unformat (line_input, "vni %d", &vni))
13737         ;
13738       else
13739         {
13740           errmsg ("parse error '%U'", format_unformat_error, line_input);
13741           return -99;
13742         }
13743     }
13744
13745   if (src_set == 0)
13746     {
13747       errmsg ("tunnel src address not specified");
13748       return -99;
13749     }
13750   if (dst_set == 0)
13751     {
13752       errmsg ("tunnel dst address not specified");
13753       return -99;
13754     }
13755
13756   if (grp_set && !ip46_address_is_multicast (&dst))
13757     {
13758       errmsg ("tunnel group address not multicast");
13759       return -99;
13760     }
13761   if (grp_set && mcast_sw_if_index == ~0)
13762     {
13763       errmsg ("tunnel nonexistent multicast device");
13764       return -99;
13765     }
13766   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13767     {
13768       errmsg ("tunnel dst address must be unicast");
13769       return -99;
13770     }
13771
13772
13773   if (ipv4_set && ipv6_set)
13774     {
13775       errmsg ("both IPv4 and IPv6 addresses specified");
13776       return -99;
13777     }
13778
13779   if ((vni == 0) || (vni >> 24))
13780     {
13781       errmsg ("vni not specified or out of range");
13782       return -99;
13783     }
13784
13785   M (GENEVE_ADD_DEL_TUNNEL, mp);
13786
13787   if (ipv6_set)
13788     {
13789       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13790       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13791     }
13792   else
13793     {
13794       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13795       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13796     }
13797   mp->encap_vrf_id = ntohl (encap_vrf_id);
13798   mp->decap_next_index = ntohl (decap_next_index);
13799   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13800   mp->vni = ntohl (vni);
13801   mp->is_add = is_add;
13802   mp->is_ipv6 = ipv6_set;
13803
13804   S (mp);
13805   W (ret);
13806   return ret;
13807 }
13808
13809 static void vl_api_geneve_tunnel_details_t_handler
13810   (vl_api_geneve_tunnel_details_t * mp)
13811 {
13812   vat_main_t *vam = &vat_main;
13813   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13814   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13815
13816   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13817          ntohl (mp->sw_if_index),
13818          format_ip46_address, &src, IP46_TYPE_ANY,
13819          format_ip46_address, &dst, IP46_TYPE_ANY,
13820          ntohl (mp->encap_vrf_id),
13821          ntohl (mp->decap_next_index), ntohl (mp->vni),
13822          ntohl (mp->mcast_sw_if_index));
13823 }
13824
13825 static void vl_api_geneve_tunnel_details_t_handler_json
13826   (vl_api_geneve_tunnel_details_t * mp)
13827 {
13828   vat_main_t *vam = &vat_main;
13829   vat_json_node_t *node = NULL;
13830
13831   if (VAT_JSON_ARRAY != vam->json_tree.type)
13832     {
13833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13834       vat_json_init_array (&vam->json_tree);
13835     }
13836   node = vat_json_array_add (&vam->json_tree);
13837
13838   vat_json_init_object (node);
13839   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13840   if (mp->is_ipv6)
13841     {
13842       struct in6_addr ip6;
13843
13844       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13845       vat_json_object_add_ip6 (node, "src_address", ip6);
13846       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13847       vat_json_object_add_ip6 (node, "dst_address", ip6);
13848     }
13849   else
13850     {
13851       struct in_addr ip4;
13852
13853       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13854       vat_json_object_add_ip4 (node, "src_address", ip4);
13855       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13856       vat_json_object_add_ip4 (node, "dst_address", ip4);
13857     }
13858   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13859   vat_json_object_add_uint (node, "decap_next_index",
13860                             ntohl (mp->decap_next_index));
13861   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13862   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13863   vat_json_object_add_uint (node, "mcast_sw_if_index",
13864                             ntohl (mp->mcast_sw_if_index));
13865 }
13866
13867 static int
13868 api_geneve_tunnel_dump (vat_main_t * vam)
13869 {
13870   unformat_input_t *i = vam->input;
13871   vl_api_geneve_tunnel_dump_t *mp;
13872   vl_api_control_ping_t *mp_ping;
13873   u32 sw_if_index;
13874   u8 sw_if_index_set = 0;
13875   int ret;
13876
13877   /* Parse args required to build the message */
13878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13879     {
13880       if (unformat (i, "sw_if_index %d", &sw_if_index))
13881         sw_if_index_set = 1;
13882       else
13883         break;
13884     }
13885
13886   if (sw_if_index_set == 0)
13887     {
13888       sw_if_index = ~0;
13889     }
13890
13891   if (!vam->json_output)
13892     {
13893       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13894              "sw_if_index", "local_address", "remote_address",
13895              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13896     }
13897
13898   /* Get list of geneve-tunnel interfaces */
13899   M (GENEVE_TUNNEL_DUMP, mp);
13900
13901   mp->sw_if_index = htonl (sw_if_index);
13902
13903   S (mp);
13904
13905   /* Use a control ping for synchronization */
13906   M (CONTROL_PING, mp_ping);
13907   S (mp_ping);
13908
13909   W (ret);
13910   return ret;
13911 }
13912
13913 static int
13914 api_gre_add_del_tunnel (vat_main_t * vam)
13915 {
13916   unformat_input_t *line_input = vam->input;
13917   vl_api_gre_add_del_tunnel_t *mp;
13918   ip4_address_t src4, dst4;
13919   ip6_address_t src6, dst6;
13920   u8 is_add = 1;
13921   u8 ipv4_set = 0;
13922   u8 ipv6_set = 0;
13923   u8 t_type = GRE_TUNNEL_TYPE_L3;
13924   u8 src_set = 0;
13925   u8 dst_set = 0;
13926   u32 outer_fib_id = 0;
13927   u32 session_id = 0;
13928   u32 instance = ~0;
13929   int ret;
13930
13931   clib_memset (&src4, 0, sizeof src4);
13932   clib_memset (&dst4, 0, sizeof dst4);
13933   clib_memset (&src6, 0, sizeof src6);
13934   clib_memset (&dst6, 0, sizeof dst6);
13935
13936   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13937     {
13938       if (unformat (line_input, "del"))
13939         is_add = 0;
13940       else if (unformat (line_input, "instance %d", &instance))
13941         ;
13942       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13943         {
13944           src_set = 1;
13945           ipv4_set = 1;
13946         }
13947       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13948         {
13949           dst_set = 1;
13950           ipv4_set = 1;
13951         }
13952       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13953         {
13954           src_set = 1;
13955           ipv6_set = 1;
13956         }
13957       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13958         {
13959           dst_set = 1;
13960           ipv6_set = 1;
13961         }
13962       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13963         ;
13964       else if (unformat (line_input, "teb"))
13965         t_type = GRE_TUNNEL_TYPE_TEB;
13966       else if (unformat (line_input, "erspan %d", &session_id))
13967         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13968       else
13969         {
13970           errmsg ("parse error '%U'", format_unformat_error, line_input);
13971           return -99;
13972         }
13973     }
13974
13975   if (src_set == 0)
13976     {
13977       errmsg ("tunnel src address not specified");
13978       return -99;
13979     }
13980   if (dst_set == 0)
13981     {
13982       errmsg ("tunnel dst address not specified");
13983       return -99;
13984     }
13985   if (ipv4_set && ipv6_set)
13986     {
13987       errmsg ("both IPv4 and IPv6 addresses specified");
13988       return -99;
13989     }
13990
13991
13992   M (GRE_ADD_DEL_TUNNEL, mp);
13993
13994   if (ipv4_set)
13995     {
13996       clib_memcpy (&mp->src_address, &src4, 4);
13997       clib_memcpy (&mp->dst_address, &dst4, 4);
13998     }
13999   else
14000     {
14001       clib_memcpy (&mp->src_address, &src6, 16);
14002       clib_memcpy (&mp->dst_address, &dst6, 16);
14003     }
14004   mp->instance = htonl (instance);
14005   mp->outer_fib_id = htonl (outer_fib_id);
14006   mp->is_add = is_add;
14007   mp->session_id = htons ((u16) session_id);
14008   mp->tunnel_type = t_type;
14009   mp->is_ipv6 = ipv6_set;
14010
14011   S (mp);
14012   W (ret);
14013   return ret;
14014 }
14015
14016 static void vl_api_gre_tunnel_details_t_handler
14017   (vl_api_gre_tunnel_details_t * mp)
14018 {
14019   vat_main_t *vam = &vat_main;
14020   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
14021   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
14022
14023   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
14024          ntohl (mp->sw_if_index),
14025          ntohl (mp->instance),
14026          format_ip46_address, &src, IP46_TYPE_ANY,
14027          format_ip46_address, &dst, IP46_TYPE_ANY,
14028          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14029 }
14030
14031 static void vl_api_gre_tunnel_details_t_handler_json
14032   (vl_api_gre_tunnel_details_t * mp)
14033 {
14034   vat_main_t *vam = &vat_main;
14035   vat_json_node_t *node = NULL;
14036   struct in_addr ip4;
14037   struct in6_addr ip6;
14038
14039   if (VAT_JSON_ARRAY != vam->json_tree.type)
14040     {
14041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14042       vat_json_init_array (&vam->json_tree);
14043     }
14044   node = vat_json_array_add (&vam->json_tree);
14045
14046   vat_json_init_object (node);
14047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14048   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14049   if (!mp->is_ipv6)
14050     {
14051       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14052       vat_json_object_add_ip4 (node, "src_address", ip4);
14053       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14054       vat_json_object_add_ip4 (node, "dst_address", ip4);
14055     }
14056   else
14057     {
14058       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14059       vat_json_object_add_ip6 (node, "src_address", ip6);
14060       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14061       vat_json_object_add_ip6 (node, "dst_address", ip6);
14062     }
14063   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14064   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14065   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14066   vat_json_object_add_uint (node, "session_id", mp->session_id);
14067 }
14068
14069 static int
14070 api_gre_tunnel_dump (vat_main_t * vam)
14071 {
14072   unformat_input_t *i = vam->input;
14073   vl_api_gre_tunnel_dump_t *mp;
14074   vl_api_control_ping_t *mp_ping;
14075   u32 sw_if_index;
14076   u8 sw_if_index_set = 0;
14077   int ret;
14078
14079   /* Parse args required to build the message */
14080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (i, "sw_if_index %d", &sw_if_index))
14083         sw_if_index_set = 1;
14084       else
14085         break;
14086     }
14087
14088   if (sw_if_index_set == 0)
14089     {
14090       sw_if_index = ~0;
14091     }
14092
14093   if (!vam->json_output)
14094     {
14095       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14096              "sw_if_index", "instance", "src_address", "dst_address",
14097              "tunnel_type", "outer_fib_id", "session_id");
14098     }
14099
14100   /* Get list of gre-tunnel interfaces */
14101   M (GRE_TUNNEL_DUMP, mp);
14102
14103   mp->sw_if_index = htonl (sw_if_index);
14104
14105   S (mp);
14106
14107   /* Use a control ping for synchronization */
14108   MPING (CONTROL_PING, mp_ping);
14109   S (mp_ping);
14110
14111   W (ret);
14112   return ret;
14113 }
14114
14115 static int
14116 api_l2_fib_clear_table (vat_main_t * vam)
14117 {
14118 //  unformat_input_t * i = vam->input;
14119   vl_api_l2_fib_clear_table_t *mp;
14120   int ret;
14121
14122   M (L2_FIB_CLEAR_TABLE, mp);
14123
14124   S (mp);
14125   W (ret);
14126   return ret;
14127 }
14128
14129 static int
14130 api_l2_interface_efp_filter (vat_main_t * vam)
14131 {
14132   unformat_input_t *i = vam->input;
14133   vl_api_l2_interface_efp_filter_t *mp;
14134   u32 sw_if_index;
14135   u8 enable = 1;
14136   u8 sw_if_index_set = 0;
14137   int ret;
14138
14139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140     {
14141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14142         sw_if_index_set = 1;
14143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14144         sw_if_index_set = 1;
14145       else if (unformat (i, "enable"))
14146         enable = 1;
14147       else if (unformat (i, "disable"))
14148         enable = 0;
14149       else
14150         {
14151           clib_warning ("parse error '%U'", format_unformat_error, i);
14152           return -99;
14153         }
14154     }
14155
14156   if (sw_if_index_set == 0)
14157     {
14158       errmsg ("missing sw_if_index");
14159       return -99;
14160     }
14161
14162   M (L2_INTERFACE_EFP_FILTER, mp);
14163
14164   mp->sw_if_index = ntohl (sw_if_index);
14165   mp->enable_disable = enable;
14166
14167   S (mp);
14168   W (ret);
14169   return ret;
14170 }
14171
14172 #define foreach_vtr_op                          \
14173 _("disable",  L2_VTR_DISABLED)                  \
14174 _("push-1",  L2_VTR_PUSH_1)                     \
14175 _("push-2",  L2_VTR_PUSH_2)                     \
14176 _("pop-1",  L2_VTR_POP_1)                       \
14177 _("pop-2",  L2_VTR_POP_2)                       \
14178 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14179 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14180 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14181 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14182
14183 static int
14184 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14185 {
14186   unformat_input_t *i = vam->input;
14187   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14188   u32 sw_if_index;
14189   u8 sw_if_index_set = 0;
14190   u8 vtr_op_set = 0;
14191   u32 vtr_op = 0;
14192   u32 push_dot1q = 1;
14193   u32 tag1 = ~0;
14194   u32 tag2 = ~0;
14195   int ret;
14196
14197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14198     {
14199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14200         sw_if_index_set = 1;
14201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14202         sw_if_index_set = 1;
14203       else if (unformat (i, "vtr_op %d", &vtr_op))
14204         vtr_op_set = 1;
14205 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14206       foreach_vtr_op
14207 #undef _
14208         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14209         ;
14210       else if (unformat (i, "tag1 %d", &tag1))
14211         ;
14212       else if (unformat (i, "tag2 %d", &tag2))
14213         ;
14214       else
14215         {
14216           clib_warning ("parse error '%U'", format_unformat_error, i);
14217           return -99;
14218         }
14219     }
14220
14221   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14222     {
14223       errmsg ("missing vtr operation or sw_if_index");
14224       return -99;
14225     }
14226
14227   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14228   mp->sw_if_index = ntohl (sw_if_index);
14229   mp->vtr_op = ntohl (vtr_op);
14230   mp->push_dot1q = ntohl (push_dot1q);
14231   mp->tag1 = ntohl (tag1);
14232   mp->tag2 = ntohl (tag2);
14233
14234   S (mp);
14235   W (ret);
14236   return ret;
14237 }
14238
14239 static int
14240 api_create_vhost_user_if (vat_main_t * vam)
14241 {
14242   unformat_input_t *i = vam->input;
14243   vl_api_create_vhost_user_if_t *mp;
14244   u8 *file_name;
14245   u8 is_server = 0;
14246   u8 file_name_set = 0;
14247   u32 custom_dev_instance = ~0;
14248   u8 hwaddr[6];
14249   u8 use_custom_mac = 0;
14250   u8 disable_mrg_rxbuf = 0;
14251   u8 disable_indirect_desc = 0;
14252   u8 *tag = 0;
14253   int ret;
14254
14255   /* Shut up coverity */
14256   clib_memset (hwaddr, 0, sizeof (hwaddr));
14257
14258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14259     {
14260       if (unformat (i, "socket %s", &file_name))
14261         {
14262           file_name_set = 1;
14263         }
14264       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14265         ;
14266       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14267         use_custom_mac = 1;
14268       else if (unformat (i, "server"))
14269         is_server = 1;
14270       else if (unformat (i, "disable_mrg_rxbuf"))
14271         disable_mrg_rxbuf = 1;
14272       else if (unformat (i, "disable_indirect_desc"))
14273         disable_indirect_desc = 1;
14274       else if (unformat (i, "tag %s", &tag))
14275         ;
14276       else
14277         break;
14278     }
14279
14280   if (file_name_set == 0)
14281     {
14282       errmsg ("missing socket file name");
14283       return -99;
14284     }
14285
14286   if (vec_len (file_name) > 255)
14287     {
14288       errmsg ("socket file name too long");
14289       return -99;
14290     }
14291   vec_add1 (file_name, 0);
14292
14293   M (CREATE_VHOST_USER_IF, mp);
14294
14295   mp->is_server = is_server;
14296   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14297   mp->disable_indirect_desc = disable_indirect_desc;
14298   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14299   vec_free (file_name);
14300   if (custom_dev_instance != ~0)
14301     {
14302       mp->renumber = 1;
14303       mp->custom_dev_instance = ntohl (custom_dev_instance);
14304     }
14305
14306   mp->use_custom_mac = use_custom_mac;
14307   clib_memcpy (mp->mac_address, hwaddr, 6);
14308   if (tag)
14309     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14310   vec_free (tag);
14311
14312   S (mp);
14313   W (ret);
14314   return ret;
14315 }
14316
14317 static int
14318 api_modify_vhost_user_if (vat_main_t * vam)
14319 {
14320   unformat_input_t *i = vam->input;
14321   vl_api_modify_vhost_user_if_t *mp;
14322   u8 *file_name;
14323   u8 is_server = 0;
14324   u8 file_name_set = 0;
14325   u32 custom_dev_instance = ~0;
14326   u8 sw_if_index_set = 0;
14327   u32 sw_if_index = (u32) ~ 0;
14328   int ret;
14329
14330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14331     {
14332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14333         sw_if_index_set = 1;
14334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14335         sw_if_index_set = 1;
14336       else if (unformat (i, "socket %s", &file_name))
14337         {
14338           file_name_set = 1;
14339         }
14340       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14341         ;
14342       else if (unformat (i, "server"))
14343         is_server = 1;
14344       else
14345         break;
14346     }
14347
14348   if (sw_if_index_set == 0)
14349     {
14350       errmsg ("missing sw_if_index or interface name");
14351       return -99;
14352     }
14353
14354   if (file_name_set == 0)
14355     {
14356       errmsg ("missing socket file name");
14357       return -99;
14358     }
14359
14360   if (vec_len (file_name) > 255)
14361     {
14362       errmsg ("socket file name too long");
14363       return -99;
14364     }
14365   vec_add1 (file_name, 0);
14366
14367   M (MODIFY_VHOST_USER_IF, mp);
14368
14369   mp->sw_if_index = ntohl (sw_if_index);
14370   mp->is_server = is_server;
14371   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14372   vec_free (file_name);
14373   if (custom_dev_instance != ~0)
14374     {
14375       mp->renumber = 1;
14376       mp->custom_dev_instance = ntohl (custom_dev_instance);
14377     }
14378
14379   S (mp);
14380   W (ret);
14381   return ret;
14382 }
14383
14384 static int
14385 api_delete_vhost_user_if (vat_main_t * vam)
14386 {
14387   unformat_input_t *i = vam->input;
14388   vl_api_delete_vhost_user_if_t *mp;
14389   u32 sw_if_index = ~0;
14390   u8 sw_if_index_set = 0;
14391   int ret;
14392
14393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14394     {
14395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14396         sw_if_index_set = 1;
14397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14398         sw_if_index_set = 1;
14399       else
14400         break;
14401     }
14402
14403   if (sw_if_index_set == 0)
14404     {
14405       errmsg ("missing sw_if_index or interface name");
14406       return -99;
14407     }
14408
14409
14410   M (DELETE_VHOST_USER_IF, mp);
14411
14412   mp->sw_if_index = ntohl (sw_if_index);
14413
14414   S (mp);
14415   W (ret);
14416   return ret;
14417 }
14418
14419 static void vl_api_sw_interface_vhost_user_details_t_handler
14420   (vl_api_sw_interface_vhost_user_details_t * mp)
14421 {
14422   vat_main_t *vam = &vat_main;
14423
14424   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14425          (char *) mp->interface_name,
14426          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14427          clib_net_to_host_u64 (mp->features), mp->is_server,
14428          ntohl (mp->num_regions), (char *) mp->sock_filename);
14429   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14430 }
14431
14432 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14433   (vl_api_sw_interface_vhost_user_details_t * mp)
14434 {
14435   vat_main_t *vam = &vat_main;
14436   vat_json_node_t *node = NULL;
14437
14438   if (VAT_JSON_ARRAY != vam->json_tree.type)
14439     {
14440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14441       vat_json_init_array (&vam->json_tree);
14442     }
14443   node = vat_json_array_add (&vam->json_tree);
14444
14445   vat_json_init_object (node);
14446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14447   vat_json_object_add_string_copy (node, "interface_name",
14448                                    mp->interface_name);
14449   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14450                             ntohl (mp->virtio_net_hdr_sz));
14451   vat_json_object_add_uint (node, "features",
14452                             clib_net_to_host_u64 (mp->features));
14453   vat_json_object_add_uint (node, "is_server", mp->is_server);
14454   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14455   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14456   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14457 }
14458
14459 static int
14460 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14461 {
14462   vl_api_sw_interface_vhost_user_dump_t *mp;
14463   vl_api_control_ping_t *mp_ping;
14464   int ret;
14465   print (vam->ofp,
14466          "Interface name            idx hdr_sz features server regions filename");
14467
14468   /* Get list of vhost-user interfaces */
14469   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14470   S (mp);
14471
14472   /* Use a control ping for synchronization */
14473   MPING (CONTROL_PING, mp_ping);
14474   S (mp_ping);
14475
14476   W (ret);
14477   return ret;
14478 }
14479
14480 static int
14481 api_show_version (vat_main_t * vam)
14482 {
14483   vl_api_show_version_t *mp;
14484   int ret;
14485
14486   M (SHOW_VERSION, mp);
14487
14488   S (mp);
14489   W (ret);
14490   return ret;
14491 }
14492
14493
14494 static int
14495 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14496 {
14497   unformat_input_t *line_input = vam->input;
14498   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14499   ip4_address_t local4, remote4;
14500   ip6_address_t local6, remote6;
14501   u8 is_add = 1;
14502   u8 ipv4_set = 0, ipv6_set = 0;
14503   u8 local_set = 0;
14504   u8 remote_set = 0;
14505   u8 grp_set = 0;
14506   u32 mcast_sw_if_index = ~0;
14507   u32 encap_vrf_id = 0;
14508   u32 decap_vrf_id = 0;
14509   u8 protocol = ~0;
14510   u32 vni;
14511   u8 vni_set = 0;
14512   int ret;
14513
14514   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14515   clib_memset (&local4, 0, sizeof local4);
14516   clib_memset (&remote4, 0, sizeof remote4);
14517   clib_memset (&local6, 0, sizeof local6);
14518   clib_memset (&remote6, 0, sizeof remote6);
14519
14520   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (line_input, "del"))
14523         is_add = 0;
14524       else if (unformat (line_input, "local %U",
14525                          unformat_ip4_address, &local4))
14526         {
14527           local_set = 1;
14528           ipv4_set = 1;
14529         }
14530       else if (unformat (line_input, "remote %U",
14531                          unformat_ip4_address, &remote4))
14532         {
14533           remote_set = 1;
14534           ipv4_set = 1;
14535         }
14536       else if (unformat (line_input, "local %U",
14537                          unformat_ip6_address, &local6))
14538         {
14539           local_set = 1;
14540           ipv6_set = 1;
14541         }
14542       else if (unformat (line_input, "remote %U",
14543                          unformat_ip6_address, &remote6))
14544         {
14545           remote_set = 1;
14546           ipv6_set = 1;
14547         }
14548       else if (unformat (line_input, "group %U %U",
14549                          unformat_ip4_address, &remote4,
14550                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14551         {
14552           grp_set = remote_set = 1;
14553           ipv4_set = 1;
14554         }
14555       else if (unformat (line_input, "group %U",
14556                          unformat_ip4_address, &remote4))
14557         {
14558           grp_set = remote_set = 1;
14559           ipv4_set = 1;
14560         }
14561       else if (unformat (line_input, "group %U %U",
14562                          unformat_ip6_address, &remote6,
14563                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14564         {
14565           grp_set = remote_set = 1;
14566           ipv6_set = 1;
14567         }
14568       else if (unformat (line_input, "group %U",
14569                          unformat_ip6_address, &remote6))
14570         {
14571           grp_set = remote_set = 1;
14572           ipv6_set = 1;
14573         }
14574       else
14575         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14576         ;
14577       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14578         ;
14579       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14580         ;
14581       else if (unformat (line_input, "vni %d", &vni))
14582         vni_set = 1;
14583       else if (unformat (line_input, "next-ip4"))
14584         protocol = 1;
14585       else if (unformat (line_input, "next-ip6"))
14586         protocol = 2;
14587       else if (unformat (line_input, "next-ethernet"))
14588         protocol = 3;
14589       else if (unformat (line_input, "next-nsh"))
14590         protocol = 4;
14591       else
14592         {
14593           errmsg ("parse error '%U'", format_unformat_error, line_input);
14594           return -99;
14595         }
14596     }
14597
14598   if (local_set == 0)
14599     {
14600       errmsg ("tunnel local address not specified");
14601       return -99;
14602     }
14603   if (remote_set == 0)
14604     {
14605       errmsg ("tunnel remote address not specified");
14606       return -99;
14607     }
14608   if (grp_set && mcast_sw_if_index == ~0)
14609     {
14610       errmsg ("tunnel nonexistent multicast device");
14611       return -99;
14612     }
14613   if (ipv4_set && ipv6_set)
14614     {
14615       errmsg ("both IPv4 and IPv6 addresses specified");
14616       return -99;
14617     }
14618
14619   if (vni_set == 0)
14620     {
14621       errmsg ("vni not specified");
14622       return -99;
14623     }
14624
14625   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14626
14627
14628   if (ipv6_set)
14629     {
14630       clib_memcpy (&mp->local, &local6, sizeof (local6));
14631       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14632     }
14633   else
14634     {
14635       clib_memcpy (&mp->local, &local4, sizeof (local4));
14636       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14637     }
14638
14639   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14640   mp->encap_vrf_id = ntohl (encap_vrf_id);
14641   mp->decap_vrf_id = ntohl (decap_vrf_id);
14642   mp->protocol = protocol;
14643   mp->vni = ntohl (vni);
14644   mp->is_add = is_add;
14645   mp->is_ipv6 = ipv6_set;
14646
14647   S (mp);
14648   W (ret);
14649   return ret;
14650 }
14651
14652 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14653   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14654 {
14655   vat_main_t *vam = &vat_main;
14656   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14657   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14658
14659   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14660          ntohl (mp->sw_if_index),
14661          format_ip46_address, &local, IP46_TYPE_ANY,
14662          format_ip46_address, &remote, IP46_TYPE_ANY,
14663          ntohl (mp->vni), mp->protocol,
14664          ntohl (mp->mcast_sw_if_index),
14665          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14666 }
14667
14668
14669 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14670   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14671 {
14672   vat_main_t *vam = &vat_main;
14673   vat_json_node_t *node = NULL;
14674   struct in_addr ip4;
14675   struct in6_addr ip6;
14676
14677   if (VAT_JSON_ARRAY != vam->json_tree.type)
14678     {
14679       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14680       vat_json_init_array (&vam->json_tree);
14681     }
14682   node = vat_json_array_add (&vam->json_tree);
14683
14684   vat_json_init_object (node);
14685   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14686   if (mp->is_ipv6)
14687     {
14688       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14689       vat_json_object_add_ip6 (node, "local", ip6);
14690       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14691       vat_json_object_add_ip6 (node, "remote", ip6);
14692     }
14693   else
14694     {
14695       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14696       vat_json_object_add_ip4 (node, "local", ip4);
14697       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14698       vat_json_object_add_ip4 (node, "remote", ip4);
14699     }
14700   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14701   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14702   vat_json_object_add_uint (node, "mcast_sw_if_index",
14703                             ntohl (mp->mcast_sw_if_index));
14704   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14705   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14706   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14707 }
14708
14709 static int
14710 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14711 {
14712   unformat_input_t *i = vam->input;
14713   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14714   vl_api_control_ping_t *mp_ping;
14715   u32 sw_if_index;
14716   u8 sw_if_index_set = 0;
14717   int ret;
14718
14719   /* Parse args required to build the message */
14720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14721     {
14722       if (unformat (i, "sw_if_index %d", &sw_if_index))
14723         sw_if_index_set = 1;
14724       else
14725         break;
14726     }
14727
14728   if (sw_if_index_set == 0)
14729     {
14730       sw_if_index = ~0;
14731     }
14732
14733   if (!vam->json_output)
14734     {
14735       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14736              "sw_if_index", "local", "remote", "vni",
14737              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14738     }
14739
14740   /* Get list of vxlan-tunnel interfaces */
14741   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14742
14743   mp->sw_if_index = htonl (sw_if_index);
14744
14745   S (mp);
14746
14747   /* Use a control ping for synchronization */
14748   MPING (CONTROL_PING, mp_ping);
14749   S (mp_ping);
14750
14751   W (ret);
14752   return ret;
14753 }
14754
14755 static void vl_api_l2_fib_table_details_t_handler
14756   (vl_api_l2_fib_table_details_t * mp)
14757 {
14758   vat_main_t *vam = &vat_main;
14759
14760   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14761          "       %d       %d     %d",
14762          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14763          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14764          mp->bvi_mac);
14765 }
14766
14767 static void vl_api_l2_fib_table_details_t_handler_json
14768   (vl_api_l2_fib_table_details_t * mp)
14769 {
14770   vat_main_t *vam = &vat_main;
14771   vat_json_node_t *node = NULL;
14772
14773   if (VAT_JSON_ARRAY != vam->json_tree.type)
14774     {
14775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14776       vat_json_init_array (&vam->json_tree);
14777     }
14778   node = vat_json_array_add (&vam->json_tree);
14779
14780   vat_json_init_object (node);
14781   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14782   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14783   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14784   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14785   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14786   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14787 }
14788
14789 static int
14790 api_l2_fib_table_dump (vat_main_t * vam)
14791 {
14792   unformat_input_t *i = vam->input;
14793   vl_api_l2_fib_table_dump_t *mp;
14794   vl_api_control_ping_t *mp_ping;
14795   u32 bd_id;
14796   u8 bd_id_set = 0;
14797   int ret;
14798
14799   /* Parse args required to build the message */
14800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14801     {
14802       if (unformat (i, "bd_id %d", &bd_id))
14803         bd_id_set = 1;
14804       else
14805         break;
14806     }
14807
14808   if (bd_id_set == 0)
14809     {
14810       errmsg ("missing bridge domain");
14811       return -99;
14812     }
14813
14814   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14815
14816   /* Get list of l2 fib entries */
14817   M (L2_FIB_TABLE_DUMP, mp);
14818
14819   mp->bd_id = ntohl (bd_id);
14820   S (mp);
14821
14822   /* Use a control ping for synchronization */
14823   MPING (CONTROL_PING, mp_ping);
14824   S (mp_ping);
14825
14826   W (ret);
14827   return ret;
14828 }
14829
14830
14831 static int
14832 api_interface_name_renumber (vat_main_t * vam)
14833 {
14834   unformat_input_t *line_input = vam->input;
14835   vl_api_interface_name_renumber_t *mp;
14836   u32 sw_if_index = ~0;
14837   u32 new_show_dev_instance = ~0;
14838   int ret;
14839
14840   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14841     {
14842       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14843                     &sw_if_index))
14844         ;
14845       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14846         ;
14847       else if (unformat (line_input, "new_show_dev_instance %d",
14848                          &new_show_dev_instance))
14849         ;
14850       else
14851         break;
14852     }
14853
14854   if (sw_if_index == ~0)
14855     {
14856       errmsg ("missing interface name or sw_if_index");
14857       return -99;
14858     }
14859
14860   if (new_show_dev_instance == ~0)
14861     {
14862       errmsg ("missing new_show_dev_instance");
14863       return -99;
14864     }
14865
14866   M (INTERFACE_NAME_RENUMBER, mp);
14867
14868   mp->sw_if_index = ntohl (sw_if_index);
14869   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14870
14871   S (mp);
14872   W (ret);
14873   return ret;
14874 }
14875
14876 static int
14877 api_ip_probe_neighbor (vat_main_t * vam)
14878 {
14879   unformat_input_t *i = vam->input;
14880   vl_api_ip_probe_neighbor_t *mp;
14881   u8 int_set = 0;
14882   u8 adr_set = 0;
14883   u8 is_ipv6 = 0;
14884   u8 dst_adr[16];
14885   u32 sw_if_index;
14886   int ret;
14887
14888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14889     {
14890       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14891         int_set = 1;
14892       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14893         int_set = 1;
14894       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14895         adr_set = 1;
14896       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14897         {
14898           adr_set = 1;
14899           is_ipv6 = 1;
14900         }
14901       else
14902         break;
14903     }
14904
14905   if (int_set == 0)
14906     {
14907       errmsg ("missing interface");
14908       return -99;
14909     }
14910
14911   if (adr_set == 0)
14912     {
14913       errmsg ("missing addresses");
14914       return -99;
14915     }
14916
14917   M (IP_PROBE_NEIGHBOR, mp);
14918
14919   mp->sw_if_index = ntohl (sw_if_index);
14920   mp->is_ipv6 = is_ipv6;
14921   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14922
14923   S (mp);
14924   W (ret);
14925   return ret;
14926 }
14927
14928 static int
14929 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14930 {
14931   unformat_input_t *i = vam->input;
14932   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14933   u8 mode = IP_SCAN_V46_NEIGHBORS;
14934   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14935   int ret;
14936
14937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (i, "ip4"))
14940         mode = IP_SCAN_V4_NEIGHBORS;
14941       else if (unformat (i, "ip6"))
14942         mode = IP_SCAN_V6_NEIGHBORS;
14943       if (unformat (i, "both"))
14944         mode = IP_SCAN_V46_NEIGHBORS;
14945       else if (unformat (i, "disable"))
14946         mode = IP_SCAN_DISABLED;
14947       else if (unformat (i, "interval %d", &interval))
14948         ;
14949       else if (unformat (i, "max-time %d", &time))
14950         ;
14951       else if (unformat (i, "max-update %d", &update))
14952         ;
14953       else if (unformat (i, "delay %d", &delay))
14954         ;
14955       else if (unformat (i, "stale %d", &stale))
14956         ;
14957       else
14958         break;
14959     }
14960
14961   if (interval > 255)
14962     {
14963       errmsg ("interval cannot exceed 255 minutes.");
14964       return -99;
14965     }
14966   if (time > 255)
14967     {
14968       errmsg ("max-time cannot exceed 255 usec.");
14969       return -99;
14970     }
14971   if (update > 255)
14972     {
14973       errmsg ("max-update cannot exceed 255.");
14974       return -99;
14975     }
14976   if (delay > 255)
14977     {
14978       errmsg ("delay cannot exceed 255 msec.");
14979       return -99;
14980     }
14981   if (stale > 255)
14982     {
14983       errmsg ("stale cannot exceed 255 minutes.");
14984       return -99;
14985     }
14986
14987   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14988   mp->mode = mode;
14989   mp->scan_interval = interval;
14990   mp->max_proc_time = time;
14991   mp->max_update = update;
14992   mp->scan_int_delay = delay;
14993   mp->stale_threshold = stale;
14994
14995   S (mp);
14996   W (ret);
14997   return ret;
14998 }
14999
15000 static int
15001 api_want_ip4_arp_events (vat_main_t * vam)
15002 {
15003   unformat_input_t *line_input = vam->input;
15004   vl_api_want_ip4_arp_events_t *mp;
15005   ip4_address_t address;
15006   int address_set = 0;
15007   u32 enable_disable = 1;
15008   int ret;
15009
15010   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15011     {
15012       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
15013         address_set = 1;
15014       else if (unformat (line_input, "del"))
15015         enable_disable = 0;
15016       else
15017         break;
15018     }
15019
15020   if (address_set == 0)
15021     {
15022       errmsg ("missing addresses");
15023       return -99;
15024     }
15025
15026   M (WANT_IP4_ARP_EVENTS, mp);
15027   mp->enable_disable = enable_disable;
15028   mp->pid = htonl (getpid ());
15029   mp->address = address.as_u32;
15030
15031   S (mp);
15032   W (ret);
15033   return ret;
15034 }
15035
15036 static int
15037 api_want_ip6_nd_events (vat_main_t * vam)
15038 {
15039   unformat_input_t *line_input = vam->input;
15040   vl_api_want_ip6_nd_events_t *mp;
15041   ip6_address_t address;
15042   int address_set = 0;
15043   u32 enable_disable = 1;
15044   int ret;
15045
15046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15047     {
15048       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15049         address_set = 1;
15050       else if (unformat (line_input, "del"))
15051         enable_disable = 0;
15052       else
15053         break;
15054     }
15055
15056   if (address_set == 0)
15057     {
15058       errmsg ("missing addresses");
15059       return -99;
15060     }
15061
15062   M (WANT_IP6_ND_EVENTS, mp);
15063   mp->enable_disable = enable_disable;
15064   mp->pid = htonl (getpid ());
15065   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15066
15067   S (mp);
15068   W (ret);
15069   return ret;
15070 }
15071
15072 static int
15073 api_want_l2_macs_events (vat_main_t * vam)
15074 {
15075   unformat_input_t *line_input = vam->input;
15076   vl_api_want_l2_macs_events_t *mp;
15077   u8 enable_disable = 1;
15078   u32 scan_delay = 0;
15079   u32 max_macs_in_event = 0;
15080   u32 learn_limit = 0;
15081   int ret;
15082
15083   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (line_input, "learn-limit %d", &learn_limit))
15086         ;
15087       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15088         ;
15089       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15090         ;
15091       else if (unformat (line_input, "disable"))
15092         enable_disable = 0;
15093       else
15094         break;
15095     }
15096
15097   M (WANT_L2_MACS_EVENTS, mp);
15098   mp->enable_disable = enable_disable;
15099   mp->pid = htonl (getpid ());
15100   mp->learn_limit = htonl (learn_limit);
15101   mp->scan_delay = (u8) scan_delay;
15102   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15103   S (mp);
15104   W (ret);
15105   return ret;
15106 }
15107
15108 static int
15109 api_input_acl_set_interface (vat_main_t * vam)
15110 {
15111   unformat_input_t *i = vam->input;
15112   vl_api_input_acl_set_interface_t *mp;
15113   u32 sw_if_index;
15114   int sw_if_index_set;
15115   u32 ip4_table_index = ~0;
15116   u32 ip6_table_index = ~0;
15117   u32 l2_table_index = ~0;
15118   u8 is_add = 1;
15119   int ret;
15120
15121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15122     {
15123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15124         sw_if_index_set = 1;
15125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15126         sw_if_index_set = 1;
15127       else if (unformat (i, "del"))
15128         is_add = 0;
15129       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15130         ;
15131       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15132         ;
15133       else if (unformat (i, "l2-table %d", &l2_table_index))
15134         ;
15135       else
15136         {
15137           clib_warning ("parse error '%U'", format_unformat_error, i);
15138           return -99;
15139         }
15140     }
15141
15142   if (sw_if_index_set == 0)
15143     {
15144       errmsg ("missing interface name or sw_if_index");
15145       return -99;
15146     }
15147
15148   M (INPUT_ACL_SET_INTERFACE, mp);
15149
15150   mp->sw_if_index = ntohl (sw_if_index);
15151   mp->ip4_table_index = ntohl (ip4_table_index);
15152   mp->ip6_table_index = ntohl (ip6_table_index);
15153   mp->l2_table_index = ntohl (l2_table_index);
15154   mp->is_add = is_add;
15155
15156   S (mp);
15157   W (ret);
15158   return ret;
15159 }
15160
15161 static int
15162 api_output_acl_set_interface (vat_main_t * vam)
15163 {
15164   unformat_input_t *i = vam->input;
15165   vl_api_output_acl_set_interface_t *mp;
15166   u32 sw_if_index;
15167   int sw_if_index_set;
15168   u32 ip4_table_index = ~0;
15169   u32 ip6_table_index = ~0;
15170   u32 l2_table_index = ~0;
15171   u8 is_add = 1;
15172   int ret;
15173
15174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15175     {
15176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15177         sw_if_index_set = 1;
15178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15179         sw_if_index_set = 1;
15180       else if (unformat (i, "del"))
15181         is_add = 0;
15182       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15183         ;
15184       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15185         ;
15186       else if (unformat (i, "l2-table %d", &l2_table_index))
15187         ;
15188       else
15189         {
15190           clib_warning ("parse error '%U'", format_unformat_error, i);
15191           return -99;
15192         }
15193     }
15194
15195   if (sw_if_index_set == 0)
15196     {
15197       errmsg ("missing interface name or sw_if_index");
15198       return -99;
15199     }
15200
15201   M (OUTPUT_ACL_SET_INTERFACE, mp);
15202
15203   mp->sw_if_index = ntohl (sw_if_index);
15204   mp->ip4_table_index = ntohl (ip4_table_index);
15205   mp->ip6_table_index = ntohl (ip6_table_index);
15206   mp->l2_table_index = ntohl (l2_table_index);
15207   mp->is_add = is_add;
15208
15209   S (mp);
15210   W (ret);
15211   return ret;
15212 }
15213
15214 static int
15215 api_ip_address_dump (vat_main_t * vam)
15216 {
15217   unformat_input_t *i = vam->input;
15218   vl_api_ip_address_dump_t *mp;
15219   vl_api_control_ping_t *mp_ping;
15220   u32 sw_if_index = ~0;
15221   u8 sw_if_index_set = 0;
15222   u8 ipv4_set = 0;
15223   u8 ipv6_set = 0;
15224   int ret;
15225
15226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (i, "sw_if_index %d", &sw_if_index))
15229         sw_if_index_set = 1;
15230       else
15231         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15232         sw_if_index_set = 1;
15233       else if (unformat (i, "ipv4"))
15234         ipv4_set = 1;
15235       else if (unformat (i, "ipv6"))
15236         ipv6_set = 1;
15237       else
15238         break;
15239     }
15240
15241   if (ipv4_set && ipv6_set)
15242     {
15243       errmsg ("ipv4 and ipv6 flags cannot be both set");
15244       return -99;
15245     }
15246
15247   if ((!ipv4_set) && (!ipv6_set))
15248     {
15249       errmsg ("no ipv4 nor ipv6 flag set");
15250       return -99;
15251     }
15252
15253   if (sw_if_index_set == 0)
15254     {
15255       errmsg ("missing interface name or sw_if_index");
15256       return -99;
15257     }
15258
15259   vam->current_sw_if_index = sw_if_index;
15260   vam->is_ipv6 = ipv6_set;
15261
15262   M (IP_ADDRESS_DUMP, mp);
15263   mp->sw_if_index = ntohl (sw_if_index);
15264   mp->is_ipv6 = ipv6_set;
15265   S (mp);
15266
15267   /* Use a control ping for synchronization */
15268   MPING (CONTROL_PING, mp_ping);
15269   S (mp_ping);
15270
15271   W (ret);
15272   return ret;
15273 }
15274
15275 static int
15276 api_ip_dump (vat_main_t * vam)
15277 {
15278   vl_api_ip_dump_t *mp;
15279   vl_api_control_ping_t *mp_ping;
15280   unformat_input_t *in = vam->input;
15281   int ipv4_set = 0;
15282   int ipv6_set = 0;
15283   int is_ipv6;
15284   int i;
15285   int ret;
15286
15287   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15288     {
15289       if (unformat (in, "ipv4"))
15290         ipv4_set = 1;
15291       else if (unformat (in, "ipv6"))
15292         ipv6_set = 1;
15293       else
15294         break;
15295     }
15296
15297   if (ipv4_set && ipv6_set)
15298     {
15299       errmsg ("ipv4 and ipv6 flags cannot be both set");
15300       return -99;
15301     }
15302
15303   if ((!ipv4_set) && (!ipv6_set))
15304     {
15305       errmsg ("no ipv4 nor ipv6 flag set");
15306       return -99;
15307     }
15308
15309   is_ipv6 = ipv6_set;
15310   vam->is_ipv6 = is_ipv6;
15311
15312   /* free old data */
15313   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15314     {
15315       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15316     }
15317   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15318
15319   M (IP_DUMP, mp);
15320   mp->is_ipv6 = ipv6_set;
15321   S (mp);
15322
15323   /* Use a control ping for synchronization */
15324   MPING (CONTROL_PING, mp_ping);
15325   S (mp_ping);
15326
15327   W (ret);
15328   return ret;
15329 }
15330
15331 static int
15332 api_ipsec_spd_add_del (vat_main_t * vam)
15333 {
15334   unformat_input_t *i = vam->input;
15335   vl_api_ipsec_spd_add_del_t *mp;
15336   u32 spd_id = ~0;
15337   u8 is_add = 1;
15338   int ret;
15339
15340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15341     {
15342       if (unformat (i, "spd_id %d", &spd_id))
15343         ;
15344       else if (unformat (i, "del"))
15345         is_add = 0;
15346       else
15347         {
15348           clib_warning ("parse error '%U'", format_unformat_error, i);
15349           return -99;
15350         }
15351     }
15352   if (spd_id == ~0)
15353     {
15354       errmsg ("spd_id must be set");
15355       return -99;
15356     }
15357
15358   M (IPSEC_SPD_ADD_DEL, mp);
15359
15360   mp->spd_id = ntohl (spd_id);
15361   mp->is_add = is_add;
15362
15363   S (mp);
15364   W (ret);
15365   return ret;
15366 }
15367
15368 static int
15369 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15370 {
15371   unformat_input_t *i = vam->input;
15372   vl_api_ipsec_interface_add_del_spd_t *mp;
15373   u32 sw_if_index;
15374   u8 sw_if_index_set = 0;
15375   u32 spd_id = (u32) ~ 0;
15376   u8 is_add = 1;
15377   int ret;
15378
15379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15380     {
15381       if (unformat (i, "del"))
15382         is_add = 0;
15383       else if (unformat (i, "spd_id %d", &spd_id))
15384         ;
15385       else
15386         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15387         sw_if_index_set = 1;
15388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15389         sw_if_index_set = 1;
15390       else
15391         {
15392           clib_warning ("parse error '%U'", format_unformat_error, i);
15393           return -99;
15394         }
15395
15396     }
15397
15398   if (spd_id == (u32) ~ 0)
15399     {
15400       errmsg ("spd_id must be set");
15401       return -99;
15402     }
15403
15404   if (sw_if_index_set == 0)
15405     {
15406       errmsg ("missing interface name or sw_if_index");
15407       return -99;
15408     }
15409
15410   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15411
15412   mp->spd_id = ntohl (spd_id);
15413   mp->sw_if_index = ntohl (sw_if_index);
15414   mp->is_add = is_add;
15415
15416   S (mp);
15417   W (ret);
15418   return ret;
15419 }
15420
15421 static int
15422 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15423 {
15424   unformat_input_t *i = vam->input;
15425   vl_api_ipsec_spd_add_del_entry_t *mp;
15426   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15427   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15428   i32 priority = 0;
15429   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15430   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15431   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15432   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15433   int ret;
15434
15435   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15436   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15437   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15438   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15439   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15440   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15441
15442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15443     {
15444       if (unformat (i, "del"))
15445         is_add = 0;
15446       if (unformat (i, "outbound"))
15447         is_outbound = 1;
15448       if (unformat (i, "inbound"))
15449         is_outbound = 0;
15450       else if (unformat (i, "spd_id %d", &spd_id))
15451         ;
15452       else if (unformat (i, "sa_id %d", &sa_id))
15453         ;
15454       else if (unformat (i, "priority %d", &priority))
15455         ;
15456       else if (unformat (i, "protocol %d", &protocol))
15457         ;
15458       else if (unformat (i, "lport_start %d", &lport_start))
15459         ;
15460       else if (unformat (i, "lport_stop %d", &lport_stop))
15461         ;
15462       else if (unformat (i, "rport_start %d", &rport_start))
15463         ;
15464       else if (unformat (i, "rport_stop %d", &rport_stop))
15465         ;
15466       else
15467         if (unformat
15468             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15469         {
15470           is_ipv6 = 0;
15471           is_ip_any = 0;
15472         }
15473       else
15474         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15475         {
15476           is_ipv6 = 0;
15477           is_ip_any = 0;
15478         }
15479       else
15480         if (unformat
15481             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15482         {
15483           is_ipv6 = 0;
15484           is_ip_any = 0;
15485         }
15486       else
15487         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15488         {
15489           is_ipv6 = 0;
15490           is_ip_any = 0;
15491         }
15492       else
15493         if (unformat
15494             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15495         {
15496           is_ipv6 = 1;
15497           is_ip_any = 0;
15498         }
15499       else
15500         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15501         {
15502           is_ipv6 = 1;
15503           is_ip_any = 0;
15504         }
15505       else
15506         if (unformat
15507             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15508         {
15509           is_ipv6 = 1;
15510           is_ip_any = 0;
15511         }
15512       else
15513         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15514         {
15515           is_ipv6 = 1;
15516           is_ip_any = 0;
15517         }
15518       else
15519         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15520         {
15521           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15522             {
15523               clib_warning ("unsupported action: 'resolve'");
15524               return -99;
15525             }
15526         }
15527       else
15528         {
15529           clib_warning ("parse error '%U'", format_unformat_error, i);
15530           return -99;
15531         }
15532
15533     }
15534
15535   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15536
15537   mp->spd_id = ntohl (spd_id);
15538   mp->priority = ntohl (priority);
15539   mp->is_outbound = is_outbound;
15540
15541   mp->is_ipv6 = is_ipv6;
15542   if (is_ipv6 || is_ip_any)
15543     {
15544       clib_memcpy (mp->remote_address_start, &raddr6_start,
15545                    sizeof (ip6_address_t));
15546       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15547                    sizeof (ip6_address_t));
15548       clib_memcpy (mp->local_address_start, &laddr6_start,
15549                    sizeof (ip6_address_t));
15550       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15551                    sizeof (ip6_address_t));
15552     }
15553   else
15554     {
15555       clib_memcpy (mp->remote_address_start, &raddr4_start,
15556                    sizeof (ip4_address_t));
15557       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15558                    sizeof (ip4_address_t));
15559       clib_memcpy (mp->local_address_start, &laddr4_start,
15560                    sizeof (ip4_address_t));
15561       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15562                    sizeof (ip4_address_t));
15563     }
15564   mp->protocol = (u8) protocol;
15565   mp->local_port_start = ntohs ((u16) lport_start);
15566   mp->local_port_stop = ntohs ((u16) lport_stop);
15567   mp->remote_port_start = ntohs ((u16) rport_start);
15568   mp->remote_port_stop = ntohs ((u16) rport_stop);
15569   mp->policy = (u8) policy;
15570   mp->sa_id = ntohl (sa_id);
15571   mp->is_add = is_add;
15572   mp->is_ip_any = is_ip_any;
15573   S (mp);
15574   W (ret);
15575   return ret;
15576 }
15577
15578 static int
15579 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15580 {
15581   unformat_input_t *i = vam->input;
15582   vl_api_ipsec_sad_add_del_entry_t *mp;
15583   u32 sad_id = 0, spi = 0;
15584   u8 *ck = 0, *ik = 0;
15585   u8 is_add = 1;
15586
15587   u8 protocol = IPSEC_PROTOCOL_AH;
15588   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15589   u32 crypto_alg = 0, integ_alg = 0;
15590   ip4_address_t tun_src4;
15591   ip4_address_t tun_dst4;
15592   ip6_address_t tun_src6;
15593   ip6_address_t tun_dst6;
15594   int ret;
15595
15596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15597     {
15598       if (unformat (i, "del"))
15599         is_add = 0;
15600       else if (unformat (i, "sad_id %d", &sad_id))
15601         ;
15602       else if (unformat (i, "spi %d", &spi))
15603         ;
15604       else if (unformat (i, "esp"))
15605         protocol = IPSEC_PROTOCOL_ESP;
15606       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15607         {
15608           is_tunnel = 1;
15609           is_tunnel_ipv6 = 0;
15610         }
15611       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15612         {
15613           is_tunnel = 1;
15614           is_tunnel_ipv6 = 0;
15615         }
15616       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15617         {
15618           is_tunnel = 1;
15619           is_tunnel_ipv6 = 1;
15620         }
15621       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15622         {
15623           is_tunnel = 1;
15624           is_tunnel_ipv6 = 1;
15625         }
15626       else
15627         if (unformat
15628             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15629         {
15630           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15631             {
15632               clib_warning ("unsupported crypto-alg: '%U'",
15633                             format_ipsec_crypto_alg, crypto_alg);
15634               return -99;
15635             }
15636         }
15637       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15638         ;
15639       else
15640         if (unformat
15641             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15642         {
15643           if (integ_alg >= IPSEC_INTEG_N_ALG)
15644             {
15645               clib_warning ("unsupported integ-alg: '%U'",
15646                             format_ipsec_integ_alg, integ_alg);
15647               return -99;
15648             }
15649         }
15650       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15651         ;
15652       else
15653         {
15654           clib_warning ("parse error '%U'", format_unformat_error, i);
15655           return -99;
15656         }
15657
15658     }
15659
15660   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15661
15662   mp->sad_id = ntohl (sad_id);
15663   mp->is_add = is_add;
15664   mp->protocol = protocol;
15665   mp->spi = ntohl (spi);
15666   mp->is_tunnel = is_tunnel;
15667   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15668   mp->crypto_algorithm = crypto_alg;
15669   mp->integrity_algorithm = integ_alg;
15670   mp->crypto_key_length = vec_len (ck);
15671   mp->integrity_key_length = vec_len (ik);
15672
15673   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15674     mp->crypto_key_length = sizeof (mp->crypto_key);
15675
15676   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15677     mp->integrity_key_length = sizeof (mp->integrity_key);
15678
15679   if (ck)
15680     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15681   if (ik)
15682     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15683
15684   if (is_tunnel)
15685     {
15686       if (is_tunnel_ipv6)
15687         {
15688           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15689                        sizeof (ip6_address_t));
15690           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15691                        sizeof (ip6_address_t));
15692         }
15693       else
15694         {
15695           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15696                        sizeof (ip4_address_t));
15697           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15698                        sizeof (ip4_address_t));
15699         }
15700     }
15701
15702   S (mp);
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static int
15708 api_ipsec_sa_set_key (vat_main_t * vam)
15709 {
15710   unformat_input_t *i = vam->input;
15711   vl_api_ipsec_sa_set_key_t *mp;
15712   u32 sa_id;
15713   u8 *ck = 0, *ik = 0;
15714   int ret;
15715
15716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15717     {
15718       if (unformat (i, "sa_id %d", &sa_id))
15719         ;
15720       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15721         ;
15722       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15723         ;
15724       else
15725         {
15726           clib_warning ("parse error '%U'", format_unformat_error, i);
15727           return -99;
15728         }
15729     }
15730
15731   M (IPSEC_SA_SET_KEY, mp);
15732
15733   mp->sa_id = ntohl (sa_id);
15734   mp->crypto_key_length = vec_len (ck);
15735   mp->integrity_key_length = vec_len (ik);
15736
15737   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15738     mp->crypto_key_length = sizeof (mp->crypto_key);
15739
15740   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15741     mp->integrity_key_length = sizeof (mp->integrity_key);
15742
15743   if (ck)
15744     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15745   if (ik)
15746     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15747
15748   S (mp);
15749   W (ret);
15750   return ret;
15751 }
15752
15753 static int
15754 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15755 {
15756   unformat_input_t *i = vam->input;
15757   vl_api_ipsec_tunnel_if_add_del_t *mp;
15758   u32 local_spi = 0, remote_spi = 0;
15759   u32 crypto_alg = 0, integ_alg = 0;
15760   u8 *lck = NULL, *rck = NULL;
15761   u8 *lik = NULL, *rik = NULL;
15762   ip4_address_t local_ip = { {0} };
15763   ip4_address_t remote_ip = { {0} };
15764   u8 is_add = 1;
15765   u8 esn = 0;
15766   u8 anti_replay = 0;
15767   u8 renumber = 0;
15768   u32 instance = ~0;
15769   int ret;
15770
15771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15772     {
15773       if (unformat (i, "del"))
15774         is_add = 0;
15775       else if (unformat (i, "esn"))
15776         esn = 1;
15777       else if (unformat (i, "anti_replay"))
15778         anti_replay = 1;
15779       else if (unformat (i, "local_spi %d", &local_spi))
15780         ;
15781       else if (unformat (i, "remote_spi %d", &remote_spi))
15782         ;
15783       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15784         ;
15785       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15786         ;
15787       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15788         ;
15789       else
15790         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15791         ;
15792       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15793         ;
15794       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15795         ;
15796       else
15797         if (unformat
15798             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15799         {
15800           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15801             {
15802               errmsg ("unsupported crypto-alg: '%U'\n",
15803                       format_ipsec_crypto_alg, crypto_alg);
15804               return -99;
15805             }
15806         }
15807       else
15808         if (unformat
15809             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15810         {
15811           if (integ_alg >= IPSEC_INTEG_N_ALG)
15812             {
15813               errmsg ("unsupported integ-alg: '%U'\n",
15814                       format_ipsec_integ_alg, integ_alg);
15815               return -99;
15816             }
15817         }
15818       else if (unformat (i, "instance %u", &instance))
15819         renumber = 1;
15820       else
15821         {
15822           errmsg ("parse error '%U'\n", format_unformat_error, i);
15823           return -99;
15824         }
15825     }
15826
15827   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15828
15829   mp->is_add = is_add;
15830   mp->esn = esn;
15831   mp->anti_replay = anti_replay;
15832
15833   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15834   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15835
15836   mp->local_spi = htonl (local_spi);
15837   mp->remote_spi = htonl (remote_spi);
15838   mp->crypto_alg = (u8) crypto_alg;
15839
15840   mp->local_crypto_key_len = 0;
15841   if (lck)
15842     {
15843       mp->local_crypto_key_len = vec_len (lck);
15844       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15845         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15846       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15847     }
15848
15849   mp->remote_crypto_key_len = 0;
15850   if (rck)
15851     {
15852       mp->remote_crypto_key_len = vec_len (rck);
15853       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15854         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15855       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15856     }
15857
15858   mp->integ_alg = (u8) integ_alg;
15859
15860   mp->local_integ_key_len = 0;
15861   if (lik)
15862     {
15863       mp->local_integ_key_len = vec_len (lik);
15864       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15865         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15866       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15867     }
15868
15869   mp->remote_integ_key_len = 0;
15870   if (rik)
15871     {
15872       mp->remote_integ_key_len = vec_len (rik);
15873       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15874         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15875       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15876     }
15877
15878   if (renumber)
15879     {
15880       mp->renumber = renumber;
15881       mp->show_instance = ntohl (instance);
15882     }
15883
15884   S (mp);
15885   W (ret);
15886   return ret;
15887 }
15888
15889 static void
15890 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15891 {
15892   vat_main_t *vam = &vat_main;
15893
15894   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15895          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15896          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15897          "tunnel_src_addr %U tunnel_dst_addr %U "
15898          "salt %u seq_outbound %lu last_seq_inbound %lu "
15899          "replay_window %lu total_data_size %lu\n",
15900          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15901          mp->protocol,
15902          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15903          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15904          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15905          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15906          mp->tunnel_src_addr,
15907          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15908          mp->tunnel_dst_addr,
15909          ntohl (mp->salt),
15910          clib_net_to_host_u64 (mp->seq_outbound),
15911          clib_net_to_host_u64 (mp->last_seq_inbound),
15912          clib_net_to_host_u64 (mp->replay_window),
15913          clib_net_to_host_u64 (mp->total_data_size));
15914 }
15915
15916 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15917 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15918
15919 static void vl_api_ipsec_sa_details_t_handler_json
15920   (vl_api_ipsec_sa_details_t * mp)
15921 {
15922   vat_main_t *vam = &vat_main;
15923   vat_json_node_t *node = NULL;
15924   struct in_addr src_ip4, dst_ip4;
15925   struct in6_addr src_ip6, dst_ip6;
15926
15927   if (VAT_JSON_ARRAY != vam->json_tree.type)
15928     {
15929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15930       vat_json_init_array (&vam->json_tree);
15931     }
15932   node = vat_json_array_add (&vam->json_tree);
15933
15934   vat_json_init_object (node);
15935   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15936   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15937   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15938   vat_json_object_add_uint (node, "proto", mp->protocol);
15939   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15940   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15941   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15942   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15943   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15944   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15945   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15946                              mp->crypto_key_len);
15947   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15948                              mp->integ_key_len);
15949   if (mp->is_tunnel_ip6)
15950     {
15951       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15952       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15953       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15954       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15955     }
15956   else
15957     {
15958       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15959       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15960       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15961       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15962     }
15963   vat_json_object_add_uint (node, "replay_window",
15964                             clib_net_to_host_u64 (mp->replay_window));
15965   vat_json_object_add_uint (node, "total_data_size",
15966                             clib_net_to_host_u64 (mp->total_data_size));
15967
15968 }
15969
15970 static int
15971 api_ipsec_sa_dump (vat_main_t * vam)
15972 {
15973   unformat_input_t *i = vam->input;
15974   vl_api_ipsec_sa_dump_t *mp;
15975   vl_api_control_ping_t *mp_ping;
15976   u32 sa_id = ~0;
15977   int ret;
15978
15979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15980     {
15981       if (unformat (i, "sa_id %d", &sa_id))
15982         ;
15983       else
15984         {
15985           clib_warning ("parse error '%U'", format_unformat_error, i);
15986           return -99;
15987         }
15988     }
15989
15990   M (IPSEC_SA_DUMP, mp);
15991
15992   mp->sa_id = ntohl (sa_id);
15993
15994   S (mp);
15995
15996   /* Use a control ping for synchronization */
15997   M (CONTROL_PING, mp_ping);
15998   S (mp_ping);
15999
16000   W (ret);
16001   return ret;
16002 }
16003
16004 static int
16005 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
16006 {
16007   unformat_input_t *i = vam->input;
16008   vl_api_ipsec_tunnel_if_set_key_t *mp;
16009   u32 sw_if_index = ~0;
16010   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
16011   u8 *key = 0;
16012   u32 alg = ~0;
16013   int ret;
16014
16015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16016     {
16017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16018         ;
16019       else
16020         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
16021         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
16022       else
16023         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
16024         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
16025       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
16026         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16027       else
16028         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16029         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16030       else if (unformat (i, "%U", unformat_hex_string, &key))
16031         ;
16032       else
16033         {
16034           clib_warning ("parse error '%U'", format_unformat_error, i);
16035           return -99;
16036         }
16037     }
16038
16039   if (sw_if_index == ~0)
16040     {
16041       errmsg ("interface must be specified");
16042       return -99;
16043     }
16044
16045   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16046     {
16047       errmsg ("key type must be specified");
16048       return -99;
16049     }
16050
16051   if (alg == ~0)
16052     {
16053       errmsg ("algorithm must be specified");
16054       return -99;
16055     }
16056
16057   if (vec_len (key) == 0)
16058     {
16059       errmsg ("key must be specified");
16060       return -99;
16061     }
16062
16063   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16064
16065   mp->sw_if_index = htonl (sw_if_index);
16066   mp->alg = alg;
16067   mp->key_type = key_type;
16068   mp->key_len = vec_len (key);
16069   clib_memcpy (mp->key, key, vec_len (key));
16070
16071   S (mp);
16072   W (ret);
16073
16074   return ret;
16075 }
16076
16077 static int
16078 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16079 {
16080   unformat_input_t *i = vam->input;
16081   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16082   u32 sw_if_index = ~0;
16083   u32 sa_id = ~0;
16084   u8 is_outbound = (u8) ~ 0;
16085   int ret;
16086
16087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16090         ;
16091       else if (unformat (i, "sa_id %d", &sa_id))
16092         ;
16093       else if (unformat (i, "outbound"))
16094         is_outbound = 1;
16095       else if (unformat (i, "inbound"))
16096         is_outbound = 0;
16097       else
16098         {
16099           clib_warning ("parse error '%U'", format_unformat_error, i);
16100           return -99;
16101         }
16102     }
16103
16104   if (sw_if_index == ~0)
16105     {
16106       errmsg ("interface must be specified");
16107       return -99;
16108     }
16109
16110   if (sa_id == ~0)
16111     {
16112       errmsg ("SA ID must be specified");
16113       return -99;
16114     }
16115
16116   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16117
16118   mp->sw_if_index = htonl (sw_if_index);
16119   mp->sa_id = htonl (sa_id);
16120   mp->is_outbound = is_outbound;
16121
16122   S (mp);
16123   W (ret);
16124
16125   return ret;
16126 }
16127
16128 static int
16129 api_ikev2_profile_add_del (vat_main_t * vam)
16130 {
16131   unformat_input_t *i = vam->input;
16132   vl_api_ikev2_profile_add_del_t *mp;
16133   u8 is_add = 1;
16134   u8 *name = 0;
16135   int ret;
16136
16137   const char *valid_chars = "a-zA-Z0-9_";
16138
16139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16140     {
16141       if (unformat (i, "del"))
16142         is_add = 0;
16143       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16144         vec_add1 (name, 0);
16145       else
16146         {
16147           errmsg ("parse error '%U'", format_unformat_error, i);
16148           return -99;
16149         }
16150     }
16151
16152   if (!vec_len (name))
16153     {
16154       errmsg ("profile name must be specified");
16155       return -99;
16156     }
16157
16158   if (vec_len (name) > 64)
16159     {
16160       errmsg ("profile name too long");
16161       return -99;
16162     }
16163
16164   M (IKEV2_PROFILE_ADD_DEL, mp);
16165
16166   clib_memcpy (mp->name, name, vec_len (name));
16167   mp->is_add = is_add;
16168   vec_free (name);
16169
16170   S (mp);
16171   W (ret);
16172   return ret;
16173 }
16174
16175 static int
16176 api_ikev2_profile_set_auth (vat_main_t * vam)
16177 {
16178   unformat_input_t *i = vam->input;
16179   vl_api_ikev2_profile_set_auth_t *mp;
16180   u8 *name = 0;
16181   u8 *data = 0;
16182   u32 auth_method = 0;
16183   u8 is_hex = 0;
16184   int ret;
16185
16186   const char *valid_chars = "a-zA-Z0-9_";
16187
16188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16189     {
16190       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16191         vec_add1 (name, 0);
16192       else if (unformat (i, "auth_method %U",
16193                          unformat_ikev2_auth_method, &auth_method))
16194         ;
16195       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16196         is_hex = 1;
16197       else if (unformat (i, "auth_data %v", &data))
16198         ;
16199       else
16200         {
16201           errmsg ("parse error '%U'", format_unformat_error, i);
16202           return -99;
16203         }
16204     }
16205
16206   if (!vec_len (name))
16207     {
16208       errmsg ("profile name must be specified");
16209       return -99;
16210     }
16211
16212   if (vec_len (name) > 64)
16213     {
16214       errmsg ("profile name too long");
16215       return -99;
16216     }
16217
16218   if (!vec_len (data))
16219     {
16220       errmsg ("auth_data must be specified");
16221       return -99;
16222     }
16223
16224   if (!auth_method)
16225     {
16226       errmsg ("auth_method must be specified");
16227       return -99;
16228     }
16229
16230   M (IKEV2_PROFILE_SET_AUTH, mp);
16231
16232   mp->is_hex = is_hex;
16233   mp->auth_method = (u8) auth_method;
16234   mp->data_len = vec_len (data);
16235   clib_memcpy (mp->name, name, vec_len (name));
16236   clib_memcpy (mp->data, data, vec_len (data));
16237   vec_free (name);
16238   vec_free (data);
16239
16240   S (mp);
16241   W (ret);
16242   return ret;
16243 }
16244
16245 static int
16246 api_ikev2_profile_set_id (vat_main_t * vam)
16247 {
16248   unformat_input_t *i = vam->input;
16249   vl_api_ikev2_profile_set_id_t *mp;
16250   u8 *name = 0;
16251   u8 *data = 0;
16252   u8 is_local = 0;
16253   u32 id_type = 0;
16254   ip4_address_t ip4;
16255   int ret;
16256
16257   const char *valid_chars = "a-zA-Z0-9_";
16258
16259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16262         vec_add1 (name, 0);
16263       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16264         ;
16265       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16266         {
16267           data = vec_new (u8, 4);
16268           clib_memcpy (data, ip4.as_u8, 4);
16269         }
16270       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16271         ;
16272       else if (unformat (i, "id_data %v", &data))
16273         ;
16274       else if (unformat (i, "local"))
16275         is_local = 1;
16276       else if (unformat (i, "remote"))
16277         is_local = 0;
16278       else
16279         {
16280           errmsg ("parse error '%U'", format_unformat_error, i);
16281           return -99;
16282         }
16283     }
16284
16285   if (!vec_len (name))
16286     {
16287       errmsg ("profile name must be specified");
16288       return -99;
16289     }
16290
16291   if (vec_len (name) > 64)
16292     {
16293       errmsg ("profile name too long");
16294       return -99;
16295     }
16296
16297   if (!vec_len (data))
16298     {
16299       errmsg ("id_data must be specified");
16300       return -99;
16301     }
16302
16303   if (!id_type)
16304     {
16305       errmsg ("id_type must be specified");
16306       return -99;
16307     }
16308
16309   M (IKEV2_PROFILE_SET_ID, mp);
16310
16311   mp->is_local = is_local;
16312   mp->id_type = (u8) id_type;
16313   mp->data_len = vec_len (data);
16314   clib_memcpy (mp->name, name, vec_len (name));
16315   clib_memcpy (mp->data, data, vec_len (data));
16316   vec_free (name);
16317   vec_free (data);
16318
16319   S (mp);
16320   W (ret);
16321   return ret;
16322 }
16323
16324 static int
16325 api_ikev2_profile_set_ts (vat_main_t * vam)
16326 {
16327   unformat_input_t *i = vam->input;
16328   vl_api_ikev2_profile_set_ts_t *mp;
16329   u8 *name = 0;
16330   u8 is_local = 0;
16331   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16332   ip4_address_t start_addr, end_addr;
16333
16334   const char *valid_chars = "a-zA-Z0-9_";
16335   int ret;
16336
16337   start_addr.as_u32 = 0;
16338   end_addr.as_u32 = (u32) ~ 0;
16339
16340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16341     {
16342       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16343         vec_add1 (name, 0);
16344       else if (unformat (i, "protocol %d", &proto))
16345         ;
16346       else if (unformat (i, "start_port %d", &start_port))
16347         ;
16348       else if (unformat (i, "end_port %d", &end_port))
16349         ;
16350       else
16351         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16352         ;
16353       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16354         ;
16355       else if (unformat (i, "local"))
16356         is_local = 1;
16357       else if (unformat (i, "remote"))
16358         is_local = 0;
16359       else
16360         {
16361           errmsg ("parse error '%U'", format_unformat_error, i);
16362           return -99;
16363         }
16364     }
16365
16366   if (!vec_len (name))
16367     {
16368       errmsg ("profile name must be specified");
16369       return -99;
16370     }
16371
16372   if (vec_len (name) > 64)
16373     {
16374       errmsg ("profile name too long");
16375       return -99;
16376     }
16377
16378   M (IKEV2_PROFILE_SET_TS, mp);
16379
16380   mp->is_local = is_local;
16381   mp->proto = (u8) proto;
16382   mp->start_port = (u16) start_port;
16383   mp->end_port = (u16) end_port;
16384   mp->start_addr = start_addr.as_u32;
16385   mp->end_addr = end_addr.as_u32;
16386   clib_memcpy (mp->name, name, vec_len (name));
16387   vec_free (name);
16388
16389   S (mp);
16390   W (ret);
16391   return ret;
16392 }
16393
16394 static int
16395 api_ikev2_set_local_key (vat_main_t * vam)
16396 {
16397   unformat_input_t *i = vam->input;
16398   vl_api_ikev2_set_local_key_t *mp;
16399   u8 *file = 0;
16400   int ret;
16401
16402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16403     {
16404       if (unformat (i, "file %v", &file))
16405         vec_add1 (file, 0);
16406       else
16407         {
16408           errmsg ("parse error '%U'", format_unformat_error, i);
16409           return -99;
16410         }
16411     }
16412
16413   if (!vec_len (file))
16414     {
16415       errmsg ("RSA key file must be specified");
16416       return -99;
16417     }
16418
16419   if (vec_len (file) > 256)
16420     {
16421       errmsg ("file name too long");
16422       return -99;
16423     }
16424
16425   M (IKEV2_SET_LOCAL_KEY, mp);
16426
16427   clib_memcpy (mp->key_file, file, vec_len (file));
16428   vec_free (file);
16429
16430   S (mp);
16431   W (ret);
16432   return ret;
16433 }
16434
16435 static int
16436 api_ikev2_set_responder (vat_main_t * vam)
16437 {
16438   unformat_input_t *i = vam->input;
16439   vl_api_ikev2_set_responder_t *mp;
16440   int ret;
16441   u8 *name = 0;
16442   u32 sw_if_index = ~0;
16443   ip4_address_t address;
16444
16445   const char *valid_chars = "a-zA-Z0-9_";
16446
16447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16448     {
16449       if (unformat
16450           (i, "%U interface %d address %U", unformat_token, valid_chars,
16451            &name, &sw_if_index, unformat_ip4_address, &address))
16452         vec_add1 (name, 0);
16453       else
16454         {
16455           errmsg ("parse error '%U'", format_unformat_error, i);
16456           return -99;
16457         }
16458     }
16459
16460   if (!vec_len (name))
16461     {
16462       errmsg ("profile name must be specified");
16463       return -99;
16464     }
16465
16466   if (vec_len (name) > 64)
16467     {
16468       errmsg ("profile name too long");
16469       return -99;
16470     }
16471
16472   M (IKEV2_SET_RESPONDER, mp);
16473
16474   clib_memcpy (mp->name, name, vec_len (name));
16475   vec_free (name);
16476
16477   mp->sw_if_index = sw_if_index;
16478   clib_memcpy (mp->address, &address, sizeof (address));
16479
16480   S (mp);
16481   W (ret);
16482   return ret;
16483 }
16484
16485 static int
16486 api_ikev2_set_ike_transforms (vat_main_t * vam)
16487 {
16488   unformat_input_t *i = vam->input;
16489   vl_api_ikev2_set_ike_transforms_t *mp;
16490   int ret;
16491   u8 *name = 0;
16492   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16493
16494   const char *valid_chars = "a-zA-Z0-9_";
16495
16496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16497     {
16498       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16499                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16500         vec_add1 (name, 0);
16501       else
16502         {
16503           errmsg ("parse error '%U'", format_unformat_error, i);
16504           return -99;
16505         }
16506     }
16507
16508   if (!vec_len (name))
16509     {
16510       errmsg ("profile name must be specified");
16511       return -99;
16512     }
16513
16514   if (vec_len (name) > 64)
16515     {
16516       errmsg ("profile name too long");
16517       return -99;
16518     }
16519
16520   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16521
16522   clib_memcpy (mp->name, name, vec_len (name));
16523   vec_free (name);
16524   mp->crypto_alg = crypto_alg;
16525   mp->crypto_key_size = crypto_key_size;
16526   mp->integ_alg = integ_alg;
16527   mp->dh_group = dh_group;
16528
16529   S (mp);
16530   W (ret);
16531   return ret;
16532 }
16533
16534
16535 static int
16536 api_ikev2_set_esp_transforms (vat_main_t * vam)
16537 {
16538   unformat_input_t *i = vam->input;
16539   vl_api_ikev2_set_esp_transforms_t *mp;
16540   int ret;
16541   u8 *name = 0;
16542   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16543
16544   const char *valid_chars = "a-zA-Z0-9_";
16545
16546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16547     {
16548       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16549                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16550         vec_add1 (name, 0);
16551       else
16552         {
16553           errmsg ("parse error '%U'", format_unformat_error, i);
16554           return -99;
16555         }
16556     }
16557
16558   if (!vec_len (name))
16559     {
16560       errmsg ("profile name must be specified");
16561       return -99;
16562     }
16563
16564   if (vec_len (name) > 64)
16565     {
16566       errmsg ("profile name too long");
16567       return -99;
16568     }
16569
16570   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16571
16572   clib_memcpy (mp->name, name, vec_len (name));
16573   vec_free (name);
16574   mp->crypto_alg = crypto_alg;
16575   mp->crypto_key_size = crypto_key_size;
16576   mp->integ_alg = integ_alg;
16577   mp->dh_group = dh_group;
16578
16579   S (mp);
16580   W (ret);
16581   return ret;
16582 }
16583
16584 static int
16585 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16586 {
16587   unformat_input_t *i = vam->input;
16588   vl_api_ikev2_set_sa_lifetime_t *mp;
16589   int ret;
16590   u8 *name = 0;
16591   u64 lifetime, lifetime_maxdata;
16592   u32 lifetime_jitter, handover;
16593
16594   const char *valid_chars = "a-zA-Z0-9_";
16595
16596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16597     {
16598       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16599                     &lifetime, &lifetime_jitter, &handover,
16600                     &lifetime_maxdata))
16601         vec_add1 (name, 0);
16602       else
16603         {
16604           errmsg ("parse error '%U'", format_unformat_error, i);
16605           return -99;
16606         }
16607     }
16608
16609   if (!vec_len (name))
16610     {
16611       errmsg ("profile name must be specified");
16612       return -99;
16613     }
16614
16615   if (vec_len (name) > 64)
16616     {
16617       errmsg ("profile name too long");
16618       return -99;
16619     }
16620
16621   M (IKEV2_SET_SA_LIFETIME, mp);
16622
16623   clib_memcpy (mp->name, name, vec_len (name));
16624   vec_free (name);
16625   mp->lifetime = lifetime;
16626   mp->lifetime_jitter = lifetime_jitter;
16627   mp->handover = handover;
16628   mp->lifetime_maxdata = lifetime_maxdata;
16629
16630   S (mp);
16631   W (ret);
16632   return ret;
16633 }
16634
16635 static int
16636 api_ikev2_initiate_sa_init (vat_main_t * vam)
16637 {
16638   unformat_input_t *i = vam->input;
16639   vl_api_ikev2_initiate_sa_init_t *mp;
16640   int ret;
16641   u8 *name = 0;
16642
16643   const char *valid_chars = "a-zA-Z0-9_";
16644
16645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16646     {
16647       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16648         vec_add1 (name, 0);
16649       else
16650         {
16651           errmsg ("parse error '%U'", format_unformat_error, i);
16652           return -99;
16653         }
16654     }
16655
16656   if (!vec_len (name))
16657     {
16658       errmsg ("profile name must be specified");
16659       return -99;
16660     }
16661
16662   if (vec_len (name) > 64)
16663     {
16664       errmsg ("profile name too long");
16665       return -99;
16666     }
16667
16668   M (IKEV2_INITIATE_SA_INIT, mp);
16669
16670   clib_memcpy (mp->name, name, vec_len (name));
16671   vec_free (name);
16672
16673   S (mp);
16674   W (ret);
16675   return ret;
16676 }
16677
16678 static int
16679 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16680 {
16681   unformat_input_t *i = vam->input;
16682   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16683   int ret;
16684   u64 ispi;
16685
16686
16687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (i, "%lx", &ispi))
16690         ;
16691       else
16692         {
16693           errmsg ("parse error '%U'", format_unformat_error, i);
16694           return -99;
16695         }
16696     }
16697
16698   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16699
16700   mp->ispi = ispi;
16701
16702   S (mp);
16703   W (ret);
16704   return ret;
16705 }
16706
16707 static int
16708 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16709 {
16710   unformat_input_t *i = vam->input;
16711   vl_api_ikev2_initiate_del_child_sa_t *mp;
16712   int ret;
16713   u32 ispi;
16714
16715
16716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (i, "%x", &ispi))
16719         ;
16720       else
16721         {
16722           errmsg ("parse error '%U'", format_unformat_error, i);
16723           return -99;
16724         }
16725     }
16726
16727   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16728
16729   mp->ispi = ispi;
16730
16731   S (mp);
16732   W (ret);
16733   return ret;
16734 }
16735
16736 static int
16737 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16738 {
16739   unformat_input_t *i = vam->input;
16740   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16741   int ret;
16742   u32 ispi;
16743
16744
16745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16746     {
16747       if (unformat (i, "%x", &ispi))
16748         ;
16749       else
16750         {
16751           errmsg ("parse error '%U'", format_unformat_error, i);
16752           return -99;
16753         }
16754     }
16755
16756   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16757
16758   mp->ispi = ispi;
16759
16760   S (mp);
16761   W (ret);
16762   return ret;
16763 }
16764
16765 static int
16766 api_get_first_msg_id (vat_main_t * vam)
16767 {
16768   vl_api_get_first_msg_id_t *mp;
16769   unformat_input_t *i = vam->input;
16770   u8 *name;
16771   u8 name_set = 0;
16772   int ret;
16773
16774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16775     {
16776       if (unformat (i, "client %s", &name))
16777         name_set = 1;
16778       else
16779         break;
16780     }
16781
16782   if (name_set == 0)
16783     {
16784       errmsg ("missing client name");
16785       return -99;
16786     }
16787   vec_add1 (name, 0);
16788
16789   if (vec_len (name) > 63)
16790     {
16791       errmsg ("client name too long");
16792       return -99;
16793     }
16794
16795   M (GET_FIRST_MSG_ID, mp);
16796   clib_memcpy (mp->name, name, vec_len (name));
16797   S (mp);
16798   W (ret);
16799   return ret;
16800 }
16801
16802 static int
16803 api_cop_interface_enable_disable (vat_main_t * vam)
16804 {
16805   unformat_input_t *line_input = vam->input;
16806   vl_api_cop_interface_enable_disable_t *mp;
16807   u32 sw_if_index = ~0;
16808   u8 enable_disable = 1;
16809   int ret;
16810
16811   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (line_input, "disable"))
16814         enable_disable = 0;
16815       if (unformat (line_input, "enable"))
16816         enable_disable = 1;
16817       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16818                          vam, &sw_if_index))
16819         ;
16820       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16821         ;
16822       else
16823         break;
16824     }
16825
16826   if (sw_if_index == ~0)
16827     {
16828       errmsg ("missing interface name or sw_if_index");
16829       return -99;
16830     }
16831
16832   /* Construct the API message */
16833   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16834   mp->sw_if_index = ntohl (sw_if_index);
16835   mp->enable_disable = enable_disable;
16836
16837   /* send it... */
16838   S (mp);
16839   /* Wait for the reply */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 static int
16845 api_cop_whitelist_enable_disable (vat_main_t * vam)
16846 {
16847   unformat_input_t *line_input = vam->input;
16848   vl_api_cop_whitelist_enable_disable_t *mp;
16849   u32 sw_if_index = ~0;
16850   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16851   u32 fib_id = 0;
16852   int ret;
16853
16854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16855     {
16856       if (unformat (line_input, "ip4"))
16857         ip4 = 1;
16858       else if (unformat (line_input, "ip6"))
16859         ip6 = 1;
16860       else if (unformat (line_input, "default"))
16861         default_cop = 1;
16862       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16863                          vam, &sw_if_index))
16864         ;
16865       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16866         ;
16867       else if (unformat (line_input, "fib-id %d", &fib_id))
16868         ;
16869       else
16870         break;
16871     }
16872
16873   if (sw_if_index == ~0)
16874     {
16875       errmsg ("missing interface name or sw_if_index");
16876       return -99;
16877     }
16878
16879   /* Construct the API message */
16880   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16881   mp->sw_if_index = ntohl (sw_if_index);
16882   mp->fib_id = ntohl (fib_id);
16883   mp->ip4 = ip4;
16884   mp->ip6 = ip6;
16885   mp->default_cop = default_cop;
16886
16887   /* send it... */
16888   S (mp);
16889   /* Wait for the reply */
16890   W (ret);
16891   return ret;
16892 }
16893
16894 static int
16895 api_get_node_graph (vat_main_t * vam)
16896 {
16897   vl_api_get_node_graph_t *mp;
16898   int ret;
16899
16900   M (GET_NODE_GRAPH, mp);
16901
16902   /* send it... */
16903   S (mp);
16904   /* Wait for the reply */
16905   W (ret);
16906   return ret;
16907 }
16908
16909 /* *INDENT-OFF* */
16910 /** Used for parsing LISP eids */
16911 typedef CLIB_PACKED(struct{
16912   u8 addr[16];   /**< eid address */
16913   u32 len;       /**< prefix length if IP */
16914   u8 type;      /**< type of eid */
16915 }) lisp_eid_vat_t;
16916 /* *INDENT-ON* */
16917
16918 static uword
16919 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16920 {
16921   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16922
16923   clib_memset (a, 0, sizeof (a[0]));
16924
16925   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16926     {
16927       a->type = 0;              /* ipv4 type */
16928     }
16929   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16930     {
16931       a->type = 1;              /* ipv6 type */
16932     }
16933   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16934     {
16935       a->type = 2;              /* mac type */
16936     }
16937   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16938     {
16939       a->type = 3;              /* NSH type */
16940       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16941       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16942     }
16943   else
16944     {
16945       return 0;
16946     }
16947
16948   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16949     {
16950       return 0;
16951     }
16952
16953   return 1;
16954 }
16955
16956 static int
16957 lisp_eid_size_vat (u8 type)
16958 {
16959   switch (type)
16960     {
16961     case 0:
16962       return 4;
16963     case 1:
16964       return 16;
16965     case 2:
16966       return 6;
16967     case 3:
16968       return 5;
16969     }
16970   return 0;
16971 }
16972
16973 static void
16974 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16975 {
16976   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16977 }
16978
16979 static int
16980 api_one_add_del_locator_set (vat_main_t * vam)
16981 {
16982   unformat_input_t *input = vam->input;
16983   vl_api_one_add_del_locator_set_t *mp;
16984   u8 is_add = 1;
16985   u8 *locator_set_name = NULL;
16986   u8 locator_set_name_set = 0;
16987   vl_api_local_locator_t locator, *locators = 0;
16988   u32 sw_if_index, priority, weight;
16989   u32 data_len = 0;
16990
16991   int ret;
16992   /* Parse args required to build the message */
16993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16994     {
16995       if (unformat (input, "del"))
16996         {
16997           is_add = 0;
16998         }
16999       else if (unformat (input, "locator-set %s", &locator_set_name))
17000         {
17001           locator_set_name_set = 1;
17002         }
17003       else if (unformat (input, "sw_if_index %u p %u w %u",
17004                          &sw_if_index, &priority, &weight))
17005         {
17006           locator.sw_if_index = htonl (sw_if_index);
17007           locator.priority = priority;
17008           locator.weight = weight;
17009           vec_add1 (locators, locator);
17010         }
17011       else
17012         if (unformat
17013             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
17014              &sw_if_index, &priority, &weight))
17015         {
17016           locator.sw_if_index = htonl (sw_if_index);
17017           locator.priority = priority;
17018           locator.weight = weight;
17019           vec_add1 (locators, locator);
17020         }
17021       else
17022         break;
17023     }
17024
17025   if (locator_set_name_set == 0)
17026     {
17027       errmsg ("missing locator-set name");
17028       vec_free (locators);
17029       return -99;
17030     }
17031
17032   if (vec_len (locator_set_name) > 64)
17033     {
17034       errmsg ("locator-set name too long");
17035       vec_free (locator_set_name);
17036       vec_free (locators);
17037       return -99;
17038     }
17039   vec_add1 (locator_set_name, 0);
17040
17041   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17042
17043   /* Construct the API message */
17044   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17045
17046   mp->is_add = is_add;
17047   clib_memcpy (mp->locator_set_name, locator_set_name,
17048                vec_len (locator_set_name));
17049   vec_free (locator_set_name);
17050
17051   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17052   if (locators)
17053     clib_memcpy (mp->locators, locators, data_len);
17054   vec_free (locators);
17055
17056   /* send it... */
17057   S (mp);
17058
17059   /* Wait for a reply... */
17060   W (ret);
17061   return ret;
17062 }
17063
17064 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17065
17066 static int
17067 api_one_add_del_locator (vat_main_t * vam)
17068 {
17069   unformat_input_t *input = vam->input;
17070   vl_api_one_add_del_locator_t *mp;
17071   u32 tmp_if_index = ~0;
17072   u32 sw_if_index = ~0;
17073   u8 sw_if_index_set = 0;
17074   u8 sw_if_index_if_name_set = 0;
17075   u32 priority = ~0;
17076   u8 priority_set = 0;
17077   u32 weight = ~0;
17078   u8 weight_set = 0;
17079   u8 is_add = 1;
17080   u8 *locator_set_name = NULL;
17081   u8 locator_set_name_set = 0;
17082   int ret;
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "del"))
17088         {
17089           is_add = 0;
17090         }
17091       else if (unformat (input, "locator-set %s", &locator_set_name))
17092         {
17093           locator_set_name_set = 1;
17094         }
17095       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17096                          &tmp_if_index))
17097         {
17098           sw_if_index_if_name_set = 1;
17099           sw_if_index = tmp_if_index;
17100         }
17101       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17102         {
17103           sw_if_index_set = 1;
17104           sw_if_index = tmp_if_index;
17105         }
17106       else if (unformat (input, "p %d", &priority))
17107         {
17108           priority_set = 1;
17109         }
17110       else if (unformat (input, "w %d", &weight))
17111         {
17112           weight_set = 1;
17113         }
17114       else
17115         break;
17116     }
17117
17118   if (locator_set_name_set == 0)
17119     {
17120       errmsg ("missing locator-set name");
17121       return -99;
17122     }
17123
17124   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17125     {
17126       errmsg ("missing sw_if_index");
17127       vec_free (locator_set_name);
17128       return -99;
17129     }
17130
17131   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17132     {
17133       errmsg ("cannot use both params interface name and sw_if_index");
17134       vec_free (locator_set_name);
17135       return -99;
17136     }
17137
17138   if (priority_set == 0)
17139     {
17140       errmsg ("missing locator-set priority");
17141       vec_free (locator_set_name);
17142       return -99;
17143     }
17144
17145   if (weight_set == 0)
17146     {
17147       errmsg ("missing locator-set weight");
17148       vec_free (locator_set_name);
17149       return -99;
17150     }
17151
17152   if (vec_len (locator_set_name) > 64)
17153     {
17154       errmsg ("locator-set name too long");
17155       vec_free (locator_set_name);
17156       return -99;
17157     }
17158   vec_add1 (locator_set_name, 0);
17159
17160   /* Construct the API message */
17161   M (ONE_ADD_DEL_LOCATOR, mp);
17162
17163   mp->is_add = is_add;
17164   mp->sw_if_index = ntohl (sw_if_index);
17165   mp->priority = priority;
17166   mp->weight = weight;
17167   clib_memcpy (mp->locator_set_name, locator_set_name,
17168                vec_len (locator_set_name));
17169   vec_free (locator_set_name);
17170
17171   /* send it... */
17172   S (mp);
17173
17174   /* Wait for a reply... */
17175   W (ret);
17176   return ret;
17177 }
17178
17179 #define api_lisp_add_del_locator api_one_add_del_locator
17180
17181 uword
17182 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17183 {
17184   u32 *key_id = va_arg (*args, u32 *);
17185   u8 *s = 0;
17186
17187   if (unformat (input, "%s", &s))
17188     {
17189       if (!strcmp ((char *) s, "sha1"))
17190         key_id[0] = HMAC_SHA_1_96;
17191       else if (!strcmp ((char *) s, "sha256"))
17192         key_id[0] = HMAC_SHA_256_128;
17193       else
17194         {
17195           clib_warning ("invalid key_id: '%s'", s);
17196           key_id[0] = HMAC_NO_KEY;
17197         }
17198     }
17199   else
17200     return 0;
17201
17202   vec_free (s);
17203   return 1;
17204 }
17205
17206 static int
17207 api_one_add_del_local_eid (vat_main_t * vam)
17208 {
17209   unformat_input_t *input = vam->input;
17210   vl_api_one_add_del_local_eid_t *mp;
17211   u8 is_add = 1;
17212   u8 eid_set = 0;
17213   lisp_eid_vat_t _eid, *eid = &_eid;
17214   u8 *locator_set_name = 0;
17215   u8 locator_set_name_set = 0;
17216   u32 vni = 0;
17217   u16 key_id = 0;
17218   u8 *key = 0;
17219   int ret;
17220
17221   /* Parse args required to build the message */
17222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (input, "del"))
17225         {
17226           is_add = 0;
17227         }
17228       else if (unformat (input, "vni %d", &vni))
17229         {
17230           ;
17231         }
17232       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17233         {
17234           eid_set = 1;
17235         }
17236       else if (unformat (input, "locator-set %s", &locator_set_name))
17237         {
17238           locator_set_name_set = 1;
17239         }
17240       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17241         ;
17242       else if (unformat (input, "secret-key %_%v%_", &key))
17243         ;
17244       else
17245         break;
17246     }
17247
17248   if (locator_set_name_set == 0)
17249     {
17250       errmsg ("missing locator-set name");
17251       return -99;
17252     }
17253
17254   if (0 == eid_set)
17255     {
17256       errmsg ("EID address not set!");
17257       vec_free (locator_set_name);
17258       return -99;
17259     }
17260
17261   if (key && (0 == key_id))
17262     {
17263       errmsg ("invalid key_id!");
17264       return -99;
17265     }
17266
17267   if (vec_len (key) > 64)
17268     {
17269       errmsg ("key too long");
17270       vec_free (key);
17271       return -99;
17272     }
17273
17274   if (vec_len (locator_set_name) > 64)
17275     {
17276       errmsg ("locator-set name too long");
17277       vec_free (locator_set_name);
17278       return -99;
17279     }
17280   vec_add1 (locator_set_name, 0);
17281
17282   /* Construct the API message */
17283   M (ONE_ADD_DEL_LOCAL_EID, mp);
17284
17285   mp->is_add = is_add;
17286   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17287   mp->eid_type = eid->type;
17288   mp->prefix_len = eid->len;
17289   mp->vni = clib_host_to_net_u32 (vni);
17290   mp->key_id = clib_host_to_net_u16 (key_id);
17291   clib_memcpy (mp->locator_set_name, locator_set_name,
17292                vec_len (locator_set_name));
17293   clib_memcpy (mp->key, key, vec_len (key));
17294
17295   vec_free (locator_set_name);
17296   vec_free (key);
17297
17298   /* send it... */
17299   S (mp);
17300
17301   /* Wait for a reply... */
17302   W (ret);
17303   return ret;
17304 }
17305
17306 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17307
17308 static int
17309 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17310 {
17311   u32 dp_table = 0, vni = 0;;
17312   unformat_input_t *input = vam->input;
17313   vl_api_gpe_add_del_fwd_entry_t *mp;
17314   u8 is_add = 1;
17315   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17316   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17317   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17318   u32 action = ~0, w;
17319   ip4_address_t rmt_rloc4, lcl_rloc4;
17320   ip6_address_t rmt_rloc6, lcl_rloc6;
17321   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17322   int ret;
17323
17324   clib_memset (&rloc, 0, sizeof (rloc));
17325
17326   /* Parse args required to build the message */
17327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17328     {
17329       if (unformat (input, "del"))
17330         is_add = 0;
17331       else if (unformat (input, "add"))
17332         is_add = 1;
17333       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17334         {
17335           rmt_eid_set = 1;
17336         }
17337       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17338         {
17339           lcl_eid_set = 1;
17340         }
17341       else if (unformat (input, "vrf %d", &dp_table))
17342         ;
17343       else if (unformat (input, "bd %d", &dp_table))
17344         ;
17345       else if (unformat (input, "vni %d", &vni))
17346         ;
17347       else if (unformat (input, "w %d", &w))
17348         {
17349           if (!curr_rloc)
17350             {
17351               errmsg ("No RLOC configured for setting priority/weight!");
17352               return -99;
17353             }
17354           curr_rloc->weight = w;
17355         }
17356       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17357                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17358         {
17359           rloc.is_ip4 = 1;
17360
17361           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17362           rloc.weight = 0;
17363           vec_add1 (lcl_locs, rloc);
17364
17365           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17366           vec_add1 (rmt_locs, rloc);
17367           /* weight saved in rmt loc */
17368           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17369         }
17370       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17371                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17372         {
17373           rloc.is_ip4 = 0;
17374           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17375           rloc.weight = 0;
17376           vec_add1 (lcl_locs, rloc);
17377
17378           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17379           vec_add1 (rmt_locs, rloc);
17380           /* weight saved in rmt loc */
17381           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17382         }
17383       else if (unformat (input, "action %d", &action))
17384         {
17385           ;
17386         }
17387       else
17388         {
17389           clib_warning ("parse error '%U'", format_unformat_error, input);
17390           return -99;
17391         }
17392     }
17393
17394   if (!rmt_eid_set)
17395     {
17396       errmsg ("remote eid addresses not set");
17397       return -99;
17398     }
17399
17400   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17401     {
17402       errmsg ("eid types don't match");
17403       return -99;
17404     }
17405
17406   if (0 == rmt_locs && (u32) ~ 0 == action)
17407     {
17408       errmsg ("action not set for negative mapping");
17409       return -99;
17410     }
17411
17412   /* Construct the API message */
17413   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17414       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17415
17416   mp->is_add = is_add;
17417   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17418   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17419   mp->eid_type = rmt_eid->type;
17420   mp->dp_table = clib_host_to_net_u32 (dp_table);
17421   mp->vni = clib_host_to_net_u32 (vni);
17422   mp->rmt_len = rmt_eid->len;
17423   mp->lcl_len = lcl_eid->len;
17424   mp->action = action;
17425
17426   if (0 != rmt_locs && 0 != lcl_locs)
17427     {
17428       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17429       clib_memcpy (mp->locs, lcl_locs,
17430                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17431
17432       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17433       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17434                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17435     }
17436   vec_free (lcl_locs);
17437   vec_free (rmt_locs);
17438
17439   /* send it... */
17440   S (mp);
17441
17442   /* Wait for a reply... */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 static int
17448 api_one_add_del_map_server (vat_main_t * vam)
17449 {
17450   unformat_input_t *input = vam->input;
17451   vl_api_one_add_del_map_server_t *mp;
17452   u8 is_add = 1;
17453   u8 ipv4_set = 0;
17454   u8 ipv6_set = 0;
17455   ip4_address_t ipv4;
17456   ip6_address_t ipv6;
17457   int ret;
17458
17459   /* Parse args required to build the message */
17460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17461     {
17462       if (unformat (input, "del"))
17463         {
17464           is_add = 0;
17465         }
17466       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17467         {
17468           ipv4_set = 1;
17469         }
17470       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17471         {
17472           ipv6_set = 1;
17473         }
17474       else
17475         break;
17476     }
17477
17478   if (ipv4_set && ipv6_set)
17479     {
17480       errmsg ("both eid v4 and v6 addresses set");
17481       return -99;
17482     }
17483
17484   if (!ipv4_set && !ipv6_set)
17485     {
17486       errmsg ("eid addresses not set");
17487       return -99;
17488     }
17489
17490   /* Construct the API message */
17491   M (ONE_ADD_DEL_MAP_SERVER, mp);
17492
17493   mp->is_add = is_add;
17494   if (ipv6_set)
17495     {
17496       mp->is_ipv6 = 1;
17497       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17498     }
17499   else
17500     {
17501       mp->is_ipv6 = 0;
17502       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17503     }
17504
17505   /* send it... */
17506   S (mp);
17507
17508   /* Wait for a reply... */
17509   W (ret);
17510   return ret;
17511 }
17512
17513 #define api_lisp_add_del_map_server api_one_add_del_map_server
17514
17515 static int
17516 api_one_add_del_map_resolver (vat_main_t * vam)
17517 {
17518   unformat_input_t *input = vam->input;
17519   vl_api_one_add_del_map_resolver_t *mp;
17520   u8 is_add = 1;
17521   u8 ipv4_set = 0;
17522   u8 ipv6_set = 0;
17523   ip4_address_t ipv4;
17524   ip6_address_t ipv6;
17525   int ret;
17526
17527   /* Parse args required to build the message */
17528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17529     {
17530       if (unformat (input, "del"))
17531         {
17532           is_add = 0;
17533         }
17534       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17535         {
17536           ipv4_set = 1;
17537         }
17538       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17539         {
17540           ipv6_set = 1;
17541         }
17542       else
17543         break;
17544     }
17545
17546   if (ipv4_set && ipv6_set)
17547     {
17548       errmsg ("both eid v4 and v6 addresses set");
17549       return -99;
17550     }
17551
17552   if (!ipv4_set && !ipv6_set)
17553     {
17554       errmsg ("eid addresses not set");
17555       return -99;
17556     }
17557
17558   /* Construct the API message */
17559   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17560
17561   mp->is_add = is_add;
17562   if (ipv6_set)
17563     {
17564       mp->is_ipv6 = 1;
17565       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17566     }
17567   else
17568     {
17569       mp->is_ipv6 = 0;
17570       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17571     }
17572
17573   /* send it... */
17574   S (mp);
17575
17576   /* Wait for a reply... */
17577   W (ret);
17578   return ret;
17579 }
17580
17581 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17582
17583 static int
17584 api_lisp_gpe_enable_disable (vat_main_t * vam)
17585 {
17586   unformat_input_t *input = vam->input;
17587   vl_api_gpe_enable_disable_t *mp;
17588   u8 is_set = 0;
17589   u8 is_en = 1;
17590   int ret;
17591
17592   /* Parse args required to build the message */
17593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17594     {
17595       if (unformat (input, "enable"))
17596         {
17597           is_set = 1;
17598           is_en = 1;
17599         }
17600       else if (unformat (input, "disable"))
17601         {
17602           is_set = 1;
17603           is_en = 0;
17604         }
17605       else
17606         break;
17607     }
17608
17609   if (is_set == 0)
17610     {
17611       errmsg ("Value not set");
17612       return -99;
17613     }
17614
17615   /* Construct the API message */
17616   M (GPE_ENABLE_DISABLE, mp);
17617
17618   mp->is_en = is_en;
17619
17620   /* send it... */
17621   S (mp);
17622
17623   /* Wait for a reply... */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 static int
17629 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17630 {
17631   unformat_input_t *input = vam->input;
17632   vl_api_one_rloc_probe_enable_disable_t *mp;
17633   u8 is_set = 0;
17634   u8 is_en = 0;
17635   int ret;
17636
17637   /* Parse args required to build the message */
17638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17639     {
17640       if (unformat (input, "enable"))
17641         {
17642           is_set = 1;
17643           is_en = 1;
17644         }
17645       else if (unformat (input, "disable"))
17646         is_set = 1;
17647       else
17648         break;
17649     }
17650
17651   if (!is_set)
17652     {
17653       errmsg ("Value not set");
17654       return -99;
17655     }
17656
17657   /* Construct the API message */
17658   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17659
17660   mp->is_enabled = is_en;
17661
17662   /* send it... */
17663   S (mp);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17671
17672 static int
17673 api_one_map_register_enable_disable (vat_main_t * vam)
17674 {
17675   unformat_input_t *input = vam->input;
17676   vl_api_one_map_register_enable_disable_t *mp;
17677   u8 is_set = 0;
17678   u8 is_en = 0;
17679   int ret;
17680
17681   /* Parse args required to build the message */
17682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17683     {
17684       if (unformat (input, "enable"))
17685         {
17686           is_set = 1;
17687           is_en = 1;
17688         }
17689       else if (unformat (input, "disable"))
17690         is_set = 1;
17691       else
17692         break;
17693     }
17694
17695   if (!is_set)
17696     {
17697       errmsg ("Value not set");
17698       return -99;
17699     }
17700
17701   /* Construct the API message */
17702   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17703
17704   mp->is_enabled = is_en;
17705
17706   /* send it... */
17707   S (mp);
17708
17709   /* Wait for a reply... */
17710   W (ret);
17711   return ret;
17712 }
17713
17714 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17715
17716 static int
17717 api_one_enable_disable (vat_main_t * vam)
17718 {
17719   unformat_input_t *input = vam->input;
17720   vl_api_one_enable_disable_t *mp;
17721   u8 is_set = 0;
17722   u8 is_en = 0;
17723   int ret;
17724
17725   /* Parse args required to build the message */
17726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17727     {
17728       if (unformat (input, "enable"))
17729         {
17730           is_set = 1;
17731           is_en = 1;
17732         }
17733       else if (unformat (input, "disable"))
17734         {
17735           is_set = 1;
17736         }
17737       else
17738         break;
17739     }
17740
17741   if (!is_set)
17742     {
17743       errmsg ("Value not set");
17744       return -99;
17745     }
17746
17747   /* Construct the API message */
17748   M (ONE_ENABLE_DISABLE, mp);
17749
17750   mp->is_en = is_en;
17751
17752   /* send it... */
17753   S (mp);
17754
17755   /* Wait for a reply... */
17756   W (ret);
17757   return ret;
17758 }
17759
17760 #define api_lisp_enable_disable api_one_enable_disable
17761
17762 static int
17763 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17764 {
17765   unformat_input_t *input = vam->input;
17766   vl_api_one_enable_disable_xtr_mode_t *mp;
17767   u8 is_set = 0;
17768   u8 is_en = 0;
17769   int ret;
17770
17771   /* Parse args required to build the message */
17772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17773     {
17774       if (unformat (input, "enable"))
17775         {
17776           is_set = 1;
17777           is_en = 1;
17778         }
17779       else if (unformat (input, "disable"))
17780         {
17781           is_set = 1;
17782         }
17783       else
17784         break;
17785     }
17786
17787   if (!is_set)
17788     {
17789       errmsg ("Value not set");
17790       return -99;
17791     }
17792
17793   /* Construct the API message */
17794   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17795
17796   mp->is_en = is_en;
17797
17798   /* send it... */
17799   S (mp);
17800
17801   /* Wait for a reply... */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 static int
17807 api_one_show_xtr_mode (vat_main_t * vam)
17808 {
17809   vl_api_one_show_xtr_mode_t *mp;
17810   int ret;
17811
17812   /* Construct the API message */
17813   M (ONE_SHOW_XTR_MODE, mp);
17814
17815   /* send it... */
17816   S (mp);
17817
17818   /* Wait for a reply... */
17819   W (ret);
17820   return ret;
17821 }
17822
17823 static int
17824 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17825 {
17826   unformat_input_t *input = vam->input;
17827   vl_api_one_enable_disable_pitr_mode_t *mp;
17828   u8 is_set = 0;
17829   u8 is_en = 0;
17830   int ret;
17831
17832   /* Parse args required to build the message */
17833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17834     {
17835       if (unformat (input, "enable"))
17836         {
17837           is_set = 1;
17838           is_en = 1;
17839         }
17840       else if (unformat (input, "disable"))
17841         {
17842           is_set = 1;
17843         }
17844       else
17845         break;
17846     }
17847
17848   if (!is_set)
17849     {
17850       errmsg ("Value not set");
17851       return -99;
17852     }
17853
17854   /* Construct the API message */
17855   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17856
17857   mp->is_en = is_en;
17858
17859   /* send it... */
17860   S (mp);
17861
17862   /* Wait for a reply... */
17863   W (ret);
17864   return ret;
17865 }
17866
17867 static int
17868 api_one_show_pitr_mode (vat_main_t * vam)
17869 {
17870   vl_api_one_show_pitr_mode_t *mp;
17871   int ret;
17872
17873   /* Construct the API message */
17874   M (ONE_SHOW_PITR_MODE, mp);
17875
17876   /* send it... */
17877   S (mp);
17878
17879   /* Wait for a reply... */
17880   W (ret);
17881   return ret;
17882 }
17883
17884 static int
17885 api_one_enable_disable_petr_mode (vat_main_t * vam)
17886 {
17887   unformat_input_t *input = vam->input;
17888   vl_api_one_enable_disable_petr_mode_t *mp;
17889   u8 is_set = 0;
17890   u8 is_en = 0;
17891   int ret;
17892
17893   /* Parse args required to build the message */
17894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17895     {
17896       if (unformat (input, "enable"))
17897         {
17898           is_set = 1;
17899           is_en = 1;
17900         }
17901       else if (unformat (input, "disable"))
17902         {
17903           is_set = 1;
17904         }
17905       else
17906         break;
17907     }
17908
17909   if (!is_set)
17910     {
17911       errmsg ("Value not set");
17912       return -99;
17913     }
17914
17915   /* Construct the API message */
17916   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17917
17918   mp->is_en = is_en;
17919
17920   /* send it... */
17921   S (mp);
17922
17923   /* Wait for a reply... */
17924   W (ret);
17925   return ret;
17926 }
17927
17928 static int
17929 api_one_show_petr_mode (vat_main_t * vam)
17930 {
17931   vl_api_one_show_petr_mode_t *mp;
17932   int ret;
17933
17934   /* Construct the API message */
17935   M (ONE_SHOW_PETR_MODE, mp);
17936
17937   /* send it... */
17938   S (mp);
17939
17940   /* Wait for a reply... */
17941   W (ret);
17942   return ret;
17943 }
17944
17945 static int
17946 api_show_one_map_register_state (vat_main_t * vam)
17947 {
17948   vl_api_show_one_map_register_state_t *mp;
17949   int ret;
17950
17951   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17952
17953   /* send */
17954   S (mp);
17955
17956   /* wait for reply */
17957   W (ret);
17958   return ret;
17959 }
17960
17961 #define api_show_lisp_map_register_state api_show_one_map_register_state
17962
17963 static int
17964 api_show_one_rloc_probe_state (vat_main_t * vam)
17965 {
17966   vl_api_show_one_rloc_probe_state_t *mp;
17967   int ret;
17968
17969   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17970
17971   /* send */
17972   S (mp);
17973
17974   /* wait for reply */
17975   W (ret);
17976   return ret;
17977 }
17978
17979 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17980
17981 static int
17982 api_one_add_del_ndp_entry (vat_main_t * vam)
17983 {
17984   vl_api_one_add_del_ndp_entry_t *mp;
17985   unformat_input_t *input = vam->input;
17986   u8 is_add = 1;
17987   u8 mac_set = 0;
17988   u8 bd_set = 0;
17989   u8 ip_set = 0;
17990   u8 mac[6] = { 0, };
17991   u8 ip6[16] = { 0, };
17992   u32 bd = ~0;
17993   int ret;
17994
17995   /* Parse args required to build the message */
17996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17997     {
17998       if (unformat (input, "del"))
17999         is_add = 0;
18000       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18001         mac_set = 1;
18002       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
18003         ip_set = 1;
18004       else if (unformat (input, "bd %d", &bd))
18005         bd_set = 1;
18006       else
18007         {
18008           errmsg ("parse error '%U'", format_unformat_error, input);
18009           return -99;
18010         }
18011     }
18012
18013   if (!bd_set || !ip_set || (!mac_set && is_add))
18014     {
18015       errmsg ("Missing BD, IP or MAC!");
18016       return -99;
18017     }
18018
18019   M (ONE_ADD_DEL_NDP_ENTRY, mp);
18020   mp->is_add = is_add;
18021   clib_memcpy (mp->mac, mac, 6);
18022   mp->bd = clib_host_to_net_u32 (bd);
18023   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
18024
18025   /* send */
18026   S (mp);
18027
18028   /* wait for reply */
18029   W (ret);
18030   return ret;
18031 }
18032
18033 static int
18034 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18035 {
18036   vl_api_one_add_del_l2_arp_entry_t *mp;
18037   unformat_input_t *input = vam->input;
18038   u8 is_add = 1;
18039   u8 mac_set = 0;
18040   u8 bd_set = 0;
18041   u8 ip_set = 0;
18042   u8 mac[6] = { 0, };
18043   u32 ip4 = 0, bd = ~0;
18044   int ret;
18045
18046   /* Parse args required to build the message */
18047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18048     {
18049       if (unformat (input, "del"))
18050         is_add = 0;
18051       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18052         mac_set = 1;
18053       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18054         ip_set = 1;
18055       else if (unformat (input, "bd %d", &bd))
18056         bd_set = 1;
18057       else
18058         {
18059           errmsg ("parse error '%U'", format_unformat_error, input);
18060           return -99;
18061         }
18062     }
18063
18064   if (!bd_set || !ip_set || (!mac_set && is_add))
18065     {
18066       errmsg ("Missing BD, IP or MAC!");
18067       return -99;
18068     }
18069
18070   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18071   mp->is_add = is_add;
18072   clib_memcpy (mp->mac, mac, 6);
18073   mp->bd = clib_host_to_net_u32 (bd);
18074   mp->ip4 = ip4;
18075
18076   /* send */
18077   S (mp);
18078
18079   /* wait for reply */
18080   W (ret);
18081   return ret;
18082 }
18083
18084 static int
18085 api_one_ndp_bd_get (vat_main_t * vam)
18086 {
18087   vl_api_one_ndp_bd_get_t *mp;
18088   int ret;
18089
18090   M (ONE_NDP_BD_GET, mp);
18091
18092   /* send */
18093   S (mp);
18094
18095   /* wait for reply */
18096   W (ret);
18097   return ret;
18098 }
18099
18100 static int
18101 api_one_ndp_entries_get (vat_main_t * vam)
18102 {
18103   vl_api_one_ndp_entries_get_t *mp;
18104   unformat_input_t *input = vam->input;
18105   u8 bd_set = 0;
18106   u32 bd = ~0;
18107   int ret;
18108
18109   /* Parse args required to build the message */
18110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18111     {
18112       if (unformat (input, "bd %d", &bd))
18113         bd_set = 1;
18114       else
18115         {
18116           errmsg ("parse error '%U'", format_unformat_error, input);
18117           return -99;
18118         }
18119     }
18120
18121   if (!bd_set)
18122     {
18123       errmsg ("Expected bridge domain!");
18124       return -99;
18125     }
18126
18127   M (ONE_NDP_ENTRIES_GET, mp);
18128   mp->bd = clib_host_to_net_u32 (bd);
18129
18130   /* send */
18131   S (mp);
18132
18133   /* wait for reply */
18134   W (ret);
18135   return ret;
18136 }
18137
18138 static int
18139 api_one_l2_arp_bd_get (vat_main_t * vam)
18140 {
18141   vl_api_one_l2_arp_bd_get_t *mp;
18142   int ret;
18143
18144   M (ONE_L2_ARP_BD_GET, mp);
18145
18146   /* send */
18147   S (mp);
18148
18149   /* wait for reply */
18150   W (ret);
18151   return ret;
18152 }
18153
18154 static int
18155 api_one_l2_arp_entries_get (vat_main_t * vam)
18156 {
18157   vl_api_one_l2_arp_entries_get_t *mp;
18158   unformat_input_t *input = vam->input;
18159   u8 bd_set = 0;
18160   u32 bd = ~0;
18161   int ret;
18162
18163   /* Parse args required to build the message */
18164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (input, "bd %d", &bd))
18167         bd_set = 1;
18168       else
18169         {
18170           errmsg ("parse error '%U'", format_unformat_error, input);
18171           return -99;
18172         }
18173     }
18174
18175   if (!bd_set)
18176     {
18177       errmsg ("Expected bridge domain!");
18178       return -99;
18179     }
18180
18181   M (ONE_L2_ARP_ENTRIES_GET, mp);
18182   mp->bd = clib_host_to_net_u32 (bd);
18183
18184   /* send */
18185   S (mp);
18186
18187   /* wait for reply */
18188   W (ret);
18189   return ret;
18190 }
18191
18192 static int
18193 api_one_stats_enable_disable (vat_main_t * vam)
18194 {
18195   vl_api_one_stats_enable_disable_t *mp;
18196   unformat_input_t *input = vam->input;
18197   u8 is_set = 0;
18198   u8 is_en = 0;
18199   int ret;
18200
18201   /* Parse args required to build the message */
18202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18203     {
18204       if (unformat (input, "enable"))
18205         {
18206           is_set = 1;
18207           is_en = 1;
18208         }
18209       else if (unformat (input, "disable"))
18210         {
18211           is_set = 1;
18212         }
18213       else
18214         break;
18215     }
18216
18217   if (!is_set)
18218     {
18219       errmsg ("Value not set");
18220       return -99;
18221     }
18222
18223   M (ONE_STATS_ENABLE_DISABLE, mp);
18224   mp->is_en = is_en;
18225
18226   /* send */
18227   S (mp);
18228
18229   /* wait for reply */
18230   W (ret);
18231   return ret;
18232 }
18233
18234 static int
18235 api_show_one_stats_enable_disable (vat_main_t * vam)
18236 {
18237   vl_api_show_one_stats_enable_disable_t *mp;
18238   int ret;
18239
18240   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18241
18242   /* send */
18243   S (mp);
18244
18245   /* wait for reply */
18246   W (ret);
18247   return ret;
18248 }
18249
18250 static int
18251 api_show_one_map_request_mode (vat_main_t * vam)
18252 {
18253   vl_api_show_one_map_request_mode_t *mp;
18254   int ret;
18255
18256   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18257
18258   /* send */
18259   S (mp);
18260
18261   /* wait for reply */
18262   W (ret);
18263   return ret;
18264 }
18265
18266 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18267
18268 static int
18269 api_one_map_request_mode (vat_main_t * vam)
18270 {
18271   unformat_input_t *input = vam->input;
18272   vl_api_one_map_request_mode_t *mp;
18273   u8 mode = 0;
18274   int ret;
18275
18276   /* Parse args required to build the message */
18277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18278     {
18279       if (unformat (input, "dst-only"))
18280         mode = 0;
18281       else if (unformat (input, "src-dst"))
18282         mode = 1;
18283       else
18284         {
18285           errmsg ("parse error '%U'", format_unformat_error, input);
18286           return -99;
18287         }
18288     }
18289
18290   M (ONE_MAP_REQUEST_MODE, mp);
18291
18292   mp->mode = mode;
18293
18294   /* send */
18295   S (mp);
18296
18297   /* wait for reply */
18298   W (ret);
18299   return ret;
18300 }
18301
18302 #define api_lisp_map_request_mode api_one_map_request_mode
18303
18304 /**
18305  * Enable/disable ONE proxy ITR.
18306  *
18307  * @param vam vpp API test context
18308  * @return return code
18309  */
18310 static int
18311 api_one_pitr_set_locator_set (vat_main_t * vam)
18312 {
18313   u8 ls_name_set = 0;
18314   unformat_input_t *input = vam->input;
18315   vl_api_one_pitr_set_locator_set_t *mp;
18316   u8 is_add = 1;
18317   u8 *ls_name = 0;
18318   int ret;
18319
18320   /* Parse args required to build the message */
18321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18322     {
18323       if (unformat (input, "del"))
18324         is_add = 0;
18325       else if (unformat (input, "locator-set %s", &ls_name))
18326         ls_name_set = 1;
18327       else
18328         {
18329           errmsg ("parse error '%U'", format_unformat_error, input);
18330           return -99;
18331         }
18332     }
18333
18334   if (!ls_name_set)
18335     {
18336       errmsg ("locator-set name not set!");
18337       return -99;
18338     }
18339
18340   M (ONE_PITR_SET_LOCATOR_SET, mp);
18341
18342   mp->is_add = is_add;
18343   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18344   vec_free (ls_name);
18345
18346   /* send */
18347   S (mp);
18348
18349   /* wait for reply */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18355
18356 static int
18357 api_one_nsh_set_locator_set (vat_main_t * vam)
18358 {
18359   u8 ls_name_set = 0;
18360   unformat_input_t *input = vam->input;
18361   vl_api_one_nsh_set_locator_set_t *mp;
18362   u8 is_add = 1;
18363   u8 *ls_name = 0;
18364   int ret;
18365
18366   /* Parse args required to build the message */
18367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18368     {
18369       if (unformat (input, "del"))
18370         is_add = 0;
18371       else if (unformat (input, "ls %s", &ls_name))
18372         ls_name_set = 1;
18373       else
18374         {
18375           errmsg ("parse error '%U'", format_unformat_error, input);
18376           return -99;
18377         }
18378     }
18379
18380   if (!ls_name_set && is_add)
18381     {
18382       errmsg ("locator-set name not set!");
18383       return -99;
18384     }
18385
18386   M (ONE_NSH_SET_LOCATOR_SET, mp);
18387
18388   mp->is_add = is_add;
18389   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18390   vec_free (ls_name);
18391
18392   /* send */
18393   S (mp);
18394
18395   /* wait for reply */
18396   W (ret);
18397   return ret;
18398 }
18399
18400 static int
18401 api_show_one_pitr (vat_main_t * vam)
18402 {
18403   vl_api_show_one_pitr_t *mp;
18404   int ret;
18405
18406   if (!vam->json_output)
18407     {
18408       print (vam->ofp, "%=20s", "lisp status:");
18409     }
18410
18411   M (SHOW_ONE_PITR, mp);
18412   /* send it... */
18413   S (mp);
18414
18415   /* Wait for a reply... */
18416   W (ret);
18417   return ret;
18418 }
18419
18420 #define api_show_lisp_pitr api_show_one_pitr
18421
18422 static int
18423 api_one_use_petr (vat_main_t * vam)
18424 {
18425   unformat_input_t *input = vam->input;
18426   vl_api_one_use_petr_t *mp;
18427   u8 is_add = 0;
18428   ip_address_t ip;
18429   int ret;
18430
18431   clib_memset (&ip, 0, sizeof (ip));
18432
18433   /* Parse args required to build the message */
18434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18435     {
18436       if (unformat (input, "disable"))
18437         is_add = 0;
18438       else
18439         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18440         {
18441           is_add = 1;
18442           ip_addr_version (&ip) = IP4;
18443         }
18444       else
18445         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18446         {
18447           is_add = 1;
18448           ip_addr_version (&ip) = IP6;
18449         }
18450       else
18451         {
18452           errmsg ("parse error '%U'", format_unformat_error, input);
18453           return -99;
18454         }
18455     }
18456
18457   M (ONE_USE_PETR, mp);
18458
18459   mp->is_add = is_add;
18460   if (is_add)
18461     {
18462       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18463       if (mp->is_ip4)
18464         clib_memcpy (mp->address, &ip, 4);
18465       else
18466         clib_memcpy (mp->address, &ip, 16);
18467     }
18468
18469   /* send */
18470   S (mp);
18471
18472   /* wait for reply */
18473   W (ret);
18474   return ret;
18475 }
18476
18477 #define api_lisp_use_petr api_one_use_petr
18478
18479 static int
18480 api_show_one_nsh_mapping (vat_main_t * vam)
18481 {
18482   vl_api_show_one_use_petr_t *mp;
18483   int ret;
18484
18485   if (!vam->json_output)
18486     {
18487       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18488     }
18489
18490   M (SHOW_ONE_NSH_MAPPING, mp);
18491   /* send it... */
18492   S (mp);
18493
18494   /* Wait for a reply... */
18495   W (ret);
18496   return ret;
18497 }
18498
18499 static int
18500 api_show_one_use_petr (vat_main_t * vam)
18501 {
18502   vl_api_show_one_use_petr_t *mp;
18503   int ret;
18504
18505   if (!vam->json_output)
18506     {
18507       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18508     }
18509
18510   M (SHOW_ONE_USE_PETR, mp);
18511   /* send it... */
18512   S (mp);
18513
18514   /* Wait for a reply... */
18515   W (ret);
18516   return ret;
18517 }
18518
18519 #define api_show_lisp_use_petr api_show_one_use_petr
18520
18521 /**
18522  * Add/delete mapping between vni and vrf
18523  */
18524 static int
18525 api_one_eid_table_add_del_map (vat_main_t * vam)
18526 {
18527   unformat_input_t *input = vam->input;
18528   vl_api_one_eid_table_add_del_map_t *mp;
18529   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18530   u32 vni, vrf, bd_index;
18531   int ret;
18532
18533   /* Parse args required to build the message */
18534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18535     {
18536       if (unformat (input, "del"))
18537         is_add = 0;
18538       else if (unformat (input, "vrf %d", &vrf))
18539         vrf_set = 1;
18540       else if (unformat (input, "bd_index %d", &bd_index))
18541         bd_index_set = 1;
18542       else if (unformat (input, "vni %d", &vni))
18543         vni_set = 1;
18544       else
18545         break;
18546     }
18547
18548   if (!vni_set || (!vrf_set && !bd_index_set))
18549     {
18550       errmsg ("missing arguments!");
18551       return -99;
18552     }
18553
18554   if (vrf_set && bd_index_set)
18555     {
18556       errmsg ("error: both vrf and bd entered!");
18557       return -99;
18558     }
18559
18560   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18561
18562   mp->is_add = is_add;
18563   mp->vni = htonl (vni);
18564   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18565   mp->is_l2 = bd_index_set;
18566
18567   /* send */
18568   S (mp);
18569
18570   /* wait for reply */
18571   W (ret);
18572   return ret;
18573 }
18574
18575 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18576
18577 uword
18578 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18579 {
18580   u32 *action = va_arg (*args, u32 *);
18581   u8 *s = 0;
18582
18583   if (unformat (input, "%s", &s))
18584     {
18585       if (!strcmp ((char *) s, "no-action"))
18586         action[0] = 0;
18587       else if (!strcmp ((char *) s, "natively-forward"))
18588         action[0] = 1;
18589       else if (!strcmp ((char *) s, "send-map-request"))
18590         action[0] = 2;
18591       else if (!strcmp ((char *) s, "drop"))
18592         action[0] = 3;
18593       else
18594         {
18595           clib_warning ("invalid action: '%s'", s);
18596           action[0] = 3;
18597         }
18598     }
18599   else
18600     return 0;
18601
18602   vec_free (s);
18603   return 1;
18604 }
18605
18606 /**
18607  * Add/del remote mapping to/from ONE control plane
18608  *
18609  * @param vam vpp API test context
18610  * @return return code
18611  */
18612 static int
18613 api_one_add_del_remote_mapping (vat_main_t * vam)
18614 {
18615   unformat_input_t *input = vam->input;
18616   vl_api_one_add_del_remote_mapping_t *mp;
18617   u32 vni = 0;
18618   lisp_eid_vat_t _eid, *eid = &_eid;
18619   lisp_eid_vat_t _seid, *seid = &_seid;
18620   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18621   u32 action = ~0, p, w, data_len;
18622   ip4_address_t rloc4;
18623   ip6_address_t rloc6;
18624   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18625   int ret;
18626
18627   clib_memset (&rloc, 0, sizeof (rloc));
18628
18629   /* Parse args required to build the message */
18630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18631     {
18632       if (unformat (input, "del-all"))
18633         {
18634           del_all = 1;
18635         }
18636       else if (unformat (input, "del"))
18637         {
18638           is_add = 0;
18639         }
18640       else if (unformat (input, "add"))
18641         {
18642           is_add = 1;
18643         }
18644       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18645         {
18646           eid_set = 1;
18647         }
18648       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18649         {
18650           seid_set = 1;
18651         }
18652       else if (unformat (input, "vni %d", &vni))
18653         {
18654           ;
18655         }
18656       else if (unformat (input, "p %d w %d", &p, &w))
18657         {
18658           if (!curr_rloc)
18659             {
18660               errmsg ("No RLOC configured for setting priority/weight!");
18661               return -99;
18662             }
18663           curr_rloc->priority = p;
18664           curr_rloc->weight = w;
18665         }
18666       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18667         {
18668           rloc.is_ip4 = 1;
18669           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18670           vec_add1 (rlocs, rloc);
18671           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18672         }
18673       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18674         {
18675           rloc.is_ip4 = 0;
18676           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18677           vec_add1 (rlocs, rloc);
18678           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18679         }
18680       else if (unformat (input, "action %U",
18681                          unformat_negative_mapping_action, &action))
18682         {
18683           ;
18684         }
18685       else
18686         {
18687           clib_warning ("parse error '%U'", format_unformat_error, input);
18688           return -99;
18689         }
18690     }
18691
18692   if (0 == eid_set)
18693     {
18694       errmsg ("missing params!");
18695       return -99;
18696     }
18697
18698   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18699     {
18700       errmsg ("no action set for negative map-reply!");
18701       return -99;
18702     }
18703
18704   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18705
18706   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18707   mp->is_add = is_add;
18708   mp->vni = htonl (vni);
18709   mp->action = (u8) action;
18710   mp->is_src_dst = seid_set;
18711   mp->eid_len = eid->len;
18712   mp->seid_len = seid->len;
18713   mp->del_all = del_all;
18714   mp->eid_type = eid->type;
18715   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18716   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18717
18718   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18719   clib_memcpy (mp->rlocs, rlocs, data_len);
18720   vec_free (rlocs);
18721
18722   /* send it... */
18723   S (mp);
18724
18725   /* Wait for a reply... */
18726   W (ret);
18727   return ret;
18728 }
18729
18730 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18731
18732 /**
18733  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18734  * forwarding entries in data-plane accordingly.
18735  *
18736  * @param vam vpp API test context
18737  * @return return code
18738  */
18739 static int
18740 api_one_add_del_adjacency (vat_main_t * vam)
18741 {
18742   unformat_input_t *input = vam->input;
18743   vl_api_one_add_del_adjacency_t *mp;
18744   u32 vni = 0;
18745   ip4_address_t leid4, reid4;
18746   ip6_address_t leid6, reid6;
18747   u8 reid_mac[6] = { 0 };
18748   u8 leid_mac[6] = { 0 };
18749   u8 reid_type, leid_type;
18750   u32 leid_len = 0, reid_len = 0, len;
18751   u8 is_add = 1;
18752   int ret;
18753
18754   leid_type = reid_type = (u8) ~ 0;
18755
18756   /* Parse args required to build the message */
18757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18758     {
18759       if (unformat (input, "del"))
18760         {
18761           is_add = 0;
18762         }
18763       else if (unformat (input, "add"))
18764         {
18765           is_add = 1;
18766         }
18767       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18768                          &reid4, &len))
18769         {
18770           reid_type = 0;        /* ipv4 */
18771           reid_len = len;
18772         }
18773       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18774                          &reid6, &len))
18775         {
18776           reid_type = 1;        /* ipv6 */
18777           reid_len = len;
18778         }
18779       else if (unformat (input, "reid %U", unformat_ethernet_address,
18780                          reid_mac))
18781         {
18782           reid_type = 2;        /* mac */
18783         }
18784       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18785                          &leid4, &len))
18786         {
18787           leid_type = 0;        /* ipv4 */
18788           leid_len = len;
18789         }
18790       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18791                          &leid6, &len))
18792         {
18793           leid_type = 1;        /* ipv6 */
18794           leid_len = len;
18795         }
18796       else if (unformat (input, "leid %U", unformat_ethernet_address,
18797                          leid_mac))
18798         {
18799           leid_type = 2;        /* mac */
18800         }
18801       else if (unformat (input, "vni %d", &vni))
18802         {
18803           ;
18804         }
18805       else
18806         {
18807           errmsg ("parse error '%U'", format_unformat_error, input);
18808           return -99;
18809         }
18810     }
18811
18812   if ((u8) ~ 0 == reid_type)
18813     {
18814       errmsg ("missing params!");
18815       return -99;
18816     }
18817
18818   if (leid_type != reid_type)
18819     {
18820       errmsg ("remote and local EIDs are of different types!");
18821       return -99;
18822     }
18823
18824   M (ONE_ADD_DEL_ADJACENCY, mp);
18825   mp->is_add = is_add;
18826   mp->vni = htonl (vni);
18827   mp->leid_len = leid_len;
18828   mp->reid_len = reid_len;
18829   mp->eid_type = reid_type;
18830
18831   switch (mp->eid_type)
18832     {
18833     case 0:
18834       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18835       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18836       break;
18837     case 1:
18838       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18839       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18840       break;
18841     case 2:
18842       clib_memcpy (mp->leid, leid_mac, 6);
18843       clib_memcpy (mp->reid, reid_mac, 6);
18844       break;
18845     default:
18846       errmsg ("unknown EID type %d!", mp->eid_type);
18847       return 0;
18848     }
18849
18850   /* send it... */
18851   S (mp);
18852
18853   /* Wait for a reply... */
18854   W (ret);
18855   return ret;
18856 }
18857
18858 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18859
18860 uword
18861 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18862 {
18863   u32 *mode = va_arg (*args, u32 *);
18864
18865   if (unformat (input, "lisp"))
18866     *mode = 0;
18867   else if (unformat (input, "vxlan"))
18868     *mode = 1;
18869   else
18870     return 0;
18871
18872   return 1;
18873 }
18874
18875 static int
18876 api_gpe_get_encap_mode (vat_main_t * vam)
18877 {
18878   vl_api_gpe_get_encap_mode_t *mp;
18879   int ret;
18880
18881   /* Construct the API message */
18882   M (GPE_GET_ENCAP_MODE, mp);
18883
18884   /* send it... */
18885   S (mp);
18886
18887   /* Wait for a reply... */
18888   W (ret);
18889   return ret;
18890 }
18891
18892 static int
18893 api_gpe_set_encap_mode (vat_main_t * vam)
18894 {
18895   unformat_input_t *input = vam->input;
18896   vl_api_gpe_set_encap_mode_t *mp;
18897   int ret;
18898   u32 mode = 0;
18899
18900   /* Parse args required to build the message */
18901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18902     {
18903       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18904         ;
18905       else
18906         break;
18907     }
18908
18909   /* Construct the API message */
18910   M (GPE_SET_ENCAP_MODE, mp);
18911
18912   mp->mode = mode;
18913
18914   /* send it... */
18915   S (mp);
18916
18917   /* Wait for a reply... */
18918   W (ret);
18919   return ret;
18920 }
18921
18922 static int
18923 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18924 {
18925   unformat_input_t *input = vam->input;
18926   vl_api_gpe_add_del_iface_t *mp;
18927   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18928   u32 dp_table = 0, vni = 0;
18929   int ret;
18930
18931   /* Parse args required to build the message */
18932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18933     {
18934       if (unformat (input, "up"))
18935         {
18936           action_set = 1;
18937           is_add = 1;
18938         }
18939       else if (unformat (input, "down"))
18940         {
18941           action_set = 1;
18942           is_add = 0;
18943         }
18944       else if (unformat (input, "table_id %d", &dp_table))
18945         {
18946           dp_table_set = 1;
18947         }
18948       else if (unformat (input, "bd_id %d", &dp_table))
18949         {
18950           dp_table_set = 1;
18951           is_l2 = 1;
18952         }
18953       else if (unformat (input, "vni %d", &vni))
18954         {
18955           vni_set = 1;
18956         }
18957       else
18958         break;
18959     }
18960
18961   if (action_set == 0)
18962     {
18963       errmsg ("Action not set");
18964       return -99;
18965     }
18966   if (dp_table_set == 0 || vni_set == 0)
18967     {
18968       errmsg ("vni and dp_table must be set");
18969       return -99;
18970     }
18971
18972   /* Construct the API message */
18973   M (GPE_ADD_DEL_IFACE, mp);
18974
18975   mp->is_add = is_add;
18976   mp->dp_table = clib_host_to_net_u32 (dp_table);
18977   mp->is_l2 = is_l2;
18978   mp->vni = clib_host_to_net_u32 (vni);
18979
18980   /* send it... */
18981   S (mp);
18982
18983   /* Wait for a reply... */
18984   W (ret);
18985   return ret;
18986 }
18987
18988 static int
18989 api_one_map_register_fallback_threshold (vat_main_t * vam)
18990 {
18991   unformat_input_t *input = vam->input;
18992   vl_api_one_map_register_fallback_threshold_t *mp;
18993   u32 value = 0;
18994   u8 is_set = 0;
18995   int ret;
18996
18997   /* Parse args required to build the message */
18998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18999     {
19000       if (unformat (input, "%u", &value))
19001         is_set = 1;
19002       else
19003         {
19004           clib_warning ("parse error '%U'", format_unformat_error, input);
19005           return -99;
19006         }
19007     }
19008
19009   if (!is_set)
19010     {
19011       errmsg ("fallback threshold value is missing!");
19012       return -99;
19013     }
19014
19015   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19016   mp->value = clib_host_to_net_u32 (value);
19017
19018   /* send it... */
19019   S (mp);
19020
19021   /* Wait for a reply... */
19022   W (ret);
19023   return ret;
19024 }
19025
19026 static int
19027 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19028 {
19029   vl_api_show_one_map_register_fallback_threshold_t *mp;
19030   int ret;
19031
19032   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19033
19034   /* send it... */
19035   S (mp);
19036
19037   /* Wait for a reply... */
19038   W (ret);
19039   return ret;
19040 }
19041
19042 uword
19043 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19044 {
19045   u32 *proto = va_arg (*args, u32 *);
19046
19047   if (unformat (input, "udp"))
19048     *proto = 1;
19049   else if (unformat (input, "api"))
19050     *proto = 2;
19051   else
19052     return 0;
19053
19054   return 1;
19055 }
19056
19057 static int
19058 api_one_set_transport_protocol (vat_main_t * vam)
19059 {
19060   unformat_input_t *input = vam->input;
19061   vl_api_one_set_transport_protocol_t *mp;
19062   u8 is_set = 0;
19063   u32 protocol = 0;
19064   int ret;
19065
19066   /* Parse args required to build the message */
19067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19068     {
19069       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19070         is_set = 1;
19071       else
19072         {
19073           clib_warning ("parse error '%U'", format_unformat_error, input);
19074           return -99;
19075         }
19076     }
19077
19078   if (!is_set)
19079     {
19080       errmsg ("Transport protocol missing!");
19081       return -99;
19082     }
19083
19084   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19085   mp->protocol = (u8) protocol;
19086
19087   /* send it... */
19088   S (mp);
19089
19090   /* Wait for a reply... */
19091   W (ret);
19092   return ret;
19093 }
19094
19095 static int
19096 api_one_get_transport_protocol (vat_main_t * vam)
19097 {
19098   vl_api_one_get_transport_protocol_t *mp;
19099   int ret;
19100
19101   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19102
19103   /* send it... */
19104   S (mp);
19105
19106   /* Wait for a reply... */
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static int
19112 api_one_map_register_set_ttl (vat_main_t * vam)
19113 {
19114   unformat_input_t *input = vam->input;
19115   vl_api_one_map_register_set_ttl_t *mp;
19116   u32 ttl = 0;
19117   u8 is_set = 0;
19118   int ret;
19119
19120   /* Parse args required to build the message */
19121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19122     {
19123       if (unformat (input, "%u", &ttl))
19124         is_set = 1;
19125       else
19126         {
19127           clib_warning ("parse error '%U'", format_unformat_error, input);
19128           return -99;
19129         }
19130     }
19131
19132   if (!is_set)
19133     {
19134       errmsg ("TTL value missing!");
19135       return -99;
19136     }
19137
19138   M (ONE_MAP_REGISTER_SET_TTL, mp);
19139   mp->ttl = clib_host_to_net_u32 (ttl);
19140
19141   /* send it... */
19142   S (mp);
19143
19144   /* Wait for a reply... */
19145   W (ret);
19146   return ret;
19147 }
19148
19149 static int
19150 api_show_one_map_register_ttl (vat_main_t * vam)
19151 {
19152   vl_api_show_one_map_register_ttl_t *mp;
19153   int ret;
19154
19155   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19156
19157   /* send it... */
19158   S (mp);
19159
19160   /* Wait for a reply... */
19161   W (ret);
19162   return ret;
19163 }
19164
19165 /**
19166  * Add/del map request itr rlocs from ONE control plane and updates
19167  *
19168  * @param vam vpp API test context
19169  * @return return code
19170  */
19171 static int
19172 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19173 {
19174   unformat_input_t *input = vam->input;
19175   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19176   u8 *locator_set_name = 0;
19177   u8 locator_set_name_set = 0;
19178   u8 is_add = 1;
19179   int ret;
19180
19181   /* Parse args required to build the message */
19182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19183     {
19184       if (unformat (input, "del"))
19185         {
19186           is_add = 0;
19187         }
19188       else if (unformat (input, "%_%v%_", &locator_set_name))
19189         {
19190           locator_set_name_set = 1;
19191         }
19192       else
19193         {
19194           clib_warning ("parse error '%U'", format_unformat_error, input);
19195           return -99;
19196         }
19197     }
19198
19199   if (is_add && !locator_set_name_set)
19200     {
19201       errmsg ("itr-rloc is not set!");
19202       return -99;
19203     }
19204
19205   if (is_add && vec_len (locator_set_name) > 64)
19206     {
19207       errmsg ("itr-rloc locator-set name too long");
19208       vec_free (locator_set_name);
19209       return -99;
19210     }
19211
19212   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19213   mp->is_add = is_add;
19214   if (is_add)
19215     {
19216       clib_memcpy (mp->locator_set_name, locator_set_name,
19217                    vec_len (locator_set_name));
19218     }
19219   else
19220     {
19221       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19222     }
19223   vec_free (locator_set_name);
19224
19225   /* send it... */
19226   S (mp);
19227
19228   /* Wait for a reply... */
19229   W (ret);
19230   return ret;
19231 }
19232
19233 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19234
19235 static int
19236 api_one_locator_dump (vat_main_t * vam)
19237 {
19238   unformat_input_t *input = vam->input;
19239   vl_api_one_locator_dump_t *mp;
19240   vl_api_control_ping_t *mp_ping;
19241   u8 is_index_set = 0, is_name_set = 0;
19242   u8 *ls_name = 0;
19243   u32 ls_index = ~0;
19244   int ret;
19245
19246   /* Parse args required to build the message */
19247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19248     {
19249       if (unformat (input, "ls_name %_%v%_", &ls_name))
19250         {
19251           is_name_set = 1;
19252         }
19253       else if (unformat (input, "ls_index %d", &ls_index))
19254         {
19255           is_index_set = 1;
19256         }
19257       else
19258         {
19259           errmsg ("parse error '%U'", format_unformat_error, input);
19260           return -99;
19261         }
19262     }
19263
19264   if (!is_index_set && !is_name_set)
19265     {
19266       errmsg ("error: expected one of index or name!");
19267       return -99;
19268     }
19269
19270   if (is_index_set && is_name_set)
19271     {
19272       errmsg ("error: only one param expected!");
19273       return -99;
19274     }
19275
19276   if (vec_len (ls_name) > 62)
19277     {
19278       errmsg ("error: locator set name too long!");
19279       return -99;
19280     }
19281
19282   if (!vam->json_output)
19283     {
19284       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19285     }
19286
19287   M (ONE_LOCATOR_DUMP, mp);
19288   mp->is_index_set = is_index_set;
19289
19290   if (is_index_set)
19291     mp->ls_index = clib_host_to_net_u32 (ls_index);
19292   else
19293     {
19294       vec_add1 (ls_name, 0);
19295       strncpy ((char *) mp->ls_name, (char *) ls_name,
19296                sizeof (mp->ls_name) - 1);
19297     }
19298
19299   /* send it... */
19300   S (mp);
19301
19302   /* Use a control ping for synchronization */
19303   MPING (CONTROL_PING, mp_ping);
19304   S (mp_ping);
19305
19306   /* Wait for a reply... */
19307   W (ret);
19308   return ret;
19309 }
19310
19311 #define api_lisp_locator_dump api_one_locator_dump
19312
19313 static int
19314 api_one_locator_set_dump (vat_main_t * vam)
19315 {
19316   vl_api_one_locator_set_dump_t *mp;
19317   vl_api_control_ping_t *mp_ping;
19318   unformat_input_t *input = vam->input;
19319   u8 filter = 0;
19320   int ret;
19321
19322   /* Parse args required to build the message */
19323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19324     {
19325       if (unformat (input, "local"))
19326         {
19327           filter = 1;
19328         }
19329       else if (unformat (input, "remote"))
19330         {
19331           filter = 2;
19332         }
19333       else
19334         {
19335           errmsg ("parse error '%U'", format_unformat_error, input);
19336           return -99;
19337         }
19338     }
19339
19340   if (!vam->json_output)
19341     {
19342       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19343     }
19344
19345   M (ONE_LOCATOR_SET_DUMP, mp);
19346
19347   mp->filter = filter;
19348
19349   /* send it... */
19350   S (mp);
19351
19352   /* Use a control ping for synchronization */
19353   MPING (CONTROL_PING, mp_ping);
19354   S (mp_ping);
19355
19356   /* Wait for a reply... */
19357   W (ret);
19358   return ret;
19359 }
19360
19361 #define api_lisp_locator_set_dump api_one_locator_set_dump
19362
19363 static int
19364 api_one_eid_table_map_dump (vat_main_t * vam)
19365 {
19366   u8 is_l2 = 0;
19367   u8 mode_set = 0;
19368   unformat_input_t *input = vam->input;
19369   vl_api_one_eid_table_map_dump_t *mp;
19370   vl_api_control_ping_t *mp_ping;
19371   int ret;
19372
19373   /* Parse args required to build the message */
19374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19375     {
19376       if (unformat (input, "l2"))
19377         {
19378           is_l2 = 1;
19379           mode_set = 1;
19380         }
19381       else if (unformat (input, "l3"))
19382         {
19383           is_l2 = 0;
19384           mode_set = 1;
19385         }
19386       else
19387         {
19388           errmsg ("parse error '%U'", format_unformat_error, input);
19389           return -99;
19390         }
19391     }
19392
19393   if (!mode_set)
19394     {
19395       errmsg ("expected one of 'l2' or 'l3' parameter!");
19396       return -99;
19397     }
19398
19399   if (!vam->json_output)
19400     {
19401       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19402     }
19403
19404   M (ONE_EID_TABLE_MAP_DUMP, mp);
19405   mp->is_l2 = is_l2;
19406
19407   /* send it... */
19408   S (mp);
19409
19410   /* Use a control ping for synchronization */
19411   MPING (CONTROL_PING, mp_ping);
19412   S (mp_ping);
19413
19414   /* Wait for a reply... */
19415   W (ret);
19416   return ret;
19417 }
19418
19419 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19420
19421 static int
19422 api_one_eid_table_vni_dump (vat_main_t * vam)
19423 {
19424   vl_api_one_eid_table_vni_dump_t *mp;
19425   vl_api_control_ping_t *mp_ping;
19426   int ret;
19427
19428   if (!vam->json_output)
19429     {
19430       print (vam->ofp, "VNI");
19431     }
19432
19433   M (ONE_EID_TABLE_VNI_DUMP, mp);
19434
19435   /* send it... */
19436   S (mp);
19437
19438   /* Use a control ping for synchronization */
19439   MPING (CONTROL_PING, mp_ping);
19440   S (mp_ping);
19441
19442   /* Wait for a reply... */
19443   W (ret);
19444   return ret;
19445 }
19446
19447 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19448
19449 static int
19450 api_one_eid_table_dump (vat_main_t * vam)
19451 {
19452   unformat_input_t *i = vam->input;
19453   vl_api_one_eid_table_dump_t *mp;
19454   vl_api_control_ping_t *mp_ping;
19455   struct in_addr ip4;
19456   struct in6_addr ip6;
19457   u8 mac[6];
19458   u8 eid_type = ~0, eid_set = 0;
19459   u32 prefix_length = ~0, t, vni = 0;
19460   u8 filter = 0;
19461   int ret;
19462   lisp_nsh_api_t nsh;
19463
19464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19465     {
19466       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19467         {
19468           eid_set = 1;
19469           eid_type = 0;
19470           prefix_length = t;
19471         }
19472       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19473         {
19474           eid_set = 1;
19475           eid_type = 1;
19476           prefix_length = t;
19477         }
19478       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19479         {
19480           eid_set = 1;
19481           eid_type = 2;
19482         }
19483       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19484         {
19485           eid_set = 1;
19486           eid_type = 3;
19487         }
19488       else if (unformat (i, "vni %d", &t))
19489         {
19490           vni = t;
19491         }
19492       else if (unformat (i, "local"))
19493         {
19494           filter = 1;
19495         }
19496       else if (unformat (i, "remote"))
19497         {
19498           filter = 2;
19499         }
19500       else
19501         {
19502           errmsg ("parse error '%U'", format_unformat_error, i);
19503           return -99;
19504         }
19505     }
19506
19507   if (!vam->json_output)
19508     {
19509       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19510              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19511     }
19512
19513   M (ONE_EID_TABLE_DUMP, mp);
19514
19515   mp->filter = filter;
19516   if (eid_set)
19517     {
19518       mp->eid_set = 1;
19519       mp->vni = htonl (vni);
19520       mp->eid_type = eid_type;
19521       switch (eid_type)
19522         {
19523         case 0:
19524           mp->prefix_length = prefix_length;
19525           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19526           break;
19527         case 1:
19528           mp->prefix_length = prefix_length;
19529           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19530           break;
19531         case 2:
19532           clib_memcpy (mp->eid, mac, sizeof (mac));
19533           break;
19534         case 3:
19535           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19536           break;
19537         default:
19538           errmsg ("unknown EID type %d!", eid_type);
19539           return -99;
19540         }
19541     }
19542
19543   /* send it... */
19544   S (mp);
19545
19546   /* Use a control ping for synchronization */
19547   MPING (CONTROL_PING, mp_ping);
19548   S (mp_ping);
19549
19550   /* Wait for a reply... */
19551   W (ret);
19552   return ret;
19553 }
19554
19555 #define api_lisp_eid_table_dump api_one_eid_table_dump
19556
19557 static int
19558 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_gpe_fwd_entries_get_t *mp;
19562   u8 vni_set = 0;
19563   u32 vni = ~0;
19564   int ret;
19565
19566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19567     {
19568       if (unformat (i, "vni %d", &vni))
19569         {
19570           vni_set = 1;
19571         }
19572       else
19573         {
19574           errmsg ("parse error '%U'", format_unformat_error, i);
19575           return -99;
19576         }
19577     }
19578
19579   if (!vni_set)
19580     {
19581       errmsg ("vni not set!");
19582       return -99;
19583     }
19584
19585   if (!vam->json_output)
19586     {
19587       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19588              "leid", "reid");
19589     }
19590
19591   M (GPE_FWD_ENTRIES_GET, mp);
19592   mp->vni = clib_host_to_net_u32 (vni);
19593
19594   /* send it... */
19595   S (mp);
19596
19597   /* Wait for a reply... */
19598   W (ret);
19599   return ret;
19600 }
19601
19602 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19603 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19604 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19605 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19606 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19607 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19608 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19609 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19610
19611 static int
19612 api_one_adjacencies_get (vat_main_t * vam)
19613 {
19614   unformat_input_t *i = vam->input;
19615   vl_api_one_adjacencies_get_t *mp;
19616   u8 vni_set = 0;
19617   u32 vni = ~0;
19618   int ret;
19619
19620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19621     {
19622       if (unformat (i, "vni %d", &vni))
19623         {
19624           vni_set = 1;
19625         }
19626       else
19627         {
19628           errmsg ("parse error '%U'", format_unformat_error, i);
19629           return -99;
19630         }
19631     }
19632
19633   if (!vni_set)
19634     {
19635       errmsg ("vni not set!");
19636       return -99;
19637     }
19638
19639   if (!vam->json_output)
19640     {
19641       print (vam->ofp, "%s %40s", "leid", "reid");
19642     }
19643
19644   M (ONE_ADJACENCIES_GET, mp);
19645   mp->vni = clib_host_to_net_u32 (vni);
19646
19647   /* send it... */
19648   S (mp);
19649
19650   /* Wait for a reply... */
19651   W (ret);
19652   return ret;
19653 }
19654
19655 #define api_lisp_adjacencies_get api_one_adjacencies_get
19656
19657 static int
19658 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19659 {
19660   unformat_input_t *i = vam->input;
19661   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19662   int ret;
19663   u8 ip_family_set = 0, is_ip4 = 1;
19664
19665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (i, "ip4"))
19668         {
19669           ip_family_set = 1;
19670           is_ip4 = 1;
19671         }
19672       else if (unformat (i, "ip6"))
19673         {
19674           ip_family_set = 1;
19675           is_ip4 = 0;
19676         }
19677       else
19678         {
19679           errmsg ("parse error '%U'", format_unformat_error, i);
19680           return -99;
19681         }
19682     }
19683
19684   if (!ip_family_set)
19685     {
19686       errmsg ("ip family not set!");
19687       return -99;
19688     }
19689
19690   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19691   mp->is_ip4 = is_ip4;
19692
19693   /* send it... */
19694   S (mp);
19695
19696   /* Wait for a reply... */
19697   W (ret);
19698   return ret;
19699 }
19700
19701 static int
19702 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19703 {
19704   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19705   int ret;
19706
19707   if (!vam->json_output)
19708     {
19709       print (vam->ofp, "VNIs");
19710     }
19711
19712   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19713
19714   /* send it... */
19715   S (mp);
19716
19717   /* Wait for a reply... */
19718   W (ret);
19719   return ret;
19720 }
19721
19722 static int
19723 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19724 {
19725   unformat_input_t *i = vam->input;
19726   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19727   int ret = 0;
19728   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19729   struct in_addr ip4;
19730   struct in6_addr ip6;
19731   u32 table_id = 0, nh_sw_if_index = ~0;
19732
19733   clib_memset (&ip4, 0, sizeof (ip4));
19734   clib_memset (&ip6, 0, sizeof (ip6));
19735
19736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19737     {
19738       if (unformat (i, "del"))
19739         is_add = 0;
19740       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19741                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19742         {
19743           ip_set = 1;
19744           is_ip4 = 1;
19745         }
19746       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19747                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19748         {
19749           ip_set = 1;
19750           is_ip4 = 0;
19751         }
19752       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19753         {
19754           ip_set = 1;
19755           is_ip4 = 1;
19756           nh_sw_if_index = ~0;
19757         }
19758       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19759         {
19760           ip_set = 1;
19761           is_ip4 = 0;
19762           nh_sw_if_index = ~0;
19763         }
19764       else if (unformat (i, "table %d", &table_id))
19765         ;
19766       else
19767         {
19768           errmsg ("parse error '%U'", format_unformat_error, i);
19769           return -99;
19770         }
19771     }
19772
19773   if (!ip_set)
19774     {
19775       errmsg ("nh addr not set!");
19776       return -99;
19777     }
19778
19779   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19780   mp->is_add = is_add;
19781   mp->table_id = clib_host_to_net_u32 (table_id);
19782   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19783   mp->is_ip4 = is_ip4;
19784   if (is_ip4)
19785     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19786   else
19787     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19788
19789   /* send it... */
19790   S (mp);
19791
19792   /* Wait for a reply... */
19793   W (ret);
19794   return ret;
19795 }
19796
19797 static int
19798 api_one_map_server_dump (vat_main_t * vam)
19799 {
19800   vl_api_one_map_server_dump_t *mp;
19801   vl_api_control_ping_t *mp_ping;
19802   int ret;
19803
19804   if (!vam->json_output)
19805     {
19806       print (vam->ofp, "%=20s", "Map server");
19807     }
19808
19809   M (ONE_MAP_SERVER_DUMP, mp);
19810   /* send it... */
19811   S (mp);
19812
19813   /* Use a control ping for synchronization */
19814   MPING (CONTROL_PING, mp_ping);
19815   S (mp_ping);
19816
19817   /* Wait for a reply... */
19818   W (ret);
19819   return ret;
19820 }
19821
19822 #define api_lisp_map_server_dump api_one_map_server_dump
19823
19824 static int
19825 api_one_map_resolver_dump (vat_main_t * vam)
19826 {
19827   vl_api_one_map_resolver_dump_t *mp;
19828   vl_api_control_ping_t *mp_ping;
19829   int ret;
19830
19831   if (!vam->json_output)
19832     {
19833       print (vam->ofp, "%=20s", "Map resolver");
19834     }
19835
19836   M (ONE_MAP_RESOLVER_DUMP, mp);
19837   /* send it... */
19838   S (mp);
19839
19840   /* Use a control ping for synchronization */
19841   MPING (CONTROL_PING, mp_ping);
19842   S (mp_ping);
19843
19844   /* Wait for a reply... */
19845   W (ret);
19846   return ret;
19847 }
19848
19849 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19850
19851 static int
19852 api_one_stats_flush (vat_main_t * vam)
19853 {
19854   vl_api_one_stats_flush_t *mp;
19855   int ret = 0;
19856
19857   M (ONE_STATS_FLUSH, mp);
19858   S (mp);
19859   W (ret);
19860   return ret;
19861 }
19862
19863 static int
19864 api_one_stats_dump (vat_main_t * vam)
19865 {
19866   vl_api_one_stats_dump_t *mp;
19867   vl_api_control_ping_t *mp_ping;
19868   int ret;
19869
19870   M (ONE_STATS_DUMP, mp);
19871   /* send it... */
19872   S (mp);
19873
19874   /* Use a control ping for synchronization */
19875   MPING (CONTROL_PING, mp_ping);
19876   S (mp_ping);
19877
19878   /* Wait for a reply... */
19879   W (ret);
19880   return ret;
19881 }
19882
19883 static int
19884 api_show_one_status (vat_main_t * vam)
19885 {
19886   vl_api_show_one_status_t *mp;
19887   int ret;
19888
19889   if (!vam->json_output)
19890     {
19891       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19892     }
19893
19894   M (SHOW_ONE_STATUS, mp);
19895   /* send it... */
19896   S (mp);
19897   /* Wait for a reply... */
19898   W (ret);
19899   return ret;
19900 }
19901
19902 #define api_show_lisp_status api_show_one_status
19903
19904 static int
19905 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19906 {
19907   vl_api_gpe_fwd_entry_path_dump_t *mp;
19908   vl_api_control_ping_t *mp_ping;
19909   unformat_input_t *i = vam->input;
19910   u32 fwd_entry_index = ~0;
19911   int ret;
19912
19913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19914     {
19915       if (unformat (i, "index %d", &fwd_entry_index))
19916         ;
19917       else
19918         break;
19919     }
19920
19921   if (~0 == fwd_entry_index)
19922     {
19923       errmsg ("no index specified!");
19924       return -99;
19925     }
19926
19927   if (!vam->json_output)
19928     {
19929       print (vam->ofp, "first line");
19930     }
19931
19932   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19933
19934   /* send it... */
19935   S (mp);
19936   /* Use a control ping for synchronization */
19937   MPING (CONTROL_PING, mp_ping);
19938   S (mp_ping);
19939
19940   /* Wait for a reply... */
19941   W (ret);
19942   return ret;
19943 }
19944
19945 static int
19946 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19947 {
19948   vl_api_one_get_map_request_itr_rlocs_t *mp;
19949   int ret;
19950
19951   if (!vam->json_output)
19952     {
19953       print (vam->ofp, "%=20s", "itr-rlocs:");
19954     }
19955
19956   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19957   /* send it... */
19958   S (mp);
19959   /* Wait for a reply... */
19960   W (ret);
19961   return ret;
19962 }
19963
19964 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19965
19966 static int
19967 api_af_packet_create (vat_main_t * vam)
19968 {
19969   unformat_input_t *i = vam->input;
19970   vl_api_af_packet_create_t *mp;
19971   u8 *host_if_name = 0;
19972   u8 hw_addr[6];
19973   u8 random_hw_addr = 1;
19974   int ret;
19975
19976   clib_memset (hw_addr, 0, sizeof (hw_addr));
19977
19978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (i, "name %s", &host_if_name))
19981         vec_add1 (host_if_name, 0);
19982       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19983         random_hw_addr = 0;
19984       else
19985         break;
19986     }
19987
19988   if (!vec_len (host_if_name))
19989     {
19990       errmsg ("host-interface name must be specified");
19991       return -99;
19992     }
19993
19994   if (vec_len (host_if_name) > 64)
19995     {
19996       errmsg ("host-interface name too long");
19997       return -99;
19998     }
19999
20000   M (AF_PACKET_CREATE, mp);
20001
20002   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20003   clib_memcpy (mp->hw_addr, hw_addr, 6);
20004   mp->use_random_hw_addr = random_hw_addr;
20005   vec_free (host_if_name);
20006
20007   S (mp);
20008
20009   /* *INDENT-OFF* */
20010   W2 (ret,
20011       ({
20012         if (ret == 0)
20013           fprintf (vam->ofp ? vam->ofp : stderr,
20014                    " new sw_if_index = %d\n", vam->sw_if_index);
20015       }));
20016   /* *INDENT-ON* */
20017   return ret;
20018 }
20019
20020 static int
20021 api_af_packet_delete (vat_main_t * vam)
20022 {
20023   unformat_input_t *i = vam->input;
20024   vl_api_af_packet_delete_t *mp;
20025   u8 *host_if_name = 0;
20026   int ret;
20027
20028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20029     {
20030       if (unformat (i, "name %s", &host_if_name))
20031         vec_add1 (host_if_name, 0);
20032       else
20033         break;
20034     }
20035
20036   if (!vec_len (host_if_name))
20037     {
20038       errmsg ("host-interface name must be specified");
20039       return -99;
20040     }
20041
20042   if (vec_len (host_if_name) > 64)
20043     {
20044       errmsg ("host-interface name too long");
20045       return -99;
20046     }
20047
20048   M (AF_PACKET_DELETE, mp);
20049
20050   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20051   vec_free (host_if_name);
20052
20053   S (mp);
20054   W (ret);
20055   return ret;
20056 }
20057
20058 static void vl_api_af_packet_details_t_handler
20059   (vl_api_af_packet_details_t * mp)
20060 {
20061   vat_main_t *vam = &vat_main;
20062
20063   print (vam->ofp, "%-16s %d",
20064          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20065 }
20066
20067 static void vl_api_af_packet_details_t_handler_json
20068   (vl_api_af_packet_details_t * mp)
20069 {
20070   vat_main_t *vam = &vat_main;
20071   vat_json_node_t *node = NULL;
20072
20073   if (VAT_JSON_ARRAY != vam->json_tree.type)
20074     {
20075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20076       vat_json_init_array (&vam->json_tree);
20077     }
20078   node = vat_json_array_add (&vam->json_tree);
20079
20080   vat_json_init_object (node);
20081   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20082   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20083 }
20084
20085 static int
20086 api_af_packet_dump (vat_main_t * vam)
20087 {
20088   vl_api_af_packet_dump_t *mp;
20089   vl_api_control_ping_t *mp_ping;
20090   int ret;
20091
20092   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20093   /* Get list of tap interfaces */
20094   M (AF_PACKET_DUMP, mp);
20095   S (mp);
20096
20097   /* Use a control ping for synchronization */
20098   MPING (CONTROL_PING, mp_ping);
20099   S (mp_ping);
20100
20101   W (ret);
20102   return ret;
20103 }
20104
20105 static int
20106 api_policer_add_del (vat_main_t * vam)
20107 {
20108   unformat_input_t *i = vam->input;
20109   vl_api_policer_add_del_t *mp;
20110   u8 is_add = 1;
20111   u8 *name = 0;
20112   u32 cir = 0;
20113   u32 eir = 0;
20114   u64 cb = 0;
20115   u64 eb = 0;
20116   u8 rate_type = 0;
20117   u8 round_type = 0;
20118   u8 type = 0;
20119   u8 color_aware = 0;
20120   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20121   int ret;
20122
20123   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20124   conform_action.dscp = 0;
20125   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20126   exceed_action.dscp = 0;
20127   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20128   violate_action.dscp = 0;
20129
20130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20131     {
20132       if (unformat (i, "del"))
20133         is_add = 0;
20134       else if (unformat (i, "name %s", &name))
20135         vec_add1 (name, 0);
20136       else if (unformat (i, "cir %u", &cir))
20137         ;
20138       else if (unformat (i, "eir %u", &eir))
20139         ;
20140       else if (unformat (i, "cb %u", &cb))
20141         ;
20142       else if (unformat (i, "eb %u", &eb))
20143         ;
20144       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20145                          &rate_type))
20146         ;
20147       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20148                          &round_type))
20149         ;
20150       else if (unformat (i, "type %U", unformat_policer_type, &type))
20151         ;
20152       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20153                          &conform_action))
20154         ;
20155       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20156                          &exceed_action))
20157         ;
20158       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20159                          &violate_action))
20160         ;
20161       else if (unformat (i, "color-aware"))
20162         color_aware = 1;
20163       else
20164         break;
20165     }
20166
20167   if (!vec_len (name))
20168     {
20169       errmsg ("policer name must be specified");
20170       return -99;
20171     }
20172
20173   if (vec_len (name) > 64)
20174     {
20175       errmsg ("policer name too long");
20176       return -99;
20177     }
20178
20179   M (POLICER_ADD_DEL, mp);
20180
20181   clib_memcpy (mp->name, name, vec_len (name));
20182   vec_free (name);
20183   mp->is_add = is_add;
20184   mp->cir = ntohl (cir);
20185   mp->eir = ntohl (eir);
20186   mp->cb = clib_net_to_host_u64 (cb);
20187   mp->eb = clib_net_to_host_u64 (eb);
20188   mp->rate_type = rate_type;
20189   mp->round_type = round_type;
20190   mp->type = type;
20191   mp->conform_action_type = conform_action.action_type;
20192   mp->conform_dscp = conform_action.dscp;
20193   mp->exceed_action_type = exceed_action.action_type;
20194   mp->exceed_dscp = exceed_action.dscp;
20195   mp->violate_action_type = violate_action.action_type;
20196   mp->violate_dscp = violate_action.dscp;
20197   mp->color_aware = color_aware;
20198
20199   S (mp);
20200   W (ret);
20201   return ret;
20202 }
20203
20204 static int
20205 api_policer_dump (vat_main_t * vam)
20206 {
20207   unformat_input_t *i = vam->input;
20208   vl_api_policer_dump_t *mp;
20209   vl_api_control_ping_t *mp_ping;
20210   u8 *match_name = 0;
20211   u8 match_name_valid = 0;
20212   int ret;
20213
20214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20215     {
20216       if (unformat (i, "name %s", &match_name))
20217         {
20218           vec_add1 (match_name, 0);
20219           match_name_valid = 1;
20220         }
20221       else
20222         break;
20223     }
20224
20225   M (POLICER_DUMP, mp);
20226   mp->match_name_valid = match_name_valid;
20227   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20228   vec_free (match_name);
20229   /* send it... */
20230   S (mp);
20231
20232   /* Use a control ping for synchronization */
20233   MPING (CONTROL_PING, mp_ping);
20234   S (mp_ping);
20235
20236   /* Wait for a reply... */
20237   W (ret);
20238   return ret;
20239 }
20240
20241 static int
20242 api_policer_classify_set_interface (vat_main_t * vam)
20243 {
20244   unformat_input_t *i = vam->input;
20245   vl_api_policer_classify_set_interface_t *mp;
20246   u32 sw_if_index;
20247   int sw_if_index_set;
20248   u32 ip4_table_index = ~0;
20249   u32 ip6_table_index = ~0;
20250   u32 l2_table_index = ~0;
20251   u8 is_add = 1;
20252   int ret;
20253
20254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20255     {
20256       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20257         sw_if_index_set = 1;
20258       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20259         sw_if_index_set = 1;
20260       else if (unformat (i, "del"))
20261         is_add = 0;
20262       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20263         ;
20264       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20265         ;
20266       else if (unformat (i, "l2-table %d", &l2_table_index))
20267         ;
20268       else
20269         {
20270           clib_warning ("parse error '%U'", format_unformat_error, i);
20271           return -99;
20272         }
20273     }
20274
20275   if (sw_if_index_set == 0)
20276     {
20277       errmsg ("missing interface name or sw_if_index");
20278       return -99;
20279     }
20280
20281   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20282
20283   mp->sw_if_index = ntohl (sw_if_index);
20284   mp->ip4_table_index = ntohl (ip4_table_index);
20285   mp->ip6_table_index = ntohl (ip6_table_index);
20286   mp->l2_table_index = ntohl (l2_table_index);
20287   mp->is_add = is_add;
20288
20289   S (mp);
20290   W (ret);
20291   return ret;
20292 }
20293
20294 static int
20295 api_policer_classify_dump (vat_main_t * vam)
20296 {
20297   unformat_input_t *i = vam->input;
20298   vl_api_policer_classify_dump_t *mp;
20299   vl_api_control_ping_t *mp_ping;
20300   u8 type = POLICER_CLASSIFY_N_TABLES;
20301   int ret;
20302
20303   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20304     ;
20305   else
20306     {
20307       errmsg ("classify table type must be specified");
20308       return -99;
20309     }
20310
20311   if (!vam->json_output)
20312     {
20313       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20314     }
20315
20316   M (POLICER_CLASSIFY_DUMP, mp);
20317   mp->type = type;
20318   /* send it... */
20319   S (mp);
20320
20321   /* Use a control ping for synchronization */
20322   MPING (CONTROL_PING, mp_ping);
20323   S (mp_ping);
20324
20325   /* Wait for a reply... */
20326   W (ret);
20327   return ret;
20328 }
20329
20330 static int
20331 api_netmap_create (vat_main_t * vam)
20332 {
20333   unformat_input_t *i = vam->input;
20334   vl_api_netmap_create_t *mp;
20335   u8 *if_name = 0;
20336   u8 hw_addr[6];
20337   u8 random_hw_addr = 1;
20338   u8 is_pipe = 0;
20339   u8 is_master = 0;
20340   int ret;
20341
20342   clib_memset (hw_addr, 0, sizeof (hw_addr));
20343
20344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20345     {
20346       if (unformat (i, "name %s", &if_name))
20347         vec_add1 (if_name, 0);
20348       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20349         random_hw_addr = 0;
20350       else if (unformat (i, "pipe"))
20351         is_pipe = 1;
20352       else if (unformat (i, "master"))
20353         is_master = 1;
20354       else if (unformat (i, "slave"))
20355         is_master = 0;
20356       else
20357         break;
20358     }
20359
20360   if (!vec_len (if_name))
20361     {
20362       errmsg ("interface name must be specified");
20363       return -99;
20364     }
20365
20366   if (vec_len (if_name) > 64)
20367     {
20368       errmsg ("interface name too long");
20369       return -99;
20370     }
20371
20372   M (NETMAP_CREATE, mp);
20373
20374   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20375   clib_memcpy (mp->hw_addr, hw_addr, 6);
20376   mp->use_random_hw_addr = random_hw_addr;
20377   mp->is_pipe = is_pipe;
20378   mp->is_master = is_master;
20379   vec_free (if_name);
20380
20381   S (mp);
20382   W (ret);
20383   return ret;
20384 }
20385
20386 static int
20387 api_netmap_delete (vat_main_t * vam)
20388 {
20389   unformat_input_t *i = vam->input;
20390   vl_api_netmap_delete_t *mp;
20391   u8 *if_name = 0;
20392   int ret;
20393
20394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20395     {
20396       if (unformat (i, "name %s", &if_name))
20397         vec_add1 (if_name, 0);
20398       else
20399         break;
20400     }
20401
20402   if (!vec_len (if_name))
20403     {
20404       errmsg ("interface name must be specified");
20405       return -99;
20406     }
20407
20408   if (vec_len (if_name) > 64)
20409     {
20410       errmsg ("interface name too long");
20411       return -99;
20412     }
20413
20414   M (NETMAP_DELETE, mp);
20415
20416   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20417   vec_free (if_name);
20418
20419   S (mp);
20420   W (ret);
20421   return ret;
20422 }
20423
20424 static void
20425 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20426 {
20427   if (fp->afi == IP46_TYPE_IP6)
20428     print (vam->ofp,
20429            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20430            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20431            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20432            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20433            format_ip6_address, fp->next_hop);
20434   else if (fp->afi == IP46_TYPE_IP4)
20435     print (vam->ofp,
20436            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20437            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20438            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20439            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20440            format_ip4_address, fp->next_hop);
20441 }
20442
20443 static void
20444 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20445                                  vl_api_fib_path_t * fp)
20446 {
20447   struct in_addr ip4;
20448   struct in6_addr ip6;
20449
20450   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20451   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20452   vat_json_object_add_uint (node, "is_local", fp->is_local);
20453   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20454   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20455   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20456   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20457   if (fp->afi == IP46_TYPE_IP4)
20458     {
20459       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20460       vat_json_object_add_ip4 (node, "next_hop", ip4);
20461     }
20462   else if (fp->afi == IP46_TYPE_IP6)
20463     {
20464       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20465       vat_json_object_add_ip6 (node, "next_hop", ip6);
20466     }
20467 }
20468
20469 static void
20470 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20471 {
20472   vat_main_t *vam = &vat_main;
20473   int count = ntohl (mp->mt_count);
20474   vl_api_fib_path_t *fp;
20475   i32 i;
20476
20477   print (vam->ofp, "[%d]: sw_if_index %d via:",
20478          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20479   fp = mp->mt_paths;
20480   for (i = 0; i < count; i++)
20481     {
20482       vl_api_mpls_fib_path_print (vam, fp);
20483       fp++;
20484     }
20485
20486   print (vam->ofp, "");
20487 }
20488
20489 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20490 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20491
20492 static void
20493 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20494 {
20495   vat_main_t *vam = &vat_main;
20496   vat_json_node_t *node = NULL;
20497   int count = ntohl (mp->mt_count);
20498   vl_api_fib_path_t *fp;
20499   i32 i;
20500
20501   if (VAT_JSON_ARRAY != vam->json_tree.type)
20502     {
20503       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20504       vat_json_init_array (&vam->json_tree);
20505     }
20506   node = vat_json_array_add (&vam->json_tree);
20507
20508   vat_json_init_object (node);
20509   vat_json_object_add_uint (node, "tunnel_index",
20510                             ntohl (mp->mt_tunnel_index));
20511   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20512
20513   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20514
20515   fp = mp->mt_paths;
20516   for (i = 0; i < count; i++)
20517     {
20518       vl_api_mpls_fib_path_json_print (node, fp);
20519       fp++;
20520     }
20521 }
20522
20523 static int
20524 api_mpls_tunnel_dump (vat_main_t * vam)
20525 {
20526   vl_api_mpls_tunnel_dump_t *mp;
20527   vl_api_control_ping_t *mp_ping;
20528   u32 sw_if_index = ~0;
20529   int ret;
20530
20531   /* Parse args required to build the message */
20532   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20533     {
20534       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20535         ;
20536     }
20537
20538   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20539
20540   M (MPLS_TUNNEL_DUMP, mp);
20541   mp->sw_if_index = htonl (sw_if_index);
20542   S (mp);
20543
20544   /* Use a control ping for synchronization */
20545   MPING (CONTROL_PING, mp_ping);
20546   S (mp_ping);
20547
20548   W (ret);
20549   return ret;
20550 }
20551
20552 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20553 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20554
20555
20556 static void
20557 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20558 {
20559   vat_main_t *vam = &vat_main;
20560   int count = ntohl (mp->count);
20561   vl_api_fib_path_t *fp;
20562   int i;
20563
20564   print (vam->ofp,
20565          "table-id %d, label %u, ess_bit %u",
20566          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20567   fp = mp->path;
20568   for (i = 0; i < count; i++)
20569     {
20570       vl_api_mpls_fib_path_print (vam, fp);
20571       fp++;
20572     }
20573 }
20574
20575 static void vl_api_mpls_fib_details_t_handler_json
20576   (vl_api_mpls_fib_details_t * mp)
20577 {
20578   vat_main_t *vam = &vat_main;
20579   int count = ntohl (mp->count);
20580   vat_json_node_t *node = NULL;
20581   vl_api_fib_path_t *fp;
20582   int i;
20583
20584   if (VAT_JSON_ARRAY != vam->json_tree.type)
20585     {
20586       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20587       vat_json_init_array (&vam->json_tree);
20588     }
20589   node = vat_json_array_add (&vam->json_tree);
20590
20591   vat_json_init_object (node);
20592   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20593   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20594   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20595   vat_json_object_add_uint (node, "path_count", count);
20596   fp = mp->path;
20597   for (i = 0; i < count; i++)
20598     {
20599       vl_api_mpls_fib_path_json_print (node, fp);
20600       fp++;
20601     }
20602 }
20603
20604 static int
20605 api_mpls_fib_dump (vat_main_t * vam)
20606 {
20607   vl_api_mpls_fib_dump_t *mp;
20608   vl_api_control_ping_t *mp_ping;
20609   int ret;
20610
20611   M (MPLS_FIB_DUMP, mp);
20612   S (mp);
20613
20614   /* Use a control ping for synchronization */
20615   MPING (CONTROL_PING, mp_ping);
20616   S (mp_ping);
20617
20618   W (ret);
20619   return ret;
20620 }
20621
20622 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20623 #define vl_api_ip_fib_details_t_print vl_noop_handler
20624
20625 static void
20626 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20627 {
20628   vat_main_t *vam = &vat_main;
20629   int count = ntohl (mp->count);
20630   vl_api_fib_path_t *fp;
20631   int i;
20632
20633   print (vam->ofp,
20634          "table-id %d, prefix %U/%d stats-index %d",
20635          ntohl (mp->table_id), format_ip4_address, mp->address,
20636          mp->address_length, ntohl (mp->stats_index));
20637   fp = mp->path;
20638   for (i = 0; i < count; i++)
20639     {
20640       if (fp->afi == IP46_TYPE_IP6)
20641         print (vam->ofp,
20642                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20643                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20644                "next_hop_table %d",
20645                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20646                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20647                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20648       else if (fp->afi == IP46_TYPE_IP4)
20649         print (vam->ofp,
20650                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20651                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20652                "next_hop_table %d",
20653                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20654                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20655                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20656       fp++;
20657     }
20658 }
20659
20660 static void vl_api_ip_fib_details_t_handler_json
20661   (vl_api_ip_fib_details_t * mp)
20662 {
20663   vat_main_t *vam = &vat_main;
20664   int count = ntohl (mp->count);
20665   vat_json_node_t *node = NULL;
20666   struct in_addr ip4;
20667   struct in6_addr ip6;
20668   vl_api_fib_path_t *fp;
20669   int i;
20670
20671   if (VAT_JSON_ARRAY != vam->json_tree.type)
20672     {
20673       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20674       vat_json_init_array (&vam->json_tree);
20675     }
20676   node = vat_json_array_add (&vam->json_tree);
20677
20678   vat_json_init_object (node);
20679   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20680   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20681   vat_json_object_add_ip4 (node, "prefix", ip4);
20682   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20683   vat_json_object_add_uint (node, "path_count", count);
20684   fp = mp->path;
20685   for (i = 0; i < count; i++)
20686     {
20687       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20688       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20689       vat_json_object_add_uint (node, "is_local", fp->is_local);
20690       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20691       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20692       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20693       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20694       if (fp->afi == IP46_TYPE_IP4)
20695         {
20696           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20697           vat_json_object_add_ip4 (node, "next_hop", ip4);
20698         }
20699       else if (fp->afi == IP46_TYPE_IP6)
20700         {
20701           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20702           vat_json_object_add_ip6 (node, "next_hop", ip6);
20703         }
20704     }
20705 }
20706
20707 static int
20708 api_ip_fib_dump (vat_main_t * vam)
20709 {
20710   vl_api_ip_fib_dump_t *mp;
20711   vl_api_control_ping_t *mp_ping;
20712   int ret;
20713
20714   M (IP_FIB_DUMP, mp);
20715   S (mp);
20716
20717   /* Use a control ping for synchronization */
20718   MPING (CONTROL_PING, mp_ping);
20719   S (mp_ping);
20720
20721   W (ret);
20722   return ret;
20723 }
20724
20725 static int
20726 api_ip_mfib_dump (vat_main_t * vam)
20727 {
20728   vl_api_ip_mfib_dump_t *mp;
20729   vl_api_control_ping_t *mp_ping;
20730   int ret;
20731
20732   M (IP_MFIB_DUMP, mp);
20733   S (mp);
20734
20735   /* Use a control ping for synchronization */
20736   MPING (CONTROL_PING, mp_ping);
20737   S (mp_ping);
20738
20739   W (ret);
20740   return ret;
20741 }
20742
20743 static void vl_api_ip_neighbor_details_t_handler
20744   (vl_api_ip_neighbor_details_t * mp)
20745 {
20746   vat_main_t *vam = &vat_main;
20747
20748   print (vam->ofp, "%c %U %U",
20749          (mp->is_static) ? 'S' : 'D',
20750          format_ethernet_address, &mp->mac_address,
20751          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20752          &mp->ip_address);
20753 }
20754
20755 static void vl_api_ip_neighbor_details_t_handler_json
20756   (vl_api_ip_neighbor_details_t * mp)
20757 {
20758
20759   vat_main_t *vam = &vat_main;
20760   vat_json_node_t *node;
20761   struct in_addr ip4;
20762   struct in6_addr ip6;
20763
20764   if (VAT_JSON_ARRAY != vam->json_tree.type)
20765     {
20766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20767       vat_json_init_array (&vam->json_tree);
20768     }
20769   node = vat_json_array_add (&vam->json_tree);
20770
20771   vat_json_init_object (node);
20772   vat_json_object_add_string_copy (node, "flag",
20773                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20774                                    "dynamic");
20775
20776   vat_json_object_add_string_copy (node, "link_layer",
20777                                    format (0, "%U", format_ethernet_address,
20778                                            &mp->mac_address));
20779
20780   if (mp->is_ipv6)
20781     {
20782       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20783       vat_json_object_add_ip6 (node, "ip_address", ip6);
20784     }
20785   else
20786     {
20787       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20788       vat_json_object_add_ip4 (node, "ip_address", ip4);
20789     }
20790 }
20791
20792 static int
20793 api_ip_neighbor_dump (vat_main_t * vam)
20794 {
20795   unformat_input_t *i = vam->input;
20796   vl_api_ip_neighbor_dump_t *mp;
20797   vl_api_control_ping_t *mp_ping;
20798   u8 is_ipv6 = 0;
20799   u32 sw_if_index = ~0;
20800   int ret;
20801
20802   /* Parse args required to build the message */
20803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20804     {
20805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20806         ;
20807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20808         ;
20809       else if (unformat (i, "ip6"))
20810         is_ipv6 = 1;
20811       else
20812         break;
20813     }
20814
20815   if (sw_if_index == ~0)
20816     {
20817       errmsg ("missing interface name or sw_if_index");
20818       return -99;
20819     }
20820
20821   M (IP_NEIGHBOR_DUMP, mp);
20822   mp->is_ipv6 = (u8) is_ipv6;
20823   mp->sw_if_index = ntohl (sw_if_index);
20824   S (mp);
20825
20826   /* Use a control ping for synchronization */
20827   MPING (CONTROL_PING, mp_ping);
20828   S (mp_ping);
20829
20830   W (ret);
20831   return ret;
20832 }
20833
20834 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20835 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20836
20837 static void
20838 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20839 {
20840   vat_main_t *vam = &vat_main;
20841   int count = ntohl (mp->count);
20842   vl_api_fib_path_t *fp;
20843   int i;
20844
20845   print (vam->ofp,
20846          "table-id %d, prefix %U/%d stats-index %d",
20847          ntohl (mp->table_id), format_ip6_address, mp->address,
20848          mp->address_length, ntohl (mp->stats_index));
20849   fp = mp->path;
20850   for (i = 0; i < count; i++)
20851     {
20852       if (fp->afi == IP46_TYPE_IP6)
20853         print (vam->ofp,
20854                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20855                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20856                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20857                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20858                format_ip6_address, fp->next_hop);
20859       else if (fp->afi == IP46_TYPE_IP4)
20860         print (vam->ofp,
20861                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20862                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20863                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20864                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20865                format_ip4_address, fp->next_hop);
20866       fp++;
20867     }
20868 }
20869
20870 static void vl_api_ip6_fib_details_t_handler_json
20871   (vl_api_ip6_fib_details_t * mp)
20872 {
20873   vat_main_t *vam = &vat_main;
20874   int count = ntohl (mp->count);
20875   vat_json_node_t *node = NULL;
20876   struct in_addr ip4;
20877   struct in6_addr ip6;
20878   vl_api_fib_path_t *fp;
20879   int i;
20880
20881   if (VAT_JSON_ARRAY != vam->json_tree.type)
20882     {
20883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20884       vat_json_init_array (&vam->json_tree);
20885     }
20886   node = vat_json_array_add (&vam->json_tree);
20887
20888   vat_json_init_object (node);
20889   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20890   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20891   vat_json_object_add_ip6 (node, "prefix", ip6);
20892   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20893   vat_json_object_add_uint (node, "path_count", count);
20894   fp = mp->path;
20895   for (i = 0; i < count; i++)
20896     {
20897       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20898       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20899       vat_json_object_add_uint (node, "is_local", fp->is_local);
20900       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20901       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20902       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20903       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20904       if (fp->afi == IP46_TYPE_IP4)
20905         {
20906           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20907           vat_json_object_add_ip4 (node, "next_hop", ip4);
20908         }
20909       else if (fp->afi == IP46_TYPE_IP6)
20910         {
20911           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20912           vat_json_object_add_ip6 (node, "next_hop", ip6);
20913         }
20914     }
20915 }
20916
20917 static int
20918 api_ip6_fib_dump (vat_main_t * vam)
20919 {
20920   vl_api_ip6_fib_dump_t *mp;
20921   vl_api_control_ping_t *mp_ping;
20922   int ret;
20923
20924   M (IP6_FIB_DUMP, mp);
20925   S (mp);
20926
20927   /* Use a control ping for synchronization */
20928   MPING (CONTROL_PING, mp_ping);
20929   S (mp_ping);
20930
20931   W (ret);
20932   return ret;
20933 }
20934
20935 static int
20936 api_ip6_mfib_dump (vat_main_t * vam)
20937 {
20938   vl_api_ip6_mfib_dump_t *mp;
20939   vl_api_control_ping_t *mp_ping;
20940   int ret;
20941
20942   M (IP6_MFIB_DUMP, mp);
20943   S (mp);
20944
20945   /* Use a control ping for synchronization */
20946   MPING (CONTROL_PING, mp_ping);
20947   S (mp_ping);
20948
20949   W (ret);
20950   return ret;
20951 }
20952
20953 int
20954 api_classify_table_ids (vat_main_t * vam)
20955 {
20956   vl_api_classify_table_ids_t *mp;
20957   int ret;
20958
20959   /* Construct the API message */
20960   M (CLASSIFY_TABLE_IDS, mp);
20961   mp->context = 0;
20962
20963   S (mp);
20964   W (ret);
20965   return ret;
20966 }
20967
20968 int
20969 api_classify_table_by_interface (vat_main_t * vam)
20970 {
20971   unformat_input_t *input = vam->input;
20972   vl_api_classify_table_by_interface_t *mp;
20973
20974   u32 sw_if_index = ~0;
20975   int ret;
20976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20977     {
20978       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20979         ;
20980       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20981         ;
20982       else
20983         break;
20984     }
20985   if (sw_if_index == ~0)
20986     {
20987       errmsg ("missing interface name or sw_if_index");
20988       return -99;
20989     }
20990
20991   /* Construct the API message */
20992   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20993   mp->context = 0;
20994   mp->sw_if_index = ntohl (sw_if_index);
20995
20996   S (mp);
20997   W (ret);
20998   return ret;
20999 }
21000
21001 int
21002 api_classify_table_info (vat_main_t * vam)
21003 {
21004   unformat_input_t *input = vam->input;
21005   vl_api_classify_table_info_t *mp;
21006
21007   u32 table_id = ~0;
21008   int ret;
21009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21010     {
21011       if (unformat (input, "table_id %d", &table_id))
21012         ;
21013       else
21014         break;
21015     }
21016   if (table_id == ~0)
21017     {
21018       errmsg ("missing table id");
21019       return -99;
21020     }
21021
21022   /* Construct the API message */
21023   M (CLASSIFY_TABLE_INFO, mp);
21024   mp->context = 0;
21025   mp->table_id = ntohl (table_id);
21026
21027   S (mp);
21028   W (ret);
21029   return ret;
21030 }
21031
21032 int
21033 api_classify_session_dump (vat_main_t * vam)
21034 {
21035   unformat_input_t *input = vam->input;
21036   vl_api_classify_session_dump_t *mp;
21037   vl_api_control_ping_t *mp_ping;
21038
21039   u32 table_id = ~0;
21040   int ret;
21041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21042     {
21043       if (unformat (input, "table_id %d", &table_id))
21044         ;
21045       else
21046         break;
21047     }
21048   if (table_id == ~0)
21049     {
21050       errmsg ("missing table id");
21051       return -99;
21052     }
21053
21054   /* Construct the API message */
21055   M (CLASSIFY_SESSION_DUMP, mp);
21056   mp->context = 0;
21057   mp->table_id = ntohl (table_id);
21058   S (mp);
21059
21060   /* Use a control ping for synchronization */
21061   MPING (CONTROL_PING, mp_ping);
21062   S (mp_ping);
21063
21064   W (ret);
21065   return ret;
21066 }
21067
21068 static void
21069 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21070 {
21071   vat_main_t *vam = &vat_main;
21072
21073   print (vam->ofp, "collector_address %U, collector_port %d, "
21074          "src_address %U, vrf_id %d, path_mtu %u, "
21075          "template_interval %u, udp_checksum %d",
21076          format_ip4_address, mp->collector_address,
21077          ntohs (mp->collector_port),
21078          format_ip4_address, mp->src_address,
21079          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21080          ntohl (mp->template_interval), mp->udp_checksum);
21081
21082   vam->retval = 0;
21083   vam->result_ready = 1;
21084 }
21085
21086 static void
21087   vl_api_ipfix_exporter_details_t_handler_json
21088   (vl_api_ipfix_exporter_details_t * mp)
21089 {
21090   vat_main_t *vam = &vat_main;
21091   vat_json_node_t node;
21092   struct in_addr collector_address;
21093   struct in_addr src_address;
21094
21095   vat_json_init_object (&node);
21096   clib_memcpy (&collector_address, &mp->collector_address,
21097                sizeof (collector_address));
21098   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21099   vat_json_object_add_uint (&node, "collector_port",
21100                             ntohs (mp->collector_port));
21101   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21102   vat_json_object_add_ip4 (&node, "src_address", src_address);
21103   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21104   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21105   vat_json_object_add_uint (&node, "template_interval",
21106                             ntohl (mp->template_interval));
21107   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21108
21109   vat_json_print (vam->ofp, &node);
21110   vat_json_free (&node);
21111   vam->retval = 0;
21112   vam->result_ready = 1;
21113 }
21114
21115 int
21116 api_ipfix_exporter_dump (vat_main_t * vam)
21117 {
21118   vl_api_ipfix_exporter_dump_t *mp;
21119   int ret;
21120
21121   /* Construct the API message */
21122   M (IPFIX_EXPORTER_DUMP, mp);
21123   mp->context = 0;
21124
21125   S (mp);
21126   W (ret);
21127   return ret;
21128 }
21129
21130 static int
21131 api_ipfix_classify_stream_dump (vat_main_t * vam)
21132 {
21133   vl_api_ipfix_classify_stream_dump_t *mp;
21134   int ret;
21135
21136   /* Construct the API message */
21137   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21138   mp->context = 0;
21139
21140   S (mp);
21141   W (ret);
21142   return ret;
21143   /* NOTREACHED */
21144   return 0;
21145 }
21146
21147 static void
21148   vl_api_ipfix_classify_stream_details_t_handler
21149   (vl_api_ipfix_classify_stream_details_t * mp)
21150 {
21151   vat_main_t *vam = &vat_main;
21152   print (vam->ofp, "domain_id %d, src_port %d",
21153          ntohl (mp->domain_id), ntohs (mp->src_port));
21154   vam->retval = 0;
21155   vam->result_ready = 1;
21156 }
21157
21158 static void
21159   vl_api_ipfix_classify_stream_details_t_handler_json
21160   (vl_api_ipfix_classify_stream_details_t * mp)
21161 {
21162   vat_main_t *vam = &vat_main;
21163   vat_json_node_t node;
21164
21165   vat_json_init_object (&node);
21166   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21167   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21168
21169   vat_json_print (vam->ofp, &node);
21170   vat_json_free (&node);
21171   vam->retval = 0;
21172   vam->result_ready = 1;
21173 }
21174
21175 static int
21176 api_ipfix_classify_table_dump (vat_main_t * vam)
21177 {
21178   vl_api_ipfix_classify_table_dump_t *mp;
21179   vl_api_control_ping_t *mp_ping;
21180   int ret;
21181
21182   if (!vam->json_output)
21183     {
21184       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21185              "transport_protocol");
21186     }
21187
21188   /* Construct the API message */
21189   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21190
21191   /* send it... */
21192   S (mp);
21193
21194   /* Use a control ping for synchronization */
21195   MPING (CONTROL_PING, mp_ping);
21196   S (mp_ping);
21197
21198   W (ret);
21199   return ret;
21200 }
21201
21202 static void
21203   vl_api_ipfix_classify_table_details_t_handler
21204   (vl_api_ipfix_classify_table_details_t * mp)
21205 {
21206   vat_main_t *vam = &vat_main;
21207   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21208          mp->transport_protocol);
21209 }
21210
21211 static void
21212   vl_api_ipfix_classify_table_details_t_handler_json
21213   (vl_api_ipfix_classify_table_details_t * mp)
21214 {
21215   vat_json_node_t *node = NULL;
21216   vat_main_t *vam = &vat_main;
21217
21218   if (VAT_JSON_ARRAY != vam->json_tree.type)
21219     {
21220       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21221       vat_json_init_array (&vam->json_tree);
21222     }
21223
21224   node = vat_json_array_add (&vam->json_tree);
21225   vat_json_init_object (node);
21226
21227   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21228   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21229   vat_json_object_add_uint (node, "transport_protocol",
21230                             mp->transport_protocol);
21231 }
21232
21233 static int
21234 api_sw_interface_span_enable_disable (vat_main_t * vam)
21235 {
21236   unformat_input_t *i = vam->input;
21237   vl_api_sw_interface_span_enable_disable_t *mp;
21238   u32 src_sw_if_index = ~0;
21239   u32 dst_sw_if_index = ~0;
21240   u8 state = 3;
21241   int ret;
21242   u8 is_l2 = 0;
21243
21244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21245     {
21246       if (unformat
21247           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21248         ;
21249       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21250         ;
21251       else
21252         if (unformat
21253             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21254         ;
21255       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21256         ;
21257       else if (unformat (i, "disable"))
21258         state = 0;
21259       else if (unformat (i, "rx"))
21260         state = 1;
21261       else if (unformat (i, "tx"))
21262         state = 2;
21263       else if (unformat (i, "both"))
21264         state = 3;
21265       else if (unformat (i, "l2"))
21266         is_l2 = 1;
21267       else
21268         break;
21269     }
21270
21271   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21272
21273   mp->sw_if_index_from = htonl (src_sw_if_index);
21274   mp->sw_if_index_to = htonl (dst_sw_if_index);
21275   mp->state = state;
21276   mp->is_l2 = is_l2;
21277
21278   S (mp);
21279   W (ret);
21280   return ret;
21281 }
21282
21283 static void
21284 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21285                                             * mp)
21286 {
21287   vat_main_t *vam = &vat_main;
21288   u8 *sw_if_from_name = 0;
21289   u8 *sw_if_to_name = 0;
21290   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21291   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21292   char *states[] = { "none", "rx", "tx", "both" };
21293   hash_pair_t *p;
21294
21295   /* *INDENT-OFF* */
21296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21297   ({
21298     if ((u32) p->value[0] == sw_if_index_from)
21299       {
21300         sw_if_from_name = (u8 *)(p->key);
21301         if (sw_if_to_name)
21302           break;
21303       }
21304     if ((u32) p->value[0] == sw_if_index_to)
21305       {
21306         sw_if_to_name = (u8 *)(p->key);
21307         if (sw_if_from_name)
21308           break;
21309       }
21310   }));
21311   /* *INDENT-ON* */
21312   print (vam->ofp, "%20s => %20s (%s) %s",
21313          sw_if_from_name, sw_if_to_name, states[mp->state],
21314          mp->is_l2 ? "l2" : "device");
21315 }
21316
21317 static void
21318   vl_api_sw_interface_span_details_t_handler_json
21319   (vl_api_sw_interface_span_details_t * mp)
21320 {
21321   vat_main_t *vam = &vat_main;
21322   vat_json_node_t *node = NULL;
21323   u8 *sw_if_from_name = 0;
21324   u8 *sw_if_to_name = 0;
21325   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21326   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21327   hash_pair_t *p;
21328
21329   /* *INDENT-OFF* */
21330   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21331   ({
21332     if ((u32) p->value[0] == sw_if_index_from)
21333       {
21334         sw_if_from_name = (u8 *)(p->key);
21335         if (sw_if_to_name)
21336           break;
21337       }
21338     if ((u32) p->value[0] == sw_if_index_to)
21339       {
21340         sw_if_to_name = (u8 *)(p->key);
21341         if (sw_if_from_name)
21342           break;
21343       }
21344   }));
21345   /* *INDENT-ON* */
21346
21347   if (VAT_JSON_ARRAY != vam->json_tree.type)
21348     {
21349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21350       vat_json_init_array (&vam->json_tree);
21351     }
21352   node = vat_json_array_add (&vam->json_tree);
21353
21354   vat_json_init_object (node);
21355   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21356   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21357   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21358   if (0 != sw_if_to_name)
21359     {
21360       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21361     }
21362   vat_json_object_add_uint (node, "state", mp->state);
21363   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21364 }
21365
21366 static int
21367 api_sw_interface_span_dump (vat_main_t * vam)
21368 {
21369   unformat_input_t *input = vam->input;
21370   vl_api_sw_interface_span_dump_t *mp;
21371   vl_api_control_ping_t *mp_ping;
21372   u8 is_l2 = 0;
21373   int ret;
21374
21375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21376     {
21377       if (unformat (input, "l2"))
21378         is_l2 = 1;
21379       else
21380         break;
21381     }
21382
21383   M (SW_INTERFACE_SPAN_DUMP, mp);
21384   mp->is_l2 = is_l2;
21385   S (mp);
21386
21387   /* Use a control ping for synchronization */
21388   MPING (CONTROL_PING, mp_ping);
21389   S (mp_ping);
21390
21391   W (ret);
21392   return ret;
21393 }
21394
21395 int
21396 api_pg_create_interface (vat_main_t * vam)
21397 {
21398   unformat_input_t *input = vam->input;
21399   vl_api_pg_create_interface_t *mp;
21400
21401   u32 if_id = ~0;
21402   int ret;
21403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21404     {
21405       if (unformat (input, "if_id %d", &if_id))
21406         ;
21407       else
21408         break;
21409     }
21410   if (if_id == ~0)
21411     {
21412       errmsg ("missing pg interface index");
21413       return -99;
21414     }
21415
21416   /* Construct the API message */
21417   M (PG_CREATE_INTERFACE, mp);
21418   mp->context = 0;
21419   mp->interface_id = ntohl (if_id);
21420
21421   S (mp);
21422   W (ret);
21423   return ret;
21424 }
21425
21426 int
21427 api_pg_capture (vat_main_t * vam)
21428 {
21429   unformat_input_t *input = vam->input;
21430   vl_api_pg_capture_t *mp;
21431
21432   u32 if_id = ~0;
21433   u8 enable = 1;
21434   u32 count = 1;
21435   u8 pcap_file_set = 0;
21436   u8 *pcap_file = 0;
21437   int ret;
21438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21439     {
21440       if (unformat (input, "if_id %d", &if_id))
21441         ;
21442       else if (unformat (input, "pcap %s", &pcap_file))
21443         pcap_file_set = 1;
21444       else if (unformat (input, "count %d", &count))
21445         ;
21446       else if (unformat (input, "disable"))
21447         enable = 0;
21448       else
21449         break;
21450     }
21451   if (if_id == ~0)
21452     {
21453       errmsg ("missing pg interface index");
21454       return -99;
21455     }
21456   if (pcap_file_set > 0)
21457     {
21458       if (vec_len (pcap_file) > 255)
21459         {
21460           errmsg ("pcap file name is too long");
21461           return -99;
21462         }
21463     }
21464
21465   u32 name_len = vec_len (pcap_file);
21466   /* Construct the API message */
21467   M (PG_CAPTURE, mp);
21468   mp->context = 0;
21469   mp->interface_id = ntohl (if_id);
21470   mp->is_enabled = enable;
21471   mp->count = ntohl (count);
21472   mp->pcap_name_length = ntohl (name_len);
21473   if (pcap_file_set != 0)
21474     {
21475       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21476     }
21477   vec_free (pcap_file);
21478
21479   S (mp);
21480   W (ret);
21481   return ret;
21482 }
21483
21484 int
21485 api_pg_enable_disable (vat_main_t * vam)
21486 {
21487   unformat_input_t *input = vam->input;
21488   vl_api_pg_enable_disable_t *mp;
21489
21490   u8 enable = 1;
21491   u8 stream_name_set = 0;
21492   u8 *stream_name = 0;
21493   int ret;
21494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21495     {
21496       if (unformat (input, "stream %s", &stream_name))
21497         stream_name_set = 1;
21498       else if (unformat (input, "disable"))
21499         enable = 0;
21500       else
21501         break;
21502     }
21503
21504   if (stream_name_set > 0)
21505     {
21506       if (vec_len (stream_name) > 255)
21507         {
21508           errmsg ("stream name too long");
21509           return -99;
21510         }
21511     }
21512
21513   u32 name_len = vec_len (stream_name);
21514   /* Construct the API message */
21515   M (PG_ENABLE_DISABLE, mp);
21516   mp->context = 0;
21517   mp->is_enabled = enable;
21518   if (stream_name_set != 0)
21519     {
21520       mp->stream_name_length = ntohl (name_len);
21521       clib_memcpy (mp->stream_name, stream_name, name_len);
21522     }
21523   vec_free (stream_name);
21524
21525   S (mp);
21526   W (ret);
21527   return ret;
21528 }
21529
21530 int
21531 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21532 {
21533   unformat_input_t *input = vam->input;
21534   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21535
21536   u16 *low_ports = 0;
21537   u16 *high_ports = 0;
21538   u16 this_low;
21539   u16 this_hi;
21540   ip4_address_t ip4_addr;
21541   ip6_address_t ip6_addr;
21542   u32 length;
21543   u32 tmp, tmp2;
21544   u8 prefix_set = 0;
21545   u32 vrf_id = ~0;
21546   u8 is_add = 1;
21547   u8 is_ipv6 = 0;
21548   int ret;
21549
21550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21551     {
21552       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21553         {
21554           prefix_set = 1;
21555         }
21556       else
21557         if (unformat
21558             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21559         {
21560           prefix_set = 1;
21561           is_ipv6 = 1;
21562         }
21563       else if (unformat (input, "vrf %d", &vrf_id))
21564         ;
21565       else if (unformat (input, "del"))
21566         is_add = 0;
21567       else if (unformat (input, "port %d", &tmp))
21568         {
21569           if (tmp == 0 || tmp > 65535)
21570             {
21571               errmsg ("port %d out of range", tmp);
21572               return -99;
21573             }
21574           this_low = tmp;
21575           this_hi = this_low + 1;
21576           vec_add1 (low_ports, this_low);
21577           vec_add1 (high_ports, this_hi);
21578         }
21579       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21580         {
21581           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21582             {
21583               errmsg ("incorrect range parameters");
21584               return -99;
21585             }
21586           this_low = tmp;
21587           /* Note: in debug CLI +1 is added to high before
21588              passing to real fn that does "the work"
21589              (ip_source_and_port_range_check_add_del).
21590              This fn is a wrapper around the binary API fn a
21591              control plane will call, which expects this increment
21592              to have occurred. Hence letting the binary API control
21593              plane fn do the increment for consistency between VAT
21594              and other control planes.
21595            */
21596           this_hi = tmp2;
21597           vec_add1 (low_ports, this_low);
21598           vec_add1 (high_ports, this_hi);
21599         }
21600       else
21601         break;
21602     }
21603
21604   if (prefix_set == 0)
21605     {
21606       errmsg ("<address>/<mask> not specified");
21607       return -99;
21608     }
21609
21610   if (vrf_id == ~0)
21611     {
21612       errmsg ("VRF ID required, not specified");
21613       return -99;
21614     }
21615
21616   if (vrf_id == 0)
21617     {
21618       errmsg
21619         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21620       return -99;
21621     }
21622
21623   if (vec_len (low_ports) == 0)
21624     {
21625       errmsg ("At least one port or port range required");
21626       return -99;
21627     }
21628
21629   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21630
21631   mp->is_add = is_add;
21632
21633   if (is_ipv6)
21634     {
21635       mp->is_ipv6 = 1;
21636       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21637     }
21638   else
21639     {
21640       mp->is_ipv6 = 0;
21641       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21642     }
21643
21644   mp->mask_length = length;
21645   mp->number_of_ranges = vec_len (low_ports);
21646
21647   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21648   vec_free (low_ports);
21649
21650   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21651   vec_free (high_ports);
21652
21653   mp->vrf_id = ntohl (vrf_id);
21654
21655   S (mp);
21656   W (ret);
21657   return ret;
21658 }
21659
21660 int
21661 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21662 {
21663   unformat_input_t *input = vam->input;
21664   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21665   u32 sw_if_index = ~0;
21666   int vrf_set = 0;
21667   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21668   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21669   u8 is_add = 1;
21670   int ret;
21671
21672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21673     {
21674       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21675         ;
21676       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21677         ;
21678       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21679         vrf_set = 1;
21680       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21681         vrf_set = 1;
21682       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21683         vrf_set = 1;
21684       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21685         vrf_set = 1;
21686       else if (unformat (input, "del"))
21687         is_add = 0;
21688       else
21689         break;
21690     }
21691
21692   if (sw_if_index == ~0)
21693     {
21694       errmsg ("Interface required but not specified");
21695       return -99;
21696     }
21697
21698   if (vrf_set == 0)
21699     {
21700       errmsg ("VRF ID required but not specified");
21701       return -99;
21702     }
21703
21704   if (tcp_out_vrf_id == 0
21705       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21706     {
21707       errmsg
21708         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21709       return -99;
21710     }
21711
21712   /* Construct the API message */
21713   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21714
21715   mp->sw_if_index = ntohl (sw_if_index);
21716   mp->is_add = is_add;
21717   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21718   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21719   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21720   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21721
21722   /* send it... */
21723   S (mp);
21724
21725   /* Wait for a reply... */
21726   W (ret);
21727   return ret;
21728 }
21729
21730 static int
21731 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21732 {
21733   unformat_input_t *i = vam->input;
21734   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21735   u32 local_sa_id = 0;
21736   u32 remote_sa_id = 0;
21737   ip4_address_t src_address;
21738   ip4_address_t dst_address;
21739   u8 is_add = 1;
21740   int ret;
21741
21742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21743     {
21744       if (unformat (i, "local_sa %d", &local_sa_id))
21745         ;
21746       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21747         ;
21748       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21749         ;
21750       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21751         ;
21752       else if (unformat (i, "del"))
21753         is_add = 0;
21754       else
21755         {
21756           clib_warning ("parse error '%U'", format_unformat_error, i);
21757           return -99;
21758         }
21759     }
21760
21761   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21762
21763   mp->local_sa_id = ntohl (local_sa_id);
21764   mp->remote_sa_id = ntohl (remote_sa_id);
21765   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21766   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21767   mp->is_add = is_add;
21768
21769   S (mp);
21770   W (ret);
21771   return ret;
21772 }
21773
21774 static int
21775 api_punt (vat_main_t * vam)
21776 {
21777   unformat_input_t *i = vam->input;
21778   vl_api_punt_t *mp;
21779   u32 ipv = ~0;
21780   u32 protocol = ~0;
21781   u32 port = ~0;
21782   int is_add = 1;
21783   int ret;
21784
21785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21786     {
21787       if (unformat (i, "ip %d", &ipv))
21788         ;
21789       else if (unformat (i, "protocol %d", &protocol))
21790         ;
21791       else if (unformat (i, "port %d", &port))
21792         ;
21793       else if (unformat (i, "del"))
21794         is_add = 0;
21795       else
21796         {
21797           clib_warning ("parse error '%U'", format_unformat_error, i);
21798           return -99;
21799         }
21800     }
21801
21802   M (PUNT, mp);
21803
21804   mp->is_add = (u8) is_add;
21805   mp->ipv = (u8) ipv;
21806   mp->l4_protocol = (u8) protocol;
21807   mp->l4_port = htons ((u16) port);
21808
21809   S (mp);
21810   W (ret);
21811   return ret;
21812 }
21813
21814 static void vl_api_ipsec_gre_tunnel_details_t_handler
21815   (vl_api_ipsec_gre_tunnel_details_t * mp)
21816 {
21817   vat_main_t *vam = &vat_main;
21818
21819   print (vam->ofp, "%11d%15U%15U%14d%14d",
21820          ntohl (mp->sw_if_index),
21821          format_ip4_address, &mp->src_address,
21822          format_ip4_address, &mp->dst_address,
21823          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21824 }
21825
21826 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21827   (vl_api_ipsec_gre_tunnel_details_t * mp)
21828 {
21829   vat_main_t *vam = &vat_main;
21830   vat_json_node_t *node = NULL;
21831   struct in_addr ip4;
21832
21833   if (VAT_JSON_ARRAY != vam->json_tree.type)
21834     {
21835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21836       vat_json_init_array (&vam->json_tree);
21837     }
21838   node = vat_json_array_add (&vam->json_tree);
21839
21840   vat_json_init_object (node);
21841   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21842   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21843   vat_json_object_add_ip4 (node, "src_address", ip4);
21844   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21845   vat_json_object_add_ip4 (node, "dst_address", ip4);
21846   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21847   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21848 }
21849
21850 static int
21851 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21852 {
21853   unformat_input_t *i = vam->input;
21854   vl_api_ipsec_gre_tunnel_dump_t *mp;
21855   vl_api_control_ping_t *mp_ping;
21856   u32 sw_if_index;
21857   u8 sw_if_index_set = 0;
21858   int ret;
21859
21860   /* Parse args required to build the message */
21861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21862     {
21863       if (unformat (i, "sw_if_index %d", &sw_if_index))
21864         sw_if_index_set = 1;
21865       else
21866         break;
21867     }
21868
21869   if (sw_if_index_set == 0)
21870     {
21871       sw_if_index = ~0;
21872     }
21873
21874   if (!vam->json_output)
21875     {
21876       print (vam->ofp, "%11s%15s%15s%14s%14s",
21877              "sw_if_index", "src_address", "dst_address",
21878              "local_sa_id", "remote_sa_id");
21879     }
21880
21881   /* Get list of gre-tunnel interfaces */
21882   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21883
21884   mp->sw_if_index = htonl (sw_if_index);
21885
21886   S (mp);
21887
21888   /* Use a control ping for synchronization */
21889   MPING (CONTROL_PING, mp_ping);
21890   S (mp_ping);
21891
21892   W (ret);
21893   return ret;
21894 }
21895
21896 static int
21897 api_delete_subif (vat_main_t * vam)
21898 {
21899   unformat_input_t *i = vam->input;
21900   vl_api_delete_subif_t *mp;
21901   u32 sw_if_index = ~0;
21902   int ret;
21903
21904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21905     {
21906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21907         ;
21908       if (unformat (i, "sw_if_index %d", &sw_if_index))
21909         ;
21910       else
21911         break;
21912     }
21913
21914   if (sw_if_index == ~0)
21915     {
21916       errmsg ("missing sw_if_index");
21917       return -99;
21918     }
21919
21920   /* Construct the API message */
21921   M (DELETE_SUBIF, mp);
21922   mp->sw_if_index = ntohl (sw_if_index);
21923
21924   S (mp);
21925   W (ret);
21926   return ret;
21927 }
21928
21929 #define foreach_pbb_vtr_op      \
21930 _("disable",  L2_VTR_DISABLED)  \
21931 _("pop",  L2_VTR_POP_2)         \
21932 _("push",  L2_VTR_PUSH_2)
21933
21934 static int
21935 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21936 {
21937   unformat_input_t *i = vam->input;
21938   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21939   u32 sw_if_index = ~0, vtr_op = ~0;
21940   u16 outer_tag = ~0;
21941   u8 dmac[6], smac[6];
21942   u8 dmac_set = 0, smac_set = 0;
21943   u16 vlanid = 0;
21944   u32 sid = ~0;
21945   u32 tmp;
21946   int ret;
21947
21948   /* Shut up coverity */
21949   clib_memset (dmac, 0, sizeof (dmac));
21950   clib_memset (smac, 0, sizeof (smac));
21951
21952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21953     {
21954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21955         ;
21956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21957         ;
21958       else if (unformat (i, "vtr_op %d", &vtr_op))
21959         ;
21960 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21961       foreach_pbb_vtr_op
21962 #undef _
21963         else if (unformat (i, "translate_pbb_stag"))
21964         {
21965           if (unformat (i, "%d", &tmp))
21966             {
21967               vtr_op = L2_VTR_TRANSLATE_2_1;
21968               outer_tag = tmp;
21969             }
21970           else
21971             {
21972               errmsg
21973                 ("translate_pbb_stag operation requires outer tag definition");
21974               return -99;
21975             }
21976         }
21977       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21978         dmac_set++;
21979       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21980         smac_set++;
21981       else if (unformat (i, "sid %d", &sid))
21982         ;
21983       else if (unformat (i, "vlanid %d", &tmp))
21984         vlanid = tmp;
21985       else
21986         {
21987           clib_warning ("parse error '%U'", format_unformat_error, i);
21988           return -99;
21989         }
21990     }
21991
21992   if ((sw_if_index == ~0) || (vtr_op == ~0))
21993     {
21994       errmsg ("missing sw_if_index or vtr operation");
21995       return -99;
21996     }
21997   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21998       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21999     {
22000       errmsg
22001         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
22002       return -99;
22003     }
22004
22005   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
22006   mp->sw_if_index = ntohl (sw_if_index);
22007   mp->vtr_op = ntohl (vtr_op);
22008   mp->outer_tag = ntohs (outer_tag);
22009   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
22010   clib_memcpy (mp->b_smac, smac, sizeof (smac));
22011   mp->b_vlanid = ntohs (vlanid);
22012   mp->i_sid = ntohl (sid);
22013
22014   S (mp);
22015   W (ret);
22016   return ret;
22017 }
22018
22019 static int
22020 api_flow_classify_set_interface (vat_main_t * vam)
22021 {
22022   unformat_input_t *i = vam->input;
22023   vl_api_flow_classify_set_interface_t *mp;
22024   u32 sw_if_index;
22025   int sw_if_index_set;
22026   u32 ip4_table_index = ~0;
22027   u32 ip6_table_index = ~0;
22028   u8 is_add = 1;
22029   int ret;
22030
22031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22032     {
22033       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22034         sw_if_index_set = 1;
22035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22036         sw_if_index_set = 1;
22037       else if (unformat (i, "del"))
22038         is_add = 0;
22039       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22040         ;
22041       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22042         ;
22043       else
22044         {
22045           clib_warning ("parse error '%U'", format_unformat_error, i);
22046           return -99;
22047         }
22048     }
22049
22050   if (sw_if_index_set == 0)
22051     {
22052       errmsg ("missing interface name or sw_if_index");
22053       return -99;
22054     }
22055
22056   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22057
22058   mp->sw_if_index = ntohl (sw_if_index);
22059   mp->ip4_table_index = ntohl (ip4_table_index);
22060   mp->ip6_table_index = ntohl (ip6_table_index);
22061   mp->is_add = is_add;
22062
22063   S (mp);
22064   W (ret);
22065   return ret;
22066 }
22067
22068 static int
22069 api_flow_classify_dump (vat_main_t * vam)
22070 {
22071   unformat_input_t *i = vam->input;
22072   vl_api_flow_classify_dump_t *mp;
22073   vl_api_control_ping_t *mp_ping;
22074   u8 type = FLOW_CLASSIFY_N_TABLES;
22075   int ret;
22076
22077   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22078     ;
22079   else
22080     {
22081       errmsg ("classify table type must be specified");
22082       return -99;
22083     }
22084
22085   if (!vam->json_output)
22086     {
22087       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22088     }
22089
22090   M (FLOW_CLASSIFY_DUMP, mp);
22091   mp->type = type;
22092   /* send it... */
22093   S (mp);
22094
22095   /* Use a control ping for synchronization */
22096   MPING (CONTROL_PING, mp_ping);
22097   S (mp_ping);
22098
22099   /* Wait for a reply... */
22100   W (ret);
22101   return ret;
22102 }
22103
22104 static int
22105 api_feature_enable_disable (vat_main_t * vam)
22106 {
22107   unformat_input_t *i = vam->input;
22108   vl_api_feature_enable_disable_t *mp;
22109   u8 *arc_name = 0;
22110   u8 *feature_name = 0;
22111   u32 sw_if_index = ~0;
22112   u8 enable = 1;
22113   int ret;
22114
22115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22116     {
22117       if (unformat (i, "arc_name %s", &arc_name))
22118         ;
22119       else if (unformat (i, "feature_name %s", &feature_name))
22120         ;
22121       else
22122         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22123         ;
22124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22125         ;
22126       else if (unformat (i, "disable"))
22127         enable = 0;
22128       else
22129         break;
22130     }
22131
22132   if (arc_name == 0)
22133     {
22134       errmsg ("missing arc name");
22135       return -99;
22136     }
22137   if (vec_len (arc_name) > 63)
22138     {
22139       errmsg ("arc name too long");
22140     }
22141
22142   if (feature_name == 0)
22143     {
22144       errmsg ("missing feature name");
22145       return -99;
22146     }
22147   if (vec_len (feature_name) > 63)
22148     {
22149       errmsg ("feature name too long");
22150     }
22151
22152   if (sw_if_index == ~0)
22153     {
22154       errmsg ("missing interface name or sw_if_index");
22155       return -99;
22156     }
22157
22158   /* Construct the API message */
22159   M (FEATURE_ENABLE_DISABLE, mp);
22160   mp->sw_if_index = ntohl (sw_if_index);
22161   mp->enable = enable;
22162   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22163   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22164   vec_free (arc_name);
22165   vec_free (feature_name);
22166
22167   S (mp);
22168   W (ret);
22169   return ret;
22170 }
22171
22172 static int
22173 api_sw_interface_tag_add_del (vat_main_t * vam)
22174 {
22175   unformat_input_t *i = vam->input;
22176   vl_api_sw_interface_tag_add_del_t *mp;
22177   u32 sw_if_index = ~0;
22178   u8 *tag = 0;
22179   u8 enable = 1;
22180   int ret;
22181
22182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22183     {
22184       if (unformat (i, "tag %s", &tag))
22185         ;
22186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22187         ;
22188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22189         ;
22190       else if (unformat (i, "del"))
22191         enable = 0;
22192       else
22193         break;
22194     }
22195
22196   if (sw_if_index == ~0)
22197     {
22198       errmsg ("missing interface name or sw_if_index");
22199       return -99;
22200     }
22201
22202   if (enable && (tag == 0))
22203     {
22204       errmsg ("no tag specified");
22205       return -99;
22206     }
22207
22208   /* Construct the API message */
22209   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22210   mp->sw_if_index = ntohl (sw_if_index);
22211   mp->is_add = enable;
22212   if (enable)
22213     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22214   vec_free (tag);
22215
22216   S (mp);
22217   W (ret);
22218   return ret;
22219 }
22220
22221 static void vl_api_l2_xconnect_details_t_handler
22222   (vl_api_l2_xconnect_details_t * mp)
22223 {
22224   vat_main_t *vam = &vat_main;
22225
22226   print (vam->ofp, "%15d%15d",
22227          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22228 }
22229
22230 static void vl_api_l2_xconnect_details_t_handler_json
22231   (vl_api_l2_xconnect_details_t * mp)
22232 {
22233   vat_main_t *vam = &vat_main;
22234   vat_json_node_t *node = NULL;
22235
22236   if (VAT_JSON_ARRAY != vam->json_tree.type)
22237     {
22238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22239       vat_json_init_array (&vam->json_tree);
22240     }
22241   node = vat_json_array_add (&vam->json_tree);
22242
22243   vat_json_init_object (node);
22244   vat_json_object_add_uint (node, "rx_sw_if_index",
22245                             ntohl (mp->rx_sw_if_index));
22246   vat_json_object_add_uint (node, "tx_sw_if_index",
22247                             ntohl (mp->tx_sw_if_index));
22248 }
22249
22250 static int
22251 api_l2_xconnect_dump (vat_main_t * vam)
22252 {
22253   vl_api_l2_xconnect_dump_t *mp;
22254   vl_api_control_ping_t *mp_ping;
22255   int ret;
22256
22257   if (!vam->json_output)
22258     {
22259       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22260     }
22261
22262   M (L2_XCONNECT_DUMP, mp);
22263
22264   S (mp);
22265
22266   /* Use a control ping for synchronization */
22267   MPING (CONTROL_PING, mp_ping);
22268   S (mp_ping);
22269
22270   W (ret);
22271   return ret;
22272 }
22273
22274 static int
22275 api_hw_interface_set_mtu (vat_main_t * vam)
22276 {
22277   unformat_input_t *i = vam->input;
22278   vl_api_hw_interface_set_mtu_t *mp;
22279   u32 sw_if_index = ~0;
22280   u32 mtu = 0;
22281   int ret;
22282
22283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22284     {
22285       if (unformat (i, "mtu %d", &mtu))
22286         ;
22287       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22288         ;
22289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22290         ;
22291       else
22292         break;
22293     }
22294
22295   if (sw_if_index == ~0)
22296     {
22297       errmsg ("missing interface name or sw_if_index");
22298       return -99;
22299     }
22300
22301   if (mtu == 0)
22302     {
22303       errmsg ("no mtu specified");
22304       return -99;
22305     }
22306
22307   /* Construct the API message */
22308   M (HW_INTERFACE_SET_MTU, mp);
22309   mp->sw_if_index = ntohl (sw_if_index);
22310   mp->mtu = ntohs ((u16) mtu);
22311
22312   S (mp);
22313   W (ret);
22314   return ret;
22315 }
22316
22317 static int
22318 api_p2p_ethernet_add (vat_main_t * vam)
22319 {
22320   unformat_input_t *i = vam->input;
22321   vl_api_p2p_ethernet_add_t *mp;
22322   u32 parent_if_index = ~0;
22323   u32 sub_id = ~0;
22324   u8 remote_mac[6];
22325   u8 mac_set = 0;
22326   int ret;
22327
22328   clib_memset (remote_mac, 0, sizeof (remote_mac));
22329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22330     {
22331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22332         ;
22333       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22334         ;
22335       else
22336         if (unformat
22337             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22338         mac_set++;
22339       else if (unformat (i, "sub_id %d", &sub_id))
22340         ;
22341       else
22342         {
22343           clib_warning ("parse error '%U'", format_unformat_error, i);
22344           return -99;
22345         }
22346     }
22347
22348   if (parent_if_index == ~0)
22349     {
22350       errmsg ("missing interface name or sw_if_index");
22351       return -99;
22352     }
22353   if (mac_set == 0)
22354     {
22355       errmsg ("missing remote mac address");
22356       return -99;
22357     }
22358   if (sub_id == ~0)
22359     {
22360       errmsg ("missing sub-interface id");
22361       return -99;
22362     }
22363
22364   M (P2P_ETHERNET_ADD, mp);
22365   mp->parent_if_index = ntohl (parent_if_index);
22366   mp->subif_id = ntohl (sub_id);
22367   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22368
22369   S (mp);
22370   W (ret);
22371   return ret;
22372 }
22373
22374 static int
22375 api_p2p_ethernet_del (vat_main_t * vam)
22376 {
22377   unformat_input_t *i = vam->input;
22378   vl_api_p2p_ethernet_del_t *mp;
22379   u32 parent_if_index = ~0;
22380   u8 remote_mac[6];
22381   u8 mac_set = 0;
22382   int ret;
22383
22384   clib_memset (remote_mac, 0, sizeof (remote_mac));
22385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22386     {
22387       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22388         ;
22389       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22390         ;
22391       else
22392         if (unformat
22393             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22394         mac_set++;
22395       else
22396         {
22397           clib_warning ("parse error '%U'", format_unformat_error, i);
22398           return -99;
22399         }
22400     }
22401
22402   if (parent_if_index == ~0)
22403     {
22404       errmsg ("missing interface name or sw_if_index");
22405       return -99;
22406     }
22407   if (mac_set == 0)
22408     {
22409       errmsg ("missing remote mac address");
22410       return -99;
22411     }
22412
22413   M (P2P_ETHERNET_DEL, mp);
22414   mp->parent_if_index = ntohl (parent_if_index);
22415   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22416
22417   S (mp);
22418   W (ret);
22419   return ret;
22420 }
22421
22422 static int
22423 api_lldp_config (vat_main_t * vam)
22424 {
22425   unformat_input_t *i = vam->input;
22426   vl_api_lldp_config_t *mp;
22427   int tx_hold = 0;
22428   int tx_interval = 0;
22429   u8 *sys_name = NULL;
22430   int ret;
22431
22432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22433     {
22434       if (unformat (i, "system-name %s", &sys_name))
22435         ;
22436       else if (unformat (i, "tx-hold %d", &tx_hold))
22437         ;
22438       else if (unformat (i, "tx-interval %d", &tx_interval))
22439         ;
22440       else
22441         {
22442           clib_warning ("parse error '%U'", format_unformat_error, i);
22443           return -99;
22444         }
22445     }
22446
22447   vec_add1 (sys_name, 0);
22448
22449   M (LLDP_CONFIG, mp);
22450   mp->tx_hold = htonl (tx_hold);
22451   mp->tx_interval = htonl (tx_interval);
22452   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22453   vec_free (sys_name);
22454
22455   S (mp);
22456   W (ret);
22457   return ret;
22458 }
22459
22460 static int
22461 api_sw_interface_set_lldp (vat_main_t * vam)
22462 {
22463   unformat_input_t *i = vam->input;
22464   vl_api_sw_interface_set_lldp_t *mp;
22465   u32 sw_if_index = ~0;
22466   u32 enable = 1;
22467   u8 *port_desc = NULL, *mgmt_oid = NULL;
22468   ip4_address_t ip4_addr;
22469   ip6_address_t ip6_addr;
22470   int ret;
22471
22472   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22473   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22474
22475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22476     {
22477       if (unformat (i, "disable"))
22478         enable = 0;
22479       else
22480         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22481         ;
22482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22483         ;
22484       else if (unformat (i, "port-desc %s", &port_desc))
22485         ;
22486       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22487         ;
22488       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22489         ;
22490       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22491         ;
22492       else
22493         break;
22494     }
22495
22496   if (sw_if_index == ~0)
22497     {
22498       errmsg ("missing interface name or sw_if_index");
22499       return -99;
22500     }
22501
22502   /* Construct the API message */
22503   vec_add1 (port_desc, 0);
22504   vec_add1 (mgmt_oid, 0);
22505   M (SW_INTERFACE_SET_LLDP, mp);
22506   mp->sw_if_index = ntohl (sw_if_index);
22507   mp->enable = enable;
22508   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22509   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22510   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22511   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22512   vec_free (port_desc);
22513   vec_free (mgmt_oid);
22514
22515   S (mp);
22516   W (ret);
22517   return ret;
22518 }
22519
22520 static int
22521 api_tcp_configure_src_addresses (vat_main_t * vam)
22522 {
22523   vl_api_tcp_configure_src_addresses_t *mp;
22524   unformat_input_t *i = vam->input;
22525   ip4_address_t v4first, v4last;
22526   ip6_address_t v6first, v6last;
22527   u8 range_set = 0;
22528   u32 vrf_id = 0;
22529   int ret;
22530
22531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22532     {
22533       if (unformat (i, "%U - %U",
22534                     unformat_ip4_address, &v4first,
22535                     unformat_ip4_address, &v4last))
22536         {
22537           if (range_set)
22538             {
22539               errmsg ("one range per message (range already set)");
22540               return -99;
22541             }
22542           range_set = 1;
22543         }
22544       else if (unformat (i, "%U - %U",
22545                          unformat_ip6_address, &v6first,
22546                          unformat_ip6_address, &v6last))
22547         {
22548           if (range_set)
22549             {
22550               errmsg ("one range per message (range already set)");
22551               return -99;
22552             }
22553           range_set = 2;
22554         }
22555       else if (unformat (i, "vrf %d", &vrf_id))
22556         ;
22557       else
22558         break;
22559     }
22560
22561   if (range_set == 0)
22562     {
22563       errmsg ("address range not set");
22564       return -99;
22565     }
22566
22567   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22568   mp->vrf_id = ntohl (vrf_id);
22569   /* ipv6? */
22570   if (range_set == 2)
22571     {
22572       mp->is_ipv6 = 1;
22573       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22574       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22575     }
22576   else
22577     {
22578       mp->is_ipv6 = 0;
22579       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22580       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22581     }
22582   S (mp);
22583   W (ret);
22584   return ret;
22585 }
22586
22587 static void vl_api_app_namespace_add_del_reply_t_handler
22588   (vl_api_app_namespace_add_del_reply_t * mp)
22589 {
22590   vat_main_t *vam = &vat_main;
22591   i32 retval = ntohl (mp->retval);
22592   if (vam->async_mode)
22593     {
22594       vam->async_errors += (retval < 0);
22595     }
22596   else
22597     {
22598       vam->retval = retval;
22599       if (retval == 0)
22600         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22601       vam->result_ready = 1;
22602     }
22603 }
22604
22605 static void vl_api_app_namespace_add_del_reply_t_handler_json
22606   (vl_api_app_namespace_add_del_reply_t * mp)
22607 {
22608   vat_main_t *vam = &vat_main;
22609   vat_json_node_t node;
22610
22611   vat_json_init_object (&node);
22612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22613   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22614
22615   vat_json_print (vam->ofp, &node);
22616   vat_json_free (&node);
22617
22618   vam->retval = ntohl (mp->retval);
22619   vam->result_ready = 1;
22620 }
22621
22622 static int
22623 api_app_namespace_add_del (vat_main_t * vam)
22624 {
22625   vl_api_app_namespace_add_del_t *mp;
22626   unformat_input_t *i = vam->input;
22627   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22628   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22629   u64 secret;
22630   int ret;
22631
22632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22633     {
22634       if (unformat (i, "id %_%v%_", &ns_id))
22635         ;
22636       else if (unformat (i, "secret %lu", &secret))
22637         secret_set = 1;
22638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22639         sw_if_index_set = 1;
22640       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22641         ;
22642       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22643         ;
22644       else
22645         break;
22646     }
22647   if (!ns_id || !secret_set || !sw_if_index_set)
22648     {
22649       errmsg ("namespace id, secret and sw_if_index must be set");
22650       return -99;
22651     }
22652   if (vec_len (ns_id) > 64)
22653     {
22654       errmsg ("namespace id too long");
22655       return -99;
22656     }
22657   M (APP_NAMESPACE_ADD_DEL, mp);
22658
22659   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22660   mp->namespace_id_len = vec_len (ns_id);
22661   mp->secret = clib_host_to_net_u64 (secret);
22662   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22663   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22664   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22665   vec_free (ns_id);
22666   S (mp);
22667   W (ret);
22668   return ret;
22669 }
22670
22671 static int
22672 api_sock_init_shm (vat_main_t * vam)
22673 {
22674 #if VPP_API_TEST_BUILTIN == 0
22675   unformat_input_t *i = vam->input;
22676   vl_api_shm_elem_config_t *config = 0;
22677   u64 size = 64 << 20;
22678   int rv;
22679
22680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22681     {
22682       if (unformat (i, "size %U", unformat_memory_size, &size))
22683         ;
22684       else
22685         break;
22686     }
22687
22688   /*
22689    * Canned custom ring allocator config.
22690    * Should probably parse all of this
22691    */
22692   vec_validate (config, 6);
22693   config[0].type = VL_API_VLIB_RING;
22694   config[0].size = 256;
22695   config[0].count = 32;
22696
22697   config[1].type = VL_API_VLIB_RING;
22698   config[1].size = 1024;
22699   config[1].count = 16;
22700
22701   config[2].type = VL_API_VLIB_RING;
22702   config[2].size = 4096;
22703   config[2].count = 2;
22704
22705   config[3].type = VL_API_CLIENT_RING;
22706   config[3].size = 256;
22707   config[3].count = 32;
22708
22709   config[4].type = VL_API_CLIENT_RING;
22710   config[4].size = 1024;
22711   config[4].count = 16;
22712
22713   config[5].type = VL_API_CLIENT_RING;
22714   config[5].size = 4096;
22715   config[5].count = 2;
22716
22717   config[6].type = VL_API_QUEUE;
22718   config[6].count = 128;
22719   config[6].size = sizeof (uword);
22720
22721   rv = vl_socket_client_init_shm (config);
22722   if (!rv)
22723     vam->client_index_invalid = 1;
22724   return rv;
22725 #else
22726   return -99;
22727 #endif
22728 }
22729
22730 static int
22731 api_dns_enable_disable (vat_main_t * vam)
22732 {
22733   unformat_input_t *line_input = vam->input;
22734   vl_api_dns_enable_disable_t *mp;
22735   u8 enable_disable = 1;
22736   int ret;
22737
22738   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22739     {
22740       if (unformat (line_input, "disable"))
22741         enable_disable = 0;
22742       if (unformat (line_input, "enable"))
22743         enable_disable = 1;
22744       else
22745         break;
22746     }
22747
22748   /* Construct the API message */
22749   M (DNS_ENABLE_DISABLE, mp);
22750   mp->enable = enable_disable;
22751
22752   /* send it... */
22753   S (mp);
22754   /* Wait for the reply */
22755   W (ret);
22756   return ret;
22757 }
22758
22759 static int
22760 api_dns_resolve_name (vat_main_t * vam)
22761 {
22762   unformat_input_t *line_input = vam->input;
22763   vl_api_dns_resolve_name_t *mp;
22764   u8 *name = 0;
22765   int ret;
22766
22767   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22768     {
22769       if (unformat (line_input, "%s", &name))
22770         ;
22771       else
22772         break;
22773     }
22774
22775   if (vec_len (name) > 127)
22776     {
22777       errmsg ("name too long");
22778       return -99;
22779     }
22780
22781   /* Construct the API message */
22782   M (DNS_RESOLVE_NAME, mp);
22783   memcpy (mp->name, name, vec_len (name));
22784   vec_free (name);
22785
22786   /* send it... */
22787   S (mp);
22788   /* Wait for the reply */
22789   W (ret);
22790   return ret;
22791 }
22792
22793 static int
22794 api_dns_resolve_ip (vat_main_t * vam)
22795 {
22796   unformat_input_t *line_input = vam->input;
22797   vl_api_dns_resolve_ip_t *mp;
22798   int is_ip6 = -1;
22799   ip4_address_t addr4;
22800   ip6_address_t addr6;
22801   int ret;
22802
22803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22804     {
22805       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22806         is_ip6 = 1;
22807       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22808         is_ip6 = 0;
22809       else
22810         break;
22811     }
22812
22813   if (is_ip6 == -1)
22814     {
22815       errmsg ("missing address");
22816       return -99;
22817     }
22818
22819   /* Construct the API message */
22820   M (DNS_RESOLVE_IP, mp);
22821   mp->is_ip6 = is_ip6;
22822   if (is_ip6)
22823     memcpy (mp->address, &addr6, sizeof (addr6));
22824   else
22825     memcpy (mp->address, &addr4, sizeof (addr4));
22826
22827   /* send it... */
22828   S (mp);
22829   /* Wait for the reply */
22830   W (ret);
22831   return ret;
22832 }
22833
22834 static int
22835 api_dns_name_server_add_del (vat_main_t * vam)
22836 {
22837   unformat_input_t *i = vam->input;
22838   vl_api_dns_name_server_add_del_t *mp;
22839   u8 is_add = 1;
22840   ip6_address_t ip6_server;
22841   ip4_address_t ip4_server;
22842   int ip6_set = 0;
22843   int ip4_set = 0;
22844   int ret = 0;
22845
22846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22847     {
22848       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22849         ip6_set = 1;
22850       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22851         ip4_set = 1;
22852       else if (unformat (i, "del"))
22853         is_add = 0;
22854       else
22855         {
22856           clib_warning ("parse error '%U'", format_unformat_error, i);
22857           return -99;
22858         }
22859     }
22860
22861   if (ip4_set && ip6_set)
22862     {
22863       errmsg ("Only one server address allowed per message");
22864       return -99;
22865     }
22866   if ((ip4_set + ip6_set) == 0)
22867     {
22868       errmsg ("Server address required");
22869       return -99;
22870     }
22871
22872   /* Construct the API message */
22873   M (DNS_NAME_SERVER_ADD_DEL, mp);
22874
22875   if (ip6_set)
22876     {
22877       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22878       mp->is_ip6 = 1;
22879     }
22880   else
22881     {
22882       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22883       mp->is_ip6 = 0;
22884     }
22885
22886   mp->is_add = is_add;
22887
22888   /* send it... */
22889   S (mp);
22890
22891   /* Wait for a reply, return good/bad news  */
22892   W (ret);
22893   return ret;
22894 }
22895
22896 static void
22897 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22898 {
22899   vat_main_t *vam = &vat_main;
22900
22901   if (mp->is_ip4)
22902     {
22903       print (vam->ofp,
22904              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22905              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22906              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22907              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22908              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22909              clib_net_to_host_u32 (mp->action_index), mp->tag);
22910     }
22911   else
22912     {
22913       print (vam->ofp,
22914              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22915              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22916              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22917              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22918              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22919              clib_net_to_host_u32 (mp->action_index), mp->tag);
22920     }
22921 }
22922
22923 static void
22924 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22925                                              mp)
22926 {
22927   vat_main_t *vam = &vat_main;
22928   vat_json_node_t *node = NULL;
22929   struct in6_addr ip6;
22930   struct in_addr ip4;
22931
22932   if (VAT_JSON_ARRAY != vam->json_tree.type)
22933     {
22934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22935       vat_json_init_array (&vam->json_tree);
22936     }
22937   node = vat_json_array_add (&vam->json_tree);
22938   vat_json_init_object (node);
22939
22940   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22941   vat_json_object_add_uint (node, "appns_index",
22942                             clib_net_to_host_u32 (mp->appns_index));
22943   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22944   vat_json_object_add_uint (node, "scope", mp->scope);
22945   vat_json_object_add_uint (node, "action_index",
22946                             clib_net_to_host_u32 (mp->action_index));
22947   vat_json_object_add_uint (node, "lcl_port",
22948                             clib_net_to_host_u16 (mp->lcl_port));
22949   vat_json_object_add_uint (node, "rmt_port",
22950                             clib_net_to_host_u16 (mp->rmt_port));
22951   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22952   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22953   vat_json_object_add_string_copy (node, "tag", mp->tag);
22954   if (mp->is_ip4)
22955     {
22956       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22957       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22958       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22959       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22960     }
22961   else
22962     {
22963       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22964       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22965       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22966       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22967     }
22968 }
22969
22970 static int
22971 api_session_rule_add_del (vat_main_t * vam)
22972 {
22973   vl_api_session_rule_add_del_t *mp;
22974   unformat_input_t *i = vam->input;
22975   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22976   u32 appns_index = 0, scope = 0;
22977   ip4_address_t lcl_ip4, rmt_ip4;
22978   ip6_address_t lcl_ip6, rmt_ip6;
22979   u8 is_ip4 = 1, conn_set = 0;
22980   u8 is_add = 1, *tag = 0;
22981   int ret;
22982
22983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22984     {
22985       if (unformat (i, "del"))
22986         is_add = 0;
22987       else if (unformat (i, "add"))
22988         ;
22989       else if (unformat (i, "proto tcp"))
22990         proto = 0;
22991       else if (unformat (i, "proto udp"))
22992         proto = 1;
22993       else if (unformat (i, "appns %d", &appns_index))
22994         ;
22995       else if (unformat (i, "scope %d", &scope))
22996         ;
22997       else if (unformat (i, "tag %_%v%_", &tag))
22998         ;
22999       else
23000         if (unformat
23001             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
23002              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
23003              &rmt_port))
23004         {
23005           is_ip4 = 1;
23006           conn_set = 1;
23007         }
23008       else
23009         if (unformat
23010             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
23011              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
23012              &rmt_port))
23013         {
23014           is_ip4 = 0;
23015           conn_set = 1;
23016         }
23017       else if (unformat (i, "action %d", &action))
23018         ;
23019       else
23020         break;
23021     }
23022   if (proto == ~0 || !conn_set || action == ~0)
23023     {
23024       errmsg ("transport proto, connection and action must be set");
23025       return -99;
23026     }
23027
23028   if (scope > 3)
23029     {
23030       errmsg ("scope should be 0-3");
23031       return -99;
23032     }
23033
23034   M (SESSION_RULE_ADD_DEL, mp);
23035
23036   mp->is_ip4 = is_ip4;
23037   mp->transport_proto = proto;
23038   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23039   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23040   mp->lcl_plen = lcl_plen;
23041   mp->rmt_plen = rmt_plen;
23042   mp->action_index = clib_host_to_net_u32 (action);
23043   mp->appns_index = clib_host_to_net_u32 (appns_index);
23044   mp->scope = scope;
23045   mp->is_add = is_add;
23046   if (is_ip4)
23047     {
23048       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23049       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23050     }
23051   else
23052     {
23053       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23054       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23055     }
23056   if (tag)
23057     {
23058       clib_memcpy (mp->tag, tag, vec_len (tag));
23059       vec_free (tag);
23060     }
23061
23062   S (mp);
23063   W (ret);
23064   return ret;
23065 }
23066
23067 static int
23068 api_session_rules_dump (vat_main_t * vam)
23069 {
23070   vl_api_session_rules_dump_t *mp;
23071   vl_api_control_ping_t *mp_ping;
23072   int ret;
23073
23074   if (!vam->json_output)
23075     {
23076       print (vam->ofp, "%=20s", "Session Rules");
23077     }
23078
23079   M (SESSION_RULES_DUMP, mp);
23080   /* send it... */
23081   S (mp);
23082
23083   /* Use a control ping for synchronization */
23084   MPING (CONTROL_PING, mp_ping);
23085   S (mp_ping);
23086
23087   /* Wait for a reply... */
23088   W (ret);
23089   return ret;
23090 }
23091
23092 static int
23093 api_ip_container_proxy_add_del (vat_main_t * vam)
23094 {
23095   vl_api_ip_container_proxy_add_del_t *mp;
23096   unformat_input_t *i = vam->input;
23097   u32 plen = ~0, sw_if_index = ~0;
23098   ip4_address_t ip4;
23099   ip6_address_t ip6;
23100   u8 is_ip4 = 1;
23101   u8 is_add = 1;
23102   int ret;
23103
23104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23105     {
23106       if (unformat (i, "del"))
23107         is_add = 0;
23108       else if (unformat (i, "add"))
23109         ;
23110       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23111         {
23112           is_ip4 = 1;
23113           plen = 32;
23114         }
23115       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23116         {
23117           is_ip4 = 0;
23118           plen = 128;
23119         }
23120       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23121         ;
23122       else
23123         break;
23124     }
23125   if (sw_if_index == ~0 || plen == ~0)
23126     {
23127       errmsg ("address and sw_if_index must be set");
23128       return -99;
23129     }
23130
23131   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23132
23133   mp->is_ip4 = is_ip4;
23134   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23135   mp->plen = plen;
23136   mp->is_add = is_add;
23137   if (is_ip4)
23138     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23139   else
23140     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23141
23142   S (mp);
23143   W (ret);
23144   return ret;
23145 }
23146
23147 static int
23148 api_qos_record_enable_disable (vat_main_t * vam)
23149 {
23150   unformat_input_t *i = vam->input;
23151   vl_api_qos_record_enable_disable_t *mp;
23152   u32 sw_if_index, qs = 0xff;
23153   u8 sw_if_index_set = 0;
23154   u8 enable = 1;
23155   int ret;
23156
23157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23158     {
23159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23160         sw_if_index_set = 1;
23161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23162         sw_if_index_set = 1;
23163       else if (unformat (i, "%U", unformat_qos_source, &qs))
23164         ;
23165       else if (unformat (i, "disable"))
23166         enable = 0;
23167       else
23168         {
23169           clib_warning ("parse error '%U'", format_unformat_error, i);
23170           return -99;
23171         }
23172     }
23173
23174   if (sw_if_index_set == 0)
23175     {
23176       errmsg ("missing interface name or sw_if_index");
23177       return -99;
23178     }
23179   if (qs == 0xff)
23180     {
23181       errmsg ("input location must be specified");
23182       return -99;
23183     }
23184
23185   M (QOS_RECORD_ENABLE_DISABLE, mp);
23186
23187   mp->sw_if_index = ntohl (sw_if_index);
23188   mp->input_source = qs;
23189   mp->enable = enable;
23190
23191   S (mp);
23192   W (ret);
23193   return ret;
23194 }
23195
23196
23197 static int
23198 q_or_quit (vat_main_t * vam)
23199 {
23200 #if VPP_API_TEST_BUILTIN == 0
23201   longjmp (vam->jump_buf, 1);
23202 #endif
23203   return 0;                     /* not so much */
23204 }
23205
23206 static int
23207 q (vat_main_t * vam)
23208 {
23209   return q_or_quit (vam);
23210 }
23211
23212 static int
23213 quit (vat_main_t * vam)
23214 {
23215   return q_or_quit (vam);
23216 }
23217
23218 static int
23219 comment (vat_main_t * vam)
23220 {
23221   return 0;
23222 }
23223
23224 static int
23225 statseg (vat_main_t * vam)
23226 {
23227   ssvm_private_t *ssvmp = &vam->stat_segment;
23228   ssvm_shared_header_t *shared_header = ssvmp->sh;
23229   vlib_counter_t **counters;
23230   u64 thread0_index1_packets;
23231   u64 thread0_index1_bytes;
23232   f64 vector_rate, input_rate;
23233   uword *p;
23234
23235   uword *counter_vector_by_name;
23236   if (vam->stat_segment_lockp == 0)
23237     {
23238       errmsg ("Stat segment not mapped...");
23239       return -99;
23240     }
23241
23242   /* look up "/if/rx for sw_if_index 1 as a test */
23243
23244   clib_spinlock_lock (vam->stat_segment_lockp);
23245
23246   counter_vector_by_name = (uword *) shared_header->opaque[1];
23247
23248   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23249   if (p == 0)
23250     {
23251       clib_spinlock_unlock (vam->stat_segment_lockp);
23252       errmsg ("/if/tx not found?");
23253       return -99;
23254     }
23255
23256   /* Fish per-thread vector of combined counters from shared memory */
23257   counters = (vlib_counter_t **) p[0];
23258
23259   if (vec_len (counters[0]) < 2)
23260     {
23261       clib_spinlock_unlock (vam->stat_segment_lockp);
23262       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23263       return -99;
23264     }
23265
23266   /* Read thread 0 sw_if_index 1 counter */
23267   thread0_index1_packets = counters[0][1].packets;
23268   thread0_index1_bytes = counters[0][1].bytes;
23269
23270   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23271   if (p == 0)
23272     {
23273       clib_spinlock_unlock (vam->stat_segment_lockp);
23274       errmsg ("vector_rate not found?");
23275       return -99;
23276     }
23277
23278   vector_rate = *(f64 *) (p[0]);
23279   p = hash_get_mem (counter_vector_by_name, "input_rate");
23280   if (p == 0)
23281     {
23282       clib_spinlock_unlock (vam->stat_segment_lockp);
23283       errmsg ("input_rate not found?");
23284       return -99;
23285     }
23286   input_rate = *(f64 *) (p[0]);
23287
23288   clib_spinlock_unlock (vam->stat_segment_lockp);
23289
23290   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23291          vector_rate, input_rate);
23292   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23293          thread0_index1_packets, thread0_index1_bytes);
23294
23295   return 0;
23296 }
23297
23298 static int
23299 cmd_cmp (void *a1, void *a2)
23300 {
23301   u8 **c1 = a1;
23302   u8 **c2 = a2;
23303
23304   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23305 }
23306
23307 static int
23308 help (vat_main_t * vam)
23309 {
23310   u8 **cmds = 0;
23311   u8 *name = 0;
23312   hash_pair_t *p;
23313   unformat_input_t *i = vam->input;
23314   int j;
23315
23316   if (unformat (i, "%s", &name))
23317     {
23318       uword *hs;
23319
23320       vec_add1 (name, 0);
23321
23322       hs = hash_get_mem (vam->help_by_name, name);
23323       if (hs)
23324         print (vam->ofp, "usage: %s %s", name, hs[0]);
23325       else
23326         print (vam->ofp, "No such msg / command '%s'", name);
23327       vec_free (name);
23328       return 0;
23329     }
23330
23331   print (vam->ofp, "Help is available for the following:");
23332
23333     /* *INDENT-OFF* */
23334     hash_foreach_pair (p, vam->function_by_name,
23335     ({
23336       vec_add1 (cmds, (u8 *)(p->key));
23337     }));
23338     /* *INDENT-ON* */
23339
23340   vec_sort_with_function (cmds, cmd_cmp);
23341
23342   for (j = 0; j < vec_len (cmds); j++)
23343     print (vam->ofp, "%s", cmds[j]);
23344
23345   vec_free (cmds);
23346   return 0;
23347 }
23348
23349 static int
23350 set (vat_main_t * vam)
23351 {
23352   u8 *name = 0, *value = 0;
23353   unformat_input_t *i = vam->input;
23354
23355   if (unformat (i, "%s", &name))
23356     {
23357       /* The input buffer is a vector, not a string. */
23358       value = vec_dup (i->buffer);
23359       vec_delete (value, i->index, 0);
23360       /* Almost certainly has a trailing newline */
23361       if (value[vec_len (value) - 1] == '\n')
23362         value[vec_len (value) - 1] = 0;
23363       /* Make sure it's a proper string, one way or the other */
23364       vec_add1 (value, 0);
23365       (void) clib_macro_set_value (&vam->macro_main,
23366                                    (char *) name, (char *) value);
23367     }
23368   else
23369     errmsg ("usage: set <name> <value>");
23370
23371   vec_free (name);
23372   vec_free (value);
23373   return 0;
23374 }
23375
23376 static int
23377 unset (vat_main_t * vam)
23378 {
23379   u8 *name = 0;
23380
23381   if (unformat (vam->input, "%s", &name))
23382     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23383       errmsg ("unset: %s wasn't set", name);
23384   vec_free (name);
23385   return 0;
23386 }
23387
23388 typedef struct
23389 {
23390   u8 *name;
23391   u8 *value;
23392 } macro_sort_t;
23393
23394
23395 static int
23396 macro_sort_cmp (void *a1, void *a2)
23397 {
23398   macro_sort_t *s1 = a1;
23399   macro_sort_t *s2 = a2;
23400
23401   return strcmp ((char *) (s1->name), (char *) (s2->name));
23402 }
23403
23404 static int
23405 dump_macro_table (vat_main_t * vam)
23406 {
23407   macro_sort_t *sort_me = 0, *sm;
23408   int i;
23409   hash_pair_t *p;
23410
23411     /* *INDENT-OFF* */
23412     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23413     ({
23414       vec_add2 (sort_me, sm, 1);
23415       sm->name = (u8 *)(p->key);
23416       sm->value = (u8 *) (p->value[0]);
23417     }));
23418     /* *INDENT-ON* */
23419
23420   vec_sort_with_function (sort_me, macro_sort_cmp);
23421
23422   if (vec_len (sort_me))
23423     print (vam->ofp, "%-15s%s", "Name", "Value");
23424   else
23425     print (vam->ofp, "The macro table is empty...");
23426
23427   for (i = 0; i < vec_len (sort_me); i++)
23428     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23429   return 0;
23430 }
23431
23432 static int
23433 dump_node_table (vat_main_t * vam)
23434 {
23435   int i, j;
23436   vlib_node_t *node, *next_node;
23437
23438   if (vec_len (vam->graph_nodes) == 0)
23439     {
23440       print (vam->ofp, "Node table empty, issue get_node_graph...");
23441       return 0;
23442     }
23443
23444   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23445     {
23446       node = vam->graph_nodes[0][i];
23447       print (vam->ofp, "[%d] %s", i, node->name);
23448       for (j = 0; j < vec_len (node->next_nodes); j++)
23449         {
23450           if (node->next_nodes[j] != ~0)
23451             {
23452               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23453               print (vam->ofp, "  [%d] %s", j, next_node->name);
23454             }
23455         }
23456     }
23457   return 0;
23458 }
23459
23460 static int
23461 value_sort_cmp (void *a1, void *a2)
23462 {
23463   name_sort_t *n1 = a1;
23464   name_sort_t *n2 = a2;
23465
23466   if (n1->value < n2->value)
23467     return -1;
23468   if (n1->value > n2->value)
23469     return 1;
23470   return 0;
23471 }
23472
23473
23474 static int
23475 dump_msg_api_table (vat_main_t * vam)
23476 {
23477   api_main_t *am = &api_main;
23478   name_sort_t *nses = 0, *ns;
23479   hash_pair_t *hp;
23480   int i;
23481
23482   /* *INDENT-OFF* */
23483   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23484   ({
23485     vec_add2 (nses, ns, 1);
23486     ns->name = (u8 *)(hp->key);
23487     ns->value = (u32) hp->value[0];
23488   }));
23489   /* *INDENT-ON* */
23490
23491   vec_sort_with_function (nses, value_sort_cmp);
23492
23493   for (i = 0; i < vec_len (nses); i++)
23494     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23495   vec_free (nses);
23496   return 0;
23497 }
23498
23499 static int
23500 get_msg_id (vat_main_t * vam)
23501 {
23502   u8 *name_and_crc;
23503   u32 message_index;
23504
23505   if (unformat (vam->input, "%s", &name_and_crc))
23506     {
23507       message_index = vl_msg_api_get_msg_index (name_and_crc);
23508       if (message_index == ~0)
23509         {
23510           print (vam->ofp, " '%s' not found", name_and_crc);
23511           return 0;
23512         }
23513       print (vam->ofp, " '%s' has message index %d",
23514              name_and_crc, message_index);
23515       return 0;
23516     }
23517   errmsg ("name_and_crc required...");
23518   return 0;
23519 }
23520
23521 static int
23522 search_node_table (vat_main_t * vam)
23523 {
23524   unformat_input_t *line_input = vam->input;
23525   u8 *node_to_find;
23526   int j;
23527   vlib_node_t *node, *next_node;
23528   uword *p;
23529
23530   if (vam->graph_node_index_by_name == 0)
23531     {
23532       print (vam->ofp, "Node table empty, issue get_node_graph...");
23533       return 0;
23534     }
23535
23536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23537     {
23538       if (unformat (line_input, "%s", &node_to_find))
23539         {
23540           vec_add1 (node_to_find, 0);
23541           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23542           if (p == 0)
23543             {
23544               print (vam->ofp, "%s not found...", node_to_find);
23545               goto out;
23546             }
23547           node = vam->graph_nodes[0][p[0]];
23548           print (vam->ofp, "[%d] %s", p[0], node->name);
23549           for (j = 0; j < vec_len (node->next_nodes); j++)
23550             {
23551               if (node->next_nodes[j] != ~0)
23552                 {
23553                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23554                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23555                 }
23556             }
23557         }
23558
23559       else
23560         {
23561           clib_warning ("parse error '%U'", format_unformat_error,
23562                         line_input);
23563           return -99;
23564         }
23565
23566     out:
23567       vec_free (node_to_find);
23568
23569     }
23570
23571   return 0;
23572 }
23573
23574
23575 static int
23576 script (vat_main_t * vam)
23577 {
23578 #if (VPP_API_TEST_BUILTIN==0)
23579   u8 *s = 0;
23580   char *save_current_file;
23581   unformat_input_t save_input;
23582   jmp_buf save_jump_buf;
23583   u32 save_line_number;
23584
23585   FILE *new_fp, *save_ifp;
23586
23587   if (unformat (vam->input, "%s", &s))
23588     {
23589       new_fp = fopen ((char *) s, "r");
23590       if (new_fp == 0)
23591         {
23592           errmsg ("Couldn't open script file %s", s);
23593           vec_free (s);
23594           return -99;
23595         }
23596     }
23597   else
23598     {
23599       errmsg ("Missing script name");
23600       return -99;
23601     }
23602
23603   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23604   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23605   save_ifp = vam->ifp;
23606   save_line_number = vam->input_line_number;
23607   save_current_file = (char *) vam->current_file;
23608
23609   vam->input_line_number = 0;
23610   vam->ifp = new_fp;
23611   vam->current_file = s;
23612   do_one_file (vam);
23613
23614   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23615   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23616   vam->ifp = save_ifp;
23617   vam->input_line_number = save_line_number;
23618   vam->current_file = (u8 *) save_current_file;
23619   vec_free (s);
23620
23621   return 0;
23622 #else
23623   clib_warning ("use the exec command...");
23624   return -99;
23625 #endif
23626 }
23627
23628 static int
23629 echo (vat_main_t * vam)
23630 {
23631   print (vam->ofp, "%v", vam->input->buffer);
23632   return 0;
23633 }
23634
23635 /* List of API message constructors, CLI names map to api_xxx */
23636 #define foreach_vpe_api_msg                                             \
23637 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23638 _(sw_interface_dump,"")                                                 \
23639 _(sw_interface_set_flags,                                               \
23640   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23641 _(sw_interface_add_del_address,                                         \
23642   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23643 _(sw_interface_set_rx_mode,                                             \
23644   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23645 _(sw_interface_set_rx_placement,                                        \
23646   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23647 _(sw_interface_rx_placement_dump,                                       \
23648   "[<intfc> | sw_if_index <id>]")                                         \
23649 _(sw_interface_set_table,                                               \
23650   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23651 _(sw_interface_set_mpls_enable,                                         \
23652   "<intfc> | sw_if_index [disable | dis]")                              \
23653 _(sw_interface_set_vpath,                                               \
23654   "<intfc> | sw_if_index <id> enable | disable")                        \
23655 _(sw_interface_set_vxlan_bypass,                                        \
23656   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23657 _(sw_interface_set_geneve_bypass,                                       \
23658   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23659 _(sw_interface_set_l2_xconnect,                                         \
23660   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23661   "enable | disable")                                                   \
23662 _(sw_interface_set_l2_bridge,                                           \
23663   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23664   "[shg <split-horizon-group>] [bvi]\n"                                 \
23665   "enable | disable")                                                   \
23666 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23667 _(bridge_domain_add_del,                                                \
23668   "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") \
23669 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23670 _(l2fib_add_del,                                                        \
23671   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23672 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23673 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23674 _(l2_flags,                                                             \
23675   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23676 _(bridge_flags,                                                         \
23677   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23678 _(tap_connect,                                                          \
23679   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23680 _(tap_modify,                                                           \
23681   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23682 _(tap_delete,                                                           \
23683   "<vpp-if-name> | sw_if_index <id>")                                   \
23684 _(sw_interface_tap_dump, "")                                            \
23685 _(tap_create_v2,                                                        \
23686   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23687 _(tap_delete_v2,                                                        \
23688   "<vpp-if-name> | sw_if_index <id>")                                   \
23689 _(sw_interface_tap_v2_dump, "")                                         \
23690 _(bond_create,                                                          \
23691   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23692   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23693 _(bond_delete,                                                          \
23694   "<vpp-if-name> | sw_if_index <id>")                                   \
23695 _(bond_enslave,                                                         \
23696   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23697 _(bond_detach_slave,                                                    \
23698   "sw_if_index <n>")                                                    \
23699 _(sw_interface_bond_dump, "")                                           \
23700 _(sw_interface_slave_dump,                                              \
23701   "<vpp-if-name> | sw_if_index <id>")                                   \
23702 _(ip_table_add_del,                                                     \
23703   "table <n> [ipv6] [add | del]\n")                                     \
23704 _(ip_add_del_route,                                                     \
23705   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23706   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23707   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23708   "[multipath] [count <n>] [del]")                                      \
23709 _(ip_mroute_add_del,                                                    \
23710   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23711   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23712 _(mpls_table_add_del,                                                   \
23713   "table <n> [add | del]\n")                                            \
23714 _(mpls_route_add_del,                                                   \
23715   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23716   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23717   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23718   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23719   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23720   "[count <n>] [del]")                                                  \
23721 _(mpls_ip_bind_unbind,                                                  \
23722   "<label> <addr/len>")                                                 \
23723 _(mpls_tunnel_add_del,                                                  \
23724   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23725   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23726   "[l2-only]  [out-label <n>]")                                         \
23727 _(sr_mpls_policy_add,                                                   \
23728   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23729 _(sr_mpls_policy_del,                                                   \
23730   "bsid <id>")                                                          \
23731 _(bier_table_add_del,                                                   \
23732   "<label> <sub-domain> <set> <bsl> [del]")                             \
23733 _(bier_route_add_del,                                                   \
23734   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23735   "[<intfc> | sw_if_index <id>]"                                        \
23736   "[weight <n>] [del] [multipath]")                                     \
23737 _(proxy_arp_add_del,                                                    \
23738   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23739 _(proxy_arp_intfc_enable_disable,                                       \
23740   "<intfc> | sw_if_index <id> enable | disable")                        \
23741 _(sw_interface_set_unnumbered,                                          \
23742   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23743 _(ip_neighbor_add_del,                                                  \
23744   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23745   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23746 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23747 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23748   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23749   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23750   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23751 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23752 _(reset_fib, "vrf <n> [ipv6]")                                          \
23753 _(dhcp_proxy_config,                                                    \
23754   "svr <v46-address> src <v46-address>\n"                               \
23755    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23756 _(dhcp_proxy_set_vss,                                                   \
23757   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23758 _(dhcp_proxy_dump, "ip6")                                               \
23759 _(dhcp_client_config,                                                   \
23760   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23761 _(set_ip_flow_hash,                                                     \
23762   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23763 _(sw_interface_ip6_enable_disable,                                      \
23764   "<intfc> | sw_if_index <id> enable | disable")                        \
23765 _(sw_interface_ip6_set_link_local_address,                              \
23766   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23767 _(ip6nd_proxy_add_del,                                                  \
23768   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23769 _(ip6nd_proxy_dump, "")                                                 \
23770 _(sw_interface_ip6nd_ra_prefix,                                         \
23771   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23772   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23773   "[nolink] [isno]")                                                    \
23774 _(sw_interface_ip6nd_ra_config,                                         \
23775   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23776   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23777   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23778 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23779 _(l2_patch_add_del,                                                     \
23780   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23781   "enable | disable")                                                   \
23782 _(sr_localsid_add_del,                                                  \
23783   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23784   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23785 _(classify_add_del_table,                                               \
23786   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23787   " [del] [del-chain] mask <mask-value>\n"                              \
23788   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23789   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23790 _(classify_add_del_session,                                             \
23791   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23792   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23793   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23794   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23795 _(classify_set_interface_ip_table,                                      \
23796   "<intfc> | sw_if_index <nn> table <nn>")                              \
23797 _(classify_set_interface_l2_tables,                                     \
23798   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23799   "  [other-table <nn>]")                                               \
23800 _(get_node_index, "node <node-name")                                    \
23801 _(add_node_next, "node <node-name> next <next-node-name>")              \
23802 _(l2tpv3_create_tunnel,                                                 \
23803   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23804   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23805   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23806 _(l2tpv3_set_tunnel_cookies,                                            \
23807   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23808   "[new_remote_cookie <nn>]\n")                                         \
23809 _(l2tpv3_interface_enable_disable,                                      \
23810   "<intfc> | sw_if_index <nn> enable | disable")                        \
23811 _(l2tpv3_set_lookup_key,                                                \
23812   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23813 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23814 _(vxlan_offload_rx,                                                     \
23815   "hw { <interface name> | hw_if_index <nn>} "                          \
23816   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23817 _(vxlan_add_del_tunnel,                                                 \
23818   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23819   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23820   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23821 _(geneve_add_del_tunnel,                                                \
23822   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23823   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23824   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23825 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23826 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23827 _(gre_add_del_tunnel,                                                   \
23828   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23829   "[teb | erspan <session-id>] [del]")                                  \
23830 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23831 _(l2_fib_clear_table, "")                                               \
23832 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23833 _(l2_interface_vlan_tag_rewrite,                                        \
23834   "<intfc> | sw_if_index <nn> \n"                                       \
23835   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23836   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23837 _(create_vhost_user_if,                                                 \
23838         "socket <filename> [server] [renumber <dev_instance>] "         \
23839         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23840         "[mac <mac_address>]")                                          \
23841 _(modify_vhost_user_if,                                                 \
23842         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23843         "[server] [renumber <dev_instance>]")                           \
23844 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23845 _(sw_interface_vhost_user_dump, "")                                     \
23846 _(show_version, "")                                                     \
23847 _(show_threads, "")                                                     \
23848 _(vxlan_gpe_add_del_tunnel,                                             \
23849   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23850   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23851   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23852   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23853 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23854 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23855 _(interface_name_renumber,                                              \
23856   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23857 _(input_acl_set_interface,                                              \
23858   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23859   "  [l2-table <nn>] [del]")                                            \
23860 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23861 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23862   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23863 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23864 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23865 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23866 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23867 _(ip_dump, "ipv4 | ipv6")                                               \
23868 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23869 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23870   "  spid_id <n> ")                                                     \
23871 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23872   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23873   "  integ_alg <alg> integ_key <hex>")                                  \
23874 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23875   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23876   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23877   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23878 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23879 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23880   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23881   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23882   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23883   "  [instance <n>]")     \
23884 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23885 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23886   "  <alg> <hex>\n")                                                    \
23887 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23888 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23889 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23890   "(auth_data 0x<data> | auth_data <data>)")                            \
23891 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23892   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23893 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23894   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23895   "(local|remote)")                                                     \
23896 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23897 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23898 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23899 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23900 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23901 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23902 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23903 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23904 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23905 _(delete_loopback,"sw_if_index <nn>")                                   \
23906 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23907 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23908 _(want_interface_events,  "enable|disable")                             \
23909 _(want_stats,"enable|disable")                                          \
23910 _(get_first_msg_id, "client <name>")                                    \
23911 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23912 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23913   "fib-id <nn> [ip4][ip6][default]")                                    \
23914 _(get_node_graph, " ")                                                  \
23915 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23916 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23917 _(ioam_disable, "")                                                     \
23918 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23919                             " sw_if_index <sw_if_index> p <priority> "  \
23920                             "w <weight>] [del]")                        \
23921 _(one_add_del_locator, "locator-set <locator_name> "                    \
23922                         "iface <intf> | sw_if_index <sw_if_index> "     \
23923                         "p <priority> w <weight> [del]")                \
23924 _(one_add_del_local_eid,"vni <vni> eid "                                \
23925                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23926                          "locator-set <locator_name> [del]"             \
23927                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23928 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23929 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23930 _(one_enable_disable, "enable|disable")                                 \
23931 _(one_map_register_enable_disable, "enable|disable")                    \
23932 _(one_map_register_fallback_threshold, "<value>")                       \
23933 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23934 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23935                                "[seid <seid>] "                         \
23936                                "rloc <locator> p <prio> "               \
23937                                "w <weight> [rloc <loc> ... ] "          \
23938                                "action <action> [del-all]")             \
23939 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23940                           "<local-eid>")                                \
23941 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23942 _(one_use_petr, "ip-address> | disable")                                \
23943 _(one_map_request_mode, "src-dst|dst-only")                             \
23944 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23945 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23946 _(one_locator_set_dump, "[local | remote]")                             \
23947 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23948 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23949                        "[local] | [remote]")                            \
23950 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23951 _(one_ndp_bd_get, "")                                                   \
23952 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23953 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23954 _(one_l2_arp_bd_get, "")                                                \
23955 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23956 _(one_stats_enable_disable, "enable|disable")                           \
23957 _(show_one_stats_enable_disable, "")                                    \
23958 _(one_eid_table_vni_dump, "")                                           \
23959 _(one_eid_table_map_dump, "l2|l3")                                      \
23960 _(one_map_resolver_dump, "")                                            \
23961 _(one_map_server_dump, "")                                              \
23962 _(one_adjacencies_get, "vni <vni>")                                     \
23963 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23964 _(show_one_rloc_probe_state, "")                                        \
23965 _(show_one_map_register_state, "")                                      \
23966 _(show_one_status, "")                                                  \
23967 _(one_stats_dump, "")                                                   \
23968 _(one_stats_flush, "")                                                  \
23969 _(one_get_map_request_itr_rlocs, "")                                    \
23970 _(one_map_register_set_ttl, "<ttl>")                                    \
23971 _(one_set_transport_protocol, "udp|api")                                \
23972 _(one_get_transport_protocol, "")                                       \
23973 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23974 _(one_show_xtr_mode, "")                                                \
23975 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23976 _(one_show_pitr_mode, "")                                               \
23977 _(one_enable_disable_petr_mode, "enable|disable")                       \
23978 _(one_show_petr_mode, "")                                               \
23979 _(show_one_nsh_mapping, "")                                             \
23980 _(show_one_pitr, "")                                                    \
23981 _(show_one_use_petr, "")                                                \
23982 _(show_one_map_request_mode, "")                                        \
23983 _(show_one_map_register_ttl, "")                                        \
23984 _(show_one_map_register_fallback_threshold, "")                         \
23985 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23986                             " sw_if_index <sw_if_index> p <priority> "  \
23987                             "w <weight>] [del]")                        \
23988 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23989                         "iface <intf> | sw_if_index <sw_if_index> "     \
23990                         "p <priority> w <weight> [del]")                \
23991 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23992                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23993                          "locator-set <locator_name> [del]"             \
23994                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23995 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23996 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23997 _(lisp_enable_disable, "enable|disable")                                \
23998 _(lisp_map_register_enable_disable, "enable|disable")                   \
23999 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
24000 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
24001                                "[seid <seid>] "                         \
24002                                "rloc <locator> p <prio> "               \
24003                                "w <weight> [rloc <loc> ... ] "          \
24004                                "action <action> [del-all]")             \
24005 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
24006                           "<local-eid>")                                \
24007 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
24008 _(lisp_use_petr, "<ip-address> | disable")                              \
24009 _(lisp_map_request_mode, "src-dst|dst-only")                            \
24010 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
24011 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
24012 _(lisp_locator_set_dump, "[local | remote]")                            \
24013 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
24014 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
24015                        "[local] | [remote]")                            \
24016 _(lisp_eid_table_vni_dump, "")                                          \
24017 _(lisp_eid_table_map_dump, "l2|l3")                                     \
24018 _(lisp_map_resolver_dump, "")                                           \
24019 _(lisp_map_server_dump, "")                                             \
24020 _(lisp_adjacencies_get, "vni <vni>")                                    \
24021 _(gpe_fwd_entry_vnis_get, "")                                           \
24022 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
24023 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
24024                                 "[table <table-id>]")                   \
24025 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
24026 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
24027 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
24028 _(gpe_get_encap_mode, "")                                               \
24029 _(lisp_gpe_add_del_iface, "up|down")                                    \
24030 _(lisp_gpe_enable_disable, "enable|disable")                            \
24031 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24032   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24033 _(show_lisp_rloc_probe_state, "")                                       \
24034 _(show_lisp_map_register_state, "")                                     \
24035 _(show_lisp_status, "")                                                 \
24036 _(lisp_get_map_request_itr_rlocs, "")                                   \
24037 _(show_lisp_pitr, "")                                                   \
24038 _(show_lisp_use_petr, "")                                               \
24039 _(show_lisp_map_request_mode, "")                                       \
24040 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24041 _(af_packet_delete, "name <host interface name>")                       \
24042 _(af_packet_dump, "")                                                   \
24043 _(policer_add_del, "name <policer name> <params> [del]")                \
24044 _(policer_dump, "[name <policer name>]")                                \
24045 _(policer_classify_set_interface,                                       \
24046   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24047   "  [l2-table <nn>] [del]")                                            \
24048 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24049 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24050     "[master|slave]")                                                   \
24051 _(netmap_delete, "name <interface name>")                               \
24052 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24053 _(mpls_fib_dump, "")                                                    \
24054 _(classify_table_ids, "")                                               \
24055 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24056 _(classify_table_info, "table_id <nn>")                                 \
24057 _(classify_session_dump, "table_id <nn>")                               \
24058 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24059     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24060     "[template_interval <nn>] [udp_checksum]")                          \
24061 _(ipfix_exporter_dump, "")                                              \
24062 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24063 _(ipfix_classify_stream_dump, "")                                       \
24064 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24065 _(ipfix_classify_table_dump, "")                                        \
24066 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24067 _(sw_interface_span_dump, "[l2]")                                           \
24068 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24069 _(pg_create_interface, "if_id <nn>")                                    \
24070 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24071 _(pg_enable_disable, "[stream <id>] disable")                           \
24072 _(ip_source_and_port_range_check_add_del,                               \
24073   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24074 _(ip_source_and_port_range_check_interface_add_del,                     \
24075   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24076   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24077 _(ipsec_gre_add_del_tunnel,                                             \
24078   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24079 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24080 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24081 _(l2_interface_pbb_tag_rewrite,                                         \
24082   "<intfc> | sw_if_index <nn> \n"                                       \
24083   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24084   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24085 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24086 _(flow_classify_set_interface,                                          \
24087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24088 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24089 _(ip_fib_dump, "")                                                      \
24090 _(ip_mfib_dump, "")                                                     \
24091 _(ip6_fib_dump, "")                                                     \
24092 _(ip6_mfib_dump, "")                                                    \
24093 _(feature_enable_disable, "arc_name <arc_name> "                        \
24094   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24095 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24096 "[disable]")                                                            \
24097 _(l2_xconnect_dump, "")                                                 \
24098 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24099 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24100 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24101 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24102 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24103 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24104 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24105   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24106 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24107 _(sock_init_shm, "size <nnn>")                                          \
24108 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24109 _(dns_enable_disable, "[enable][disable]")                              \
24110 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24111 _(dns_resolve_name, "<hostname>")                                       \
24112 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24113 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24114 _(dns_resolve_name, "<hostname>")                                       \
24115 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24116   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24117 _(session_rules_dump, "")                                               \
24118 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24119 _(output_acl_set_interface,                                             \
24120   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24121   "  [l2-table <nn>] [del]")                                            \
24122 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24123
24124 /* List of command functions, CLI names map directly to functions */
24125 #define foreach_cli_function                                    \
24126 _(comment, "usage: comment <ignore-rest-of-line>")              \
24127 _(dump_interface_table, "usage: dump_interface_table")          \
24128 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24129 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24130 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24131 _(dump_stats_table, "usage: dump_stats_table")                  \
24132 _(dump_macro_table, "usage: dump_macro_table ")                 \
24133 _(dump_node_table, "usage: dump_node_table")                    \
24134 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24135 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24136 _(echo, "usage: echo <message>")                                \
24137 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24138 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24139 _(help, "usage: help")                                          \
24140 _(q, "usage: quit")                                             \
24141 _(quit, "usage: quit")                                          \
24142 _(search_node_table, "usage: search_node_table <name>...")      \
24143 _(set, "usage: set <variable-name> <value>")                    \
24144 _(script, "usage: script <file-name>")                          \
24145 _(statseg, "usage: statseg");                                   \
24146 _(unset, "usage: unset <variable-name>")
24147
24148 #define _(N,n)                                  \
24149     static void vl_api_##n##_t_handler_uni      \
24150     (vl_api_##n##_t * mp)                       \
24151     {                                           \
24152         vat_main_t * vam = &vat_main;           \
24153         if (vam->json_output) {                 \
24154             vl_api_##n##_t_handler_json(mp);    \
24155         } else {                                \
24156             vl_api_##n##_t_handler(mp);         \
24157         }                                       \
24158     }
24159 foreach_vpe_api_reply_msg;
24160 #if VPP_API_TEST_BUILTIN == 0
24161 foreach_standalone_reply_msg;
24162 #endif
24163 #undef _
24164
24165 void
24166 vat_api_hookup (vat_main_t * vam)
24167 {
24168 #define _(N,n)                                                  \
24169     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24170                            vl_api_##n##_t_handler_uni,          \
24171                            vl_noop_handler,                     \
24172                            vl_api_##n##_t_endian,               \
24173                            vl_api_##n##_t_print,                \
24174                            sizeof(vl_api_##n##_t), 1);
24175   foreach_vpe_api_reply_msg;
24176 #if VPP_API_TEST_BUILTIN == 0
24177   foreach_standalone_reply_msg;
24178 #endif
24179 #undef _
24180
24181 #if (VPP_API_TEST_BUILTIN==0)
24182   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24183
24184   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24185
24186   vam->function_by_name = hash_create_string (0, sizeof (uword));
24187
24188   vam->help_by_name = hash_create_string (0, sizeof (uword));
24189 #endif
24190
24191   /* API messages we can send */
24192 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24193   foreach_vpe_api_msg;
24194 #undef _
24195
24196   /* Help strings */
24197 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24198   foreach_vpe_api_msg;
24199 #undef _
24200
24201   /* CLI functions */
24202 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24203   foreach_cli_function;
24204 #undef _
24205
24206   /* Help strings */
24207 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24208   foreach_cli_function;
24209 #undef _
24210 }
24211
24212 #if VPP_API_TEST_BUILTIN
24213 static clib_error_t *
24214 vat_api_hookup_shim (vlib_main_t * vm)
24215 {
24216   vat_api_hookup (&vat_main);
24217   return 0;
24218 }
24219
24220 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24221 #endif
24222
24223 /*
24224  * fd.io coding-style-patch-verification: ON
24225  *
24226  * Local Variables:
24227  * eval: (c-set-style "gnu")
24228  * End:
24229  */