FIB path dump: fix next-hop-table ID for recursive routes
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 static uword
180 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
181 {
182   return 0;
183 }
184
185 /* Parse an IP4 address %d.%d.%d.%d. */
186 uword
187 unformat_ip4_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   unsigned a[4];
191
192   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
193     return 0;
194
195   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
196     return 0;
197
198   result[0] = a[0];
199   result[1] = a[1];
200   result[2] = a[2];
201   result[3] = a[3];
202
203   return 1;
204 }
205
206 uword
207 unformat_ethernet_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   u32 i, a[6];
211
212   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
213                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
214     return 0;
215
216   /* Check range. */
217   for (i = 0; i < 6; i++)
218     if (a[i] >= (1 << 8))
219       return 0;
220
221   for (i = 0; i < 6; i++)
222     result[i] = a[i];
223
224   return 1;
225 }
226
227 /* Returns ethernet type as an int in host byte order. */
228 uword
229 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
230                                         va_list * args)
231 {
232   u16 *result = va_arg (*args, u16 *);
233   int type;
234
235   /* Numeric type. */
236   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
237     {
238       if (type >= (1 << 16))
239         return 0;
240       *result = type;
241       return 1;
242     }
243   return 0;
244 }
245
246 /* Parse an IP6 address. */
247 uword
248 unformat_ip6_address (unformat_input_t * input, va_list * args)
249 {
250   ip6_address_t *result = va_arg (*args, ip6_address_t *);
251   u16 hex_quads[8];
252   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
253   uword c, n_colon, double_colon_index;
254
255   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
256   double_colon_index = ARRAY_LEN (hex_quads);
257   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
258     {
259       hex_digit = 16;
260       if (c >= '0' && c <= '9')
261         hex_digit = c - '0';
262       else if (c >= 'a' && c <= 'f')
263         hex_digit = c + 10 - 'a';
264       else if (c >= 'A' && c <= 'F')
265         hex_digit = c + 10 - 'A';
266       else if (c == ':' && n_colon < 2)
267         n_colon++;
268       else
269         {
270           unformat_put_input (input);
271           break;
272         }
273
274       /* Too many hex quads. */
275       if (n_hex_quads >= ARRAY_LEN (hex_quads))
276         return 0;
277
278       if (hex_digit < 16)
279         {
280           hex_quad = (hex_quad << 4) | hex_digit;
281
282           /* Hex quad must fit in 16 bits. */
283           if (n_hex_digits >= 4)
284             return 0;
285
286           n_colon = 0;
287           n_hex_digits++;
288         }
289
290       /* Save position of :: */
291       if (n_colon == 2)
292         {
293           /* More than one :: ? */
294           if (double_colon_index < ARRAY_LEN (hex_quads))
295             return 0;
296           double_colon_index = n_hex_quads;
297         }
298
299       if (n_colon > 0 && n_hex_digits > 0)
300         {
301           hex_quads[n_hex_quads++] = hex_quad;
302           hex_quad = 0;
303           n_hex_digits = 0;
304         }
305     }
306
307   if (n_hex_digits > 0)
308     hex_quads[n_hex_quads++] = hex_quad;
309
310   {
311     word i;
312
313     /* Expand :: to appropriate number of zero hex quads. */
314     if (double_colon_index < ARRAY_LEN (hex_quads))
315       {
316         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
317
318         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
319           hex_quads[n_zero + i] = hex_quads[i];
320
321         for (i = 0; i < n_zero; i++)
322           hex_quads[double_colon_index + i] = 0;
323
324         n_hex_quads = ARRAY_LEN (hex_quads);
325       }
326
327     /* Too few hex quads given. */
328     if (n_hex_quads < ARRAY_LEN (hex_quads))
329       return 0;
330
331     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
332       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
333
334     return 1;
335   }
336 }
337
338 uword
339 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
340 {
341   u32 *r = va_arg (*args, u32 *);
342
343   if (0);
344 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
345   foreach_ipsec_policy_action
346 #undef _
347     else
348     return 0;
349   return 1;
350 }
351
352 uword
353 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
354 {
355   u32 *r = va_arg (*args, u32 *);
356
357   if (0);
358 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
359   foreach_ipsec_crypto_alg
360 #undef _
361     else
362     return 0;
363   return 1;
364 }
365
366 u8 *
367 format_ipsec_crypto_alg (u8 * s, va_list * args)
368 {
369   u32 i = va_arg (*args, u32);
370   u8 *t = 0;
371
372   switch (i)
373     {
374 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
375       foreach_ipsec_crypto_alg
376 #undef _
377     default:
378       return format (s, "unknown");
379     }
380   return format (s, "%s", t);
381 }
382
383 uword
384 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
385 {
386   u32 *r = va_arg (*args, u32 *);
387
388   if (0);
389 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
390   foreach_ipsec_integ_alg
391 #undef _
392     else
393     return 0;
394   return 1;
395 }
396
397 u8 *
398 format_ipsec_integ_alg (u8 * s, va_list * args)
399 {
400   u32 i = va_arg (*args, u32);
401   u8 *t = 0;
402
403   switch (i)
404     {
405 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
406       foreach_ipsec_integ_alg
407 #undef _
408     default:
409       return format (s, "unknown");
410     }
411   return format (s, "%s", t);
412 }
413
414 uword
415 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
416 {
417   u32 *r = va_arg (*args, u32 *);
418
419   if (0);
420 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
421   foreach_ikev2_auth_method
422 #undef _
423     else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
435   foreach_ikev2_id_type
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441 #else /* VPP_API_TEST_BUILTIN == 1 */
442 static uword
443 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
444 {
445   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
446   vnet_main_t *vnm = vnet_get_main ();
447   u32 *result = va_arg (*args, u32 *);
448
449   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
450 }
451
452 static uword
453 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
454 {
455   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
456   vnet_main_t *vnm = vnet_get_main ();
457   u32 *result = va_arg (*args, u32 *);
458
459   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
460 }
461
462 #endif /* VPP_API_TEST_BUILTIN */
463
464 static uword
465 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
466 {
467   u8 *r = va_arg (*args, u8 *);
468
469   if (unformat (input, "kbps"))
470     *r = SSE2_QOS_RATE_KBPS;
471   else if (unformat (input, "pps"))
472     *r = SSE2_QOS_RATE_PPS;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_round_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "closest"))
484     *r = SSE2_QOS_ROUND_TO_CLOSEST;
485   else if (unformat (input, "up"))
486     *r = SSE2_QOS_ROUND_TO_UP;
487   else if (unformat (input, "down"))
488     *r = SSE2_QOS_ROUND_TO_DOWN;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "1r2c"))
500     *r = SSE2_QOS_POLICER_TYPE_1R2C;
501   else if (unformat (input, "1r3c"))
502     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
503   else if (unformat (input, "2r3c-2698"))
504     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
505   else if (unformat (input, "2r3c-4115"))
506     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
507   else if (unformat (input, "2r3c-mef5cf1"))
508     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
509   else
510     return 0;
511   return 1;
512 }
513
514 static uword
515 unformat_dscp (unformat_input_t * input, va_list * va)
516 {
517   u8 *r = va_arg (*va, u8 *);
518
519   if (0);
520 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
521   foreach_vnet_dscp
522 #undef _
523     else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_policer_action_type (unformat_input_t * input, va_list * va)
530 {
531   sse2_qos_pol_action_params_st *a
532     = va_arg (*va, sse2_qos_pol_action_params_st *);
533
534   if (unformat (input, "drop"))
535     a->action_type = SSE2_QOS_ACTION_DROP;
536   else if (unformat (input, "transmit"))
537     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
538   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
539     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
540   else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
547 {
548   u32 *r = va_arg (*va, u32 *);
549   u32 tid;
550
551   if (unformat (input, "ip4"))
552     tid = POLICER_CLASSIFY_TABLE_IP4;
553   else if (unformat (input, "ip6"))
554     tid = POLICER_CLASSIFY_TABLE_IP6;
555   else if (unformat (input, "l2"))
556     tid = POLICER_CLASSIFY_TABLE_L2;
557   else
558     return 0;
559
560   *r = tid;
561   return 1;
562 }
563
564 static uword
565 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
566 {
567   u32 *r = va_arg (*va, u32 *);
568   u32 tid;
569
570   if (unformat (input, "ip4"))
571     tid = FLOW_CLASSIFY_TABLE_IP4;
572   else if (unformat (input, "ip6"))
573     tid = FLOW_CLASSIFY_TABLE_IP6;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
582 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
583 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
584 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
585
586 #if (VPP_API_TEST_BUILTIN==0)
587 uword
588 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
589 {
590   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
591   mfib_itf_attribute_t attr;
592
593   old = *iflags;
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_long_names[attr]))
597       *iflags |= (1 << attr);
598   }
599   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_itf_flag_names[attr]))
602       *iflags |= (1 << attr);
603   }
604
605   return (old == *iflags ? 0 : 1);
606 }
607
608 uword
609 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
610 {
611   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
612   mfib_entry_attribute_t attr;
613
614   old = *eflags;
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_long_names[attr]))
618       *eflags |= (1 << attr);
619   }
620   FOR_EACH_MFIB_ATTRIBUTE (attr)
621   {
622     if (unformat (input, mfib_flag_names[attr]))
623       *eflags |= (1 << attr);
624   }
625
626   return (old == *eflags ? 0 : 1);
627 }
628
629 u8 *
630 format_ip4_address (u8 * s, va_list * args)
631 {
632   u8 *a = va_arg (*args, u8 *);
633   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
634 }
635
636 u8 *
637 format_ip6_address (u8 * s, va_list * args)
638 {
639   ip6_address_t *a = va_arg (*args, ip6_address_t *);
640   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
641
642   i_max_n_zero = ARRAY_LEN (a->as_u16);
643   max_n_zeros = 0;
644   i_first_zero = i_max_n_zero;
645   n_zeros = 0;
646   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
647     {
648       u32 is_zero = a->as_u16[i] == 0;
649       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
650         {
651           i_first_zero = i;
652           n_zeros = 0;
653         }
654       n_zeros += is_zero;
655       if ((!is_zero && n_zeros > max_n_zeros)
656           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
657         {
658           i_max_n_zero = i_first_zero;
659           max_n_zeros = n_zeros;
660           i_first_zero = ARRAY_LEN (a->as_u16);
661           n_zeros = 0;
662         }
663     }
664
665   last_double_colon = 0;
666   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
667     {
668       if (i == i_max_n_zero && max_n_zeros > 1)
669         {
670           s = format (s, "::");
671           i += max_n_zeros - 1;
672           last_double_colon = 1;
673         }
674       else
675         {
676           s = format (s, "%s%x",
677                       (last_double_colon || i == 0) ? "" : ":",
678                       clib_net_to_host_u16 (a->as_u16[i]));
679           last_double_colon = 0;
680         }
681     }
682
683   return s;
684 }
685
686 /* Format an IP46 address. */
687 u8 *
688 format_ip46_address (u8 * s, va_list * args)
689 {
690   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
691   ip46_type_t type = va_arg (*args, ip46_type_t);
692   int is_ip4 = 1;
693
694   switch (type)
695     {
696     case IP46_TYPE_ANY:
697       is_ip4 = ip46_address_is_ip4 (ip46);
698       break;
699     case IP46_TYPE_IP4:
700       is_ip4 = 1;
701       break;
702     case IP46_TYPE_IP6:
703       is_ip4 = 0;
704       break;
705     }
706
707   return is_ip4 ?
708     format (s, "%U", format_ip4_address, &ip46->ip4) :
709     format (s, "%U", format_ip6_address, &ip46->ip6);
710 }
711
712 u8 *
713 format_ethernet_address (u8 * s, va_list * args)
714 {
715   u8 *a = va_arg (*args, u8 *);
716
717   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
718                  a[0], a[1], a[2], a[3], a[4], a[5]);
719 }
720 #endif
721
722 static void
723 increment_v4_address (ip4_address_t * a)
724 {
725   u32 v;
726
727   v = ntohl (a->as_u32) + 1;
728   a->as_u32 = ntohl (v);
729 }
730
731 static void
732 increment_v6_address (ip6_address_t * a)
733 {
734   u64 v0, v1;
735
736   v0 = clib_net_to_host_u64 (a->as_u64[0]);
737   v1 = clib_net_to_host_u64 (a->as_u64[1]);
738
739   v1 += 1;
740   if (v1 == 0)
741     v0 += 1;
742   a->as_u64[0] = clib_net_to_host_u64 (v0);
743   a->as_u64[1] = clib_net_to_host_u64 (v1);
744 }
745
746 static void
747 increment_mac_address (u8 * mac)
748 {
749   u64 tmp = *((u64 *) mac);
750   tmp = clib_net_to_host_u64 (tmp);
751   tmp += 1 << 16;               /* skip unused (least significant) octets */
752   tmp = clib_host_to_net_u64 (tmp);
753
754   clib_memcpy (mac, &tmp, 6);
755 }
756
757 static void vl_api_create_loopback_reply_t_handler
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_reply_t_handler_json
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler_json
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler_json
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->sw_if_index = ntohl (mp->sw_if_index);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler_json
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
863
864   vat_json_print (vam->ofp, &node);
865   vat_json_free (&node);
866
867   vam->retval = ntohl (mp->retval);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   i32 retval = ntohl (mp->retval);
876
877   vam->retval = retval;
878   vam->regenerate_interface_table = 1;
879   vam->sw_if_index = ntohl (mp->sw_if_index);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler_json
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   vat_json_node_t node;
888
889   vat_json_init_object (&node);
890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
892
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   i32 retval = ntohl (mp->retval);
905
906   vam->retval = retval;
907   vam->regenerate_interface_table = 1;
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler_json
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   vat_json_node_t node;
916
917   vat_json_init_object (&node);
918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
919
920   vat_json_print (vam->ofp, &node);
921   vat_json_free (&node);
922
923   vam->retval = ntohl (mp->retval);
924   vam->result_ready = 1;
925 }
926
927 /*
928  * Special-case: build the interface table, maintain
929  * the next loopback sw_if_index vbl.
930  */
931 static void vl_api_sw_interface_details_t_handler
932   (vl_api_sw_interface_details_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   u8 *s = format (0, "%s%c", mp->interface_name, 0);
936
937   hash_set_mem (vam->sw_if_index_by_interface_name, s,
938                 ntohl (mp->sw_if_index));
939
940   /* In sub interface case, fill the sub interface table entry */
941   if (mp->sw_if_index != mp->sup_sw_if_index)
942     {
943       sw_interface_subif_t *sub = NULL;
944
945       vec_add2 (vam->sw_if_subif_table, sub, 1);
946
947       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
948       strncpy ((char *) sub->interface_name, (char *) s,
949                vec_len (sub->interface_name));
950       sub->sw_if_index = ntohl (mp->sw_if_index);
951       sub->sub_id = ntohl (mp->sub_id);
952
953       sub->sub_dot1ad = mp->sub_dot1ad;
954       sub->sub_number_of_tags = mp->sub_number_of_tags;
955       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
956       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
957       sub->sub_exact_match = mp->sub_exact_match;
958       sub->sub_default = mp->sub_default;
959       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
960       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
961
962       /* vlan tag rewrite */
963       sub->vtr_op = ntohl (mp->vtr_op);
964       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
965       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
966       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
967     }
968 }
969
970 static void vl_api_sw_interface_details_t_handler_json
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t *node = NULL;
975
976   if (VAT_JSON_ARRAY != vam->json_tree.type)
977     {
978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
979       vat_json_init_array (&vam->json_tree);
980     }
981   node = vat_json_array_add (&vam->json_tree);
982
983   vat_json_init_object (node);
984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
985   vat_json_object_add_uint (node, "sup_sw_if_index",
986                             ntohl (mp->sup_sw_if_index));
987   vat_json_object_add_uint (node, "l2_address_length",
988                             ntohl (mp->l2_address_length));
989   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
990                              sizeof (mp->l2_address));
991   vat_json_object_add_string_copy (node, "interface_name",
992                                    mp->interface_name);
993   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
994   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
995   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
996   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
997   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
998   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
999   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1000   vat_json_object_add_uint (node, "sub_number_of_tags",
1001                             mp->sub_number_of_tags);
1002   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1003                             ntohs (mp->sub_outer_vlan_id));
1004   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1005                             ntohs (mp->sub_inner_vlan_id));
1006   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1007   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1008   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1009                             mp->sub_outer_vlan_id_any);
1010   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1011                             mp->sub_inner_vlan_id_any);
1012   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1013   vat_json_object_add_uint (node, "vtr_push_dot1q",
1014                             ntohl (mp->vtr_push_dot1q));
1015   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1016   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1017   if (mp->sub_dot1ah)
1018     {
1019       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1020                                        format (0, "%U",
1021                                                format_ethernet_address,
1022                                                &mp->b_dmac));
1023       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_smac));
1027       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1028       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1029     }
1030 }
1031
1032 #if VPP_API_TEST_BUILTIN == 0
1033 static void vl_api_sw_interface_event_t_handler
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   if (vam->interface_event_display)
1038     errmsg ("interface flags: sw_if_index %d %s %s",
1039             ntohl (mp->sw_if_index),
1040             mp->admin_up_down ? "admin-up" : "admin-down",
1041             mp->link_up_down ? "link-up" : "link-down");
1042 }
1043 #endif
1044
1045 static void vl_api_sw_interface_event_t_handler_json
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   /* JSON output not supported */
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   i32 retval = ntohl (mp->retval);
1056
1057   vam->retval = retval;
1058   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067   api_main_t *am = &api_main;
1068   void *oldheap;
1069   u8 *reply;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "reply_in_shmem",
1074                             ntohl (mp->reply_in_shmem));
1075   /* Toss the shared-memory original... */
1076   pthread_mutex_lock (&am->vlib_rp->mutex);
1077   oldheap = svm_push_data_heap (am->vlib_rp);
1078
1079   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1080   vec_free (reply);
1081
1082   svm_pop_heap (oldheap);
1083   pthread_mutex_unlock (&am->vlib_rp->mutex);
1084
1085   vat_json_print (vam->ofp, &node);
1086   vat_json_free (&node);
1087
1088   vam->retval = ntohl (mp->retval);
1089   vam->result_ready = 1;
1090 }
1091
1092 static void
1093 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   i32 retval = ntohl (mp->retval);
1097   u32 length = ntohl (mp->length);
1098
1099   vec_reset_length (vam->cmd_reply);
1100
1101   vam->retval = retval;
1102   if (retval == 0)
1103     {
1104       vec_validate (vam->cmd_reply, length);
1105       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1106       vam->cmd_reply[length] = 0;
1107     }
1108   vam->result_ready = 1;
1109 }
1110
1111 static void
1112 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vec_reset_length (vam->cmd_reply);
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   if (vam->async_mode)
1136     {
1137       vam->async_errors += (retval < 0);
1138     }
1139   else
1140     {
1141       vam->retval = retval;
1142       if (retval == 0 &&
1143           ((mp->new_table_index != 0xFFFFFFFF) ||
1144            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1145            (mp->match_n_vectors != 0xFFFFFFFF)))
1146         /*
1147          * Note: this is just barely thread-safe, depends on
1148          * the main thread spinning waiting for an answer...
1149          */
1150         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1151                 ntohl (mp->new_table_index),
1152                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1153       vam->result_ready = 1;
1154     }
1155 }
1156
1157 static void vl_api_classify_add_del_table_reply_t_handler_json
1158   (vl_api_classify_add_del_table_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   vat_json_node_t node;
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_uint (&node, "new_table_index",
1166                             ntohl (mp->new_table_index));
1167   vat_json_object_add_uint (&node, "skip_n_vectors",
1168                             ntohl (mp->skip_n_vectors));
1169   vat_json_object_add_uint (&node, "match_n_vectors",
1170                             ntohl (mp->match_n_vectors));
1171
1172   vat_json_print (vam->ofp, &node);
1173   vat_json_free (&node);
1174
1175   vam->retval = ntohl (mp->retval);
1176   vam->result_ready = 1;
1177 }
1178
1179 static void vl_api_get_node_index_reply_t_handler
1180   (vl_api_get_node_index_reply_t * mp)
1181 {
1182   vat_main_t *vam = &vat_main;
1183   i32 retval = ntohl (mp->retval);
1184   if (vam->async_mode)
1185     {
1186       vam->async_errors += (retval < 0);
1187     }
1188   else
1189     {
1190       vam->retval = retval;
1191       if (retval == 0)
1192         errmsg ("node index %d", ntohl (mp->node_index));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_get_node_index_reply_t_handler_json
1198   (vl_api_get_node_index_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_next_index_reply_t_handler
1215   (vl_api_get_next_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("next node index %d", ntohl (mp->next_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_next_index_reply_t_handler_json
1233   (vl_api_get_next_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_add_node_next_reply_t_handler
1250   (vl_api_add_node_next_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_add_node_next_reply_t_handler_json
1268   (vl_api_add_node_next_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_show_version_reply_t_handler
1285   (vl_api_show_version_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289
1290   if (retval >= 0)
1291     {
1292       errmsg ("        program: %s", mp->program);
1293       errmsg ("        version: %s", mp->version);
1294       errmsg ("     build date: %s", mp->build_date);
1295       errmsg ("build directory: %s", mp->build_directory);
1296     }
1297   vam->retval = retval;
1298   vam->result_ready = 1;
1299 }
1300
1301 static void vl_api_show_version_reply_t_handler_json
1302   (vl_api_show_version_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_string_copy (&node, "program", mp->program);
1310   vat_json_object_add_string_copy (&node, "version", mp->version);
1311   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1312   vat_json_object_add_string_copy (&node, "build_directory",
1313                                    mp->build_directory);
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void
1323 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1324 {
1325   u32 sw_if_index = ntohl (mp->sw_if_index);
1326   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1327           mp->mac_ip ? "mac/ip binding" : "address resolution",
1328           ntohl (mp->pid), format_ip4_address, &mp->address,
1329           format_ethernet_address, mp->new_mac, sw_if_index);
1330 }
1331
1332 static void
1333 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1334 {
1335   /* JSON output not supported */
1336 }
1337
1338 static void
1339 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1340 {
1341   u32 sw_if_index = ntohl (mp->sw_if_index);
1342   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1343           mp->mac_ip ? "mac/ip binding" : "address resolution",
1344           ntohl (mp->pid), format_ip6_address, mp->address,
1345           format_ethernet_address, mp->new_mac, sw_if_index);
1346 }
1347
1348 static void
1349 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1350 {
1351   /* JSON output not supported */
1352 }
1353
1354 static void
1355 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1356 {
1357   u32 n_macs = ntohl (mp->n_macs);
1358   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_table_reply)                         \
5353 _(sw_interface_set_mpls_enable_reply)                   \
5354 _(sw_interface_set_vpath_reply)                         \
5355 _(sw_interface_set_vxlan_bypass_reply)                  \
5356 _(sw_interface_set_geneve_bypass_reply)                 \
5357 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5358 _(sw_interface_set_l2_bridge_reply)                     \
5359 _(bridge_domain_add_del_reply)                          \
5360 _(sw_interface_set_l2_xconnect_reply)                   \
5361 _(l2fib_add_del_reply)                                  \
5362 _(l2fib_flush_int_reply)                                \
5363 _(l2fib_flush_bd_reply)                                 \
5364 _(ip_add_del_route_reply)                               \
5365 _(ip_table_add_del_reply)                               \
5366 _(ip_mroute_add_del_reply)                              \
5367 _(mpls_route_add_del_reply)                             \
5368 _(mpls_table_add_del_reply)                             \
5369 _(mpls_ip_bind_unbind_reply)                            \
5370 _(bier_route_add_del_reply)                             \
5371 _(bier_table_add_del_reply)                             \
5372 _(proxy_arp_add_del_reply)                              \
5373 _(proxy_arp_intfc_enable_disable_reply)                 \
5374 _(sw_interface_set_unnumbered_reply)                    \
5375 _(ip_neighbor_add_del_reply)                            \
5376 _(oam_add_del_reply)                                    \
5377 _(reset_fib_reply)                                      \
5378 _(dhcp_proxy_config_reply)                              \
5379 _(dhcp_proxy_set_vss_reply)                             \
5380 _(dhcp_client_config_reply)                             \
5381 _(set_ip_flow_hash_reply)                               \
5382 _(sw_interface_ip6_enable_disable_reply)                \
5383 _(sw_interface_ip6_set_link_local_address_reply)        \
5384 _(ip6nd_proxy_add_del_reply)                            \
5385 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5386 _(sw_interface_ip6nd_ra_config_reply)                   \
5387 _(set_arp_neighbor_limit_reply)                         \
5388 _(l2_patch_add_del_reply)                               \
5389 _(sr_policy_add_reply)                                  \
5390 _(sr_policy_mod_reply)                                  \
5391 _(sr_policy_del_reply)                                  \
5392 _(sr_localsid_add_del_reply)                            \
5393 _(sr_steering_add_del_reply)                            \
5394 _(classify_add_del_session_reply)                       \
5395 _(classify_set_interface_ip_table_reply)                \
5396 _(classify_set_interface_l2_tables_reply)               \
5397 _(l2tpv3_set_tunnel_cookies_reply)                      \
5398 _(l2tpv3_interface_enable_disable_reply)                \
5399 _(l2tpv3_set_lookup_key_reply)                          \
5400 _(l2_fib_clear_table_reply)                             \
5401 _(l2_interface_efp_filter_reply)                        \
5402 _(l2_interface_vlan_tag_rewrite_reply)                  \
5403 _(modify_vhost_user_if_reply)                           \
5404 _(delete_vhost_user_if_reply)                           \
5405 _(ip_probe_neighbor_reply)                              \
5406 _(ip_scan_neighbor_enable_disable_reply)                \
5407 _(want_ip4_arp_events_reply)                            \
5408 _(want_ip6_nd_events_reply)                             \
5409 _(want_l2_macs_events_reply)                            \
5410 _(input_acl_set_interface_reply)                        \
5411 _(ipsec_spd_add_del_reply)                              \
5412 _(ipsec_interface_add_del_spd_reply)                    \
5413 _(ipsec_spd_add_del_entry_reply)                        \
5414 _(ipsec_sad_add_del_entry_reply)                        \
5415 _(ipsec_sa_set_key_reply)                               \
5416 _(ipsec_tunnel_if_add_del_reply)                        \
5417 _(ipsec_tunnel_if_set_key_reply)                        \
5418 _(ipsec_tunnel_if_set_sa_reply)                         \
5419 _(ikev2_profile_add_del_reply)                          \
5420 _(ikev2_profile_set_auth_reply)                         \
5421 _(ikev2_profile_set_id_reply)                           \
5422 _(ikev2_profile_set_ts_reply)                           \
5423 _(ikev2_set_local_key_reply)                            \
5424 _(ikev2_set_responder_reply)                            \
5425 _(ikev2_set_ike_transforms_reply)                       \
5426 _(ikev2_set_esp_transforms_reply)                       \
5427 _(ikev2_set_sa_lifetime_reply)                          \
5428 _(ikev2_initiate_sa_init_reply)                         \
5429 _(ikev2_initiate_del_ike_sa_reply)                      \
5430 _(ikev2_initiate_del_child_sa_reply)                    \
5431 _(ikev2_initiate_rekey_child_sa_reply)                  \
5432 _(delete_loopback_reply)                                \
5433 _(bd_ip_mac_add_del_reply)                              \
5434 _(want_interface_events_reply)                          \
5435 _(want_stats_reply)                                     \
5436 _(cop_interface_enable_disable_reply)                   \
5437 _(cop_whitelist_enable_disable_reply)                   \
5438 _(sw_interface_clear_stats_reply)                       \
5439 _(ioam_enable_reply)                                    \
5440 _(ioam_disable_reply)                                   \
5441 _(one_add_del_locator_reply)                            \
5442 _(one_add_del_local_eid_reply)                          \
5443 _(one_add_del_remote_mapping_reply)                     \
5444 _(one_add_del_adjacency_reply)                          \
5445 _(one_add_del_map_resolver_reply)                       \
5446 _(one_add_del_map_server_reply)                         \
5447 _(one_enable_disable_reply)                             \
5448 _(one_rloc_probe_enable_disable_reply)                  \
5449 _(one_map_register_enable_disable_reply)                \
5450 _(one_map_register_set_ttl_reply)                       \
5451 _(one_set_transport_protocol_reply)                     \
5452 _(one_map_register_fallback_threshold_reply)            \
5453 _(one_pitr_set_locator_set_reply)                       \
5454 _(one_map_request_mode_reply)                           \
5455 _(one_add_del_map_request_itr_rlocs_reply)              \
5456 _(one_eid_table_add_del_map_reply)                      \
5457 _(one_use_petr_reply)                                   \
5458 _(one_stats_enable_disable_reply)                       \
5459 _(one_add_del_l2_arp_entry_reply)                       \
5460 _(one_add_del_ndp_entry_reply)                          \
5461 _(one_stats_flush_reply)                                \
5462 _(one_enable_disable_xtr_mode_reply)                    \
5463 _(one_enable_disable_pitr_mode_reply)                   \
5464 _(one_enable_disable_petr_mode_reply)                   \
5465 _(gpe_enable_disable_reply)                             \
5466 _(gpe_set_encap_mode_reply)                             \
5467 _(gpe_add_del_iface_reply)                              \
5468 _(gpe_add_del_native_fwd_rpath_reply)                   \
5469 _(af_packet_delete_reply)                               \
5470 _(policer_classify_set_interface_reply)                 \
5471 _(netmap_create_reply)                                  \
5472 _(netmap_delete_reply)                                  \
5473 _(set_ipfix_exporter_reply)                             \
5474 _(set_ipfix_classify_stream_reply)                      \
5475 _(ipfix_classify_table_add_del_reply)                   \
5476 _(flow_classify_set_interface_reply)                    \
5477 _(sw_interface_span_enable_disable_reply)               \
5478 _(pg_capture_reply)                                     \
5479 _(pg_enable_disable_reply)                              \
5480 _(ip_source_and_port_range_check_add_del_reply)         \
5481 _(ip_source_and_port_range_check_interface_add_del_reply)\
5482 _(delete_subif_reply)                                   \
5483 _(l2_interface_pbb_tag_rewrite_reply)                   \
5484 _(punt_reply)                                           \
5485 _(feature_enable_disable_reply)                         \
5486 _(sw_interface_tag_add_del_reply)                       \
5487 _(hw_interface_set_mtu_reply)                           \
5488 _(p2p_ethernet_add_reply)                               \
5489 _(p2p_ethernet_del_reply)                               \
5490 _(lldp_config_reply)                                    \
5491 _(sw_interface_set_lldp_reply)                          \
5492 _(tcp_configure_src_addresses_reply)                    \
5493 _(dns_enable_disable_reply)                             \
5494 _(dns_name_server_add_del_reply)                        \
5495 _(session_rule_add_del_reply)                           \
5496 _(ip_container_proxy_add_del_reply)                     \
5497 _(output_acl_set_interface_reply)                       \
5498 _(qos_record_enable_disable_reply)
5499
5500 #define _(n)                                    \
5501     static void vl_api_##n##_t_handler          \
5502     (vl_api_##n##_t * mp)                       \
5503     {                                           \
5504         vat_main_t * vam = &vat_main;           \
5505         i32 retval = ntohl(mp->retval);         \
5506         if (vam->async_mode) {                  \
5507             vam->async_errors += (retval < 0);  \
5508         } else {                                \
5509             vam->retval = retval;               \
5510             vam->result_ready = 1;              \
5511         }                                       \
5512     }
5513 foreach_standard_reply_retval_handler;
5514 #undef _
5515
5516 #define _(n)                                    \
5517     static void vl_api_##n##_t_handler_json     \
5518     (vl_api_##n##_t * mp)                       \
5519     {                                           \
5520         vat_main_t * vam = &vat_main;           \
5521         vat_json_node_t node;                   \
5522         vat_json_init_object(&node);            \
5523         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5524         vat_json_print(vam->ofp, &node);        \
5525         vam->retval = ntohl(mp->retval);        \
5526         vam->result_ready = 1;                  \
5527     }
5528 foreach_standard_reply_retval_handler;
5529 #undef _
5530
5531 /*
5532  * Table of message reply handlers, must include boilerplate handlers
5533  * we just generated
5534  */
5535
5536 #define foreach_vpe_api_reply_msg                                       \
5537 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5538 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5539 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5540 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5541 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5542 _(CLI_REPLY, cli_reply)                                                 \
5543 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5544 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5545   sw_interface_add_del_address_reply)                                   \
5546 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5547 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5548 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5549 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5550 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5551 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5552 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5553 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5554   sw_interface_set_l2_xconnect_reply)                                   \
5555 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5556   sw_interface_set_l2_bridge_reply)                                     \
5557 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5558 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5559 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5560 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5561 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5562 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5563 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5564 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5565 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5566 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5567 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5568 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5569 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5570 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5571 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5572 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5573 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5574 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5575 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5576 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5577 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5578 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5579 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5580 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5581 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5582 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5583 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5584 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5585 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5586 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5587 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5588   proxy_arp_intfc_enable_disable_reply)                                 \
5589 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5590 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5591   sw_interface_set_unnumbered_reply)                                    \
5592 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5593 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5594 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5595 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5596 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5597 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5598 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5599 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5600 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5601 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5602 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5603   sw_interface_ip6_enable_disable_reply)                                \
5604 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5605   sw_interface_ip6_set_link_local_address_reply)                        \
5606 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5607 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5608 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5609   sw_interface_ip6nd_ra_prefix_reply)                                   \
5610 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5611   sw_interface_ip6nd_ra_config_reply)                                   \
5612 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5613 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5614 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5615 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5616 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5617 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5618 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5619 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5620 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5621 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5622 classify_set_interface_ip_table_reply)                                  \
5623 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5624   classify_set_interface_l2_tables_reply)                               \
5625 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5626 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5627 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5628 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5629 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5630   l2tpv3_interface_enable_disable_reply)                                \
5631 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5632 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5633 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5634 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5635 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5636 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5637 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5638 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5639 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5640 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5641 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5642 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5643 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5644 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5645 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5646 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5647 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5648 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5649 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5650 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5651 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5652 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5653 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5654 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5655 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5656 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5657 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5658 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5659 _(L2_MACS_EVENT, l2_macs_event)                                         \
5660 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5661 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5662 _(IP_DETAILS, ip_details)                                               \
5663 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5664 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5665 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5666 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5667 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5668 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5669 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5670 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5671 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5672 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5673 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5674 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5675 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5676 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5677 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5678 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5679 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5680 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5681 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5682 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5683 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5684 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5685 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5686 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5687 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5688 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5689 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5690 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5691 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5692 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5693 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5694 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5695 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5696 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5697 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5698 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5699 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5700 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5701 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5702 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5703 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5704 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5705 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5706   one_map_register_enable_disable_reply)                                \
5707 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5708 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5709 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5710 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5711   one_map_register_fallback_threshold_reply)                            \
5712 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5713   one_rloc_probe_enable_disable_reply)                                  \
5714 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5715 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5716 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5717 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5718 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5719 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5720 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5721 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5722 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5723 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5724 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5725 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5726 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5727 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5728 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5729 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5730   show_one_stats_enable_disable_reply)                                  \
5731 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5732 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5733 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5734 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5735 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5736 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5737 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5738 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5739   one_enable_disable_pitr_mode_reply)                                   \
5740 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5741   one_enable_disable_petr_mode_reply)                                   \
5742 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5743 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5744 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5745 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5746 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5747 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5748 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5749 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5750 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5751 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5752 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5753 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5754   gpe_add_del_native_fwd_rpath_reply)                                   \
5755 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5756   gpe_fwd_entry_path_details)                                           \
5757 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5758 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5759   one_add_del_map_request_itr_rlocs_reply)                              \
5760 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5761   one_get_map_request_itr_rlocs_reply)                                  \
5762 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5763 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5764 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5765 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5766 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5767 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5768   show_one_map_register_state_reply)                                    \
5769 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5770 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5771   show_one_map_register_fallback_threshold_reply)                       \
5772 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5773 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5774 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5775 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5776 _(POLICER_DETAILS, policer_details)                                     \
5777 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5778 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5779 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5780 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5781 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5782 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5783 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5784 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5785 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5786 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5787 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5788 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5789 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5790 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5791 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5792 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5793 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5794 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5795 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5796 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5797 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5798 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5799 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5800 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5801 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5802  ip_source_and_port_range_check_add_del_reply)                          \
5803 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5804  ip_source_and_port_range_check_interface_add_del_reply)                \
5805 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5806 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5807 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5808 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5809 _(PUNT_REPLY, punt_reply)                                               \
5810 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5811 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5812 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5813 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5814 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5815 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5816 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5817 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5818 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5819 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5820 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5821 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5822 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5823 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5824 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5825 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5826 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5827 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5828 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5829 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5830 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5831 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5832 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5833
5834 #define foreach_standalone_reply_msg                                    \
5835 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5836 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5837 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5838 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5839 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5840 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5841 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5842
5843 typedef struct
5844 {
5845   u8 *name;
5846   u32 value;
5847 } name_sort_t;
5848
5849 #define STR_VTR_OP_CASE(op)     \
5850     case L2_VTR_ ## op:         \
5851         return "" # op;
5852
5853 static const char *
5854 str_vtr_op (u32 vtr_op)
5855 {
5856   switch (vtr_op)
5857     {
5858       STR_VTR_OP_CASE (DISABLED);
5859       STR_VTR_OP_CASE (PUSH_1);
5860       STR_VTR_OP_CASE (PUSH_2);
5861       STR_VTR_OP_CASE (POP_1);
5862       STR_VTR_OP_CASE (POP_2);
5863       STR_VTR_OP_CASE (TRANSLATE_1_1);
5864       STR_VTR_OP_CASE (TRANSLATE_1_2);
5865       STR_VTR_OP_CASE (TRANSLATE_2_1);
5866       STR_VTR_OP_CASE (TRANSLATE_2_2);
5867     }
5868
5869   return "UNKNOWN";
5870 }
5871
5872 static int
5873 dump_sub_interface_table (vat_main_t * vam)
5874 {
5875   const sw_interface_subif_t *sub = NULL;
5876
5877   if (vam->json_output)
5878     {
5879       clib_warning
5880         ("JSON output supported only for VPE API calls and dump_stats_table");
5881       return -99;
5882     }
5883
5884   print (vam->ofp,
5885          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5886          "Interface", "sw_if_index",
5887          "sub id", "dot1ad", "tags", "outer id",
5888          "inner id", "exact", "default", "outer any", "inner any");
5889
5890   vec_foreach (sub, vam->sw_if_subif_table)
5891   {
5892     print (vam->ofp,
5893            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5894            sub->interface_name,
5895            sub->sw_if_index,
5896            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5897            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5898            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5899            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5900     if (sub->vtr_op != L2_VTR_DISABLED)
5901       {
5902         print (vam->ofp,
5903                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5904                "tag1: %d tag2: %d ]",
5905                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5906                sub->vtr_tag1, sub->vtr_tag2);
5907       }
5908   }
5909
5910   return 0;
5911 }
5912
5913 static int
5914 name_sort_cmp (void *a1, void *a2)
5915 {
5916   name_sort_t *n1 = a1;
5917   name_sort_t *n2 = a2;
5918
5919   return strcmp ((char *) n1->name, (char *) n2->name);
5920 }
5921
5922 static int
5923 dump_interface_table (vat_main_t * vam)
5924 {
5925   hash_pair_t *p;
5926   name_sort_t *nses = 0, *ns;
5927
5928   if (vam->json_output)
5929     {
5930       clib_warning
5931         ("JSON output supported only for VPE API calls and dump_stats_table");
5932       return -99;
5933     }
5934
5935   /* *INDENT-OFF* */
5936   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5937   ({
5938     vec_add2 (nses, ns, 1);
5939     ns->name = (u8 *)(p->key);
5940     ns->value = (u32) p->value[0];
5941   }));
5942   /* *INDENT-ON* */
5943
5944   vec_sort_with_function (nses, name_sort_cmp);
5945
5946   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5947   vec_foreach (ns, nses)
5948   {
5949     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5950   }
5951   vec_free (nses);
5952   return 0;
5953 }
5954
5955 static int
5956 dump_ip_table (vat_main_t * vam, int is_ipv6)
5957 {
5958   const ip_details_t *det = NULL;
5959   const ip_address_details_t *address = NULL;
5960   u32 i = ~0;
5961
5962   print (vam->ofp, "%-12s", "sw_if_index");
5963
5964   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5965   {
5966     i++;
5967     if (!det->present)
5968       {
5969         continue;
5970       }
5971     print (vam->ofp, "%-12d", i);
5972     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5973     if (!det->addr)
5974       {
5975         continue;
5976       }
5977     vec_foreach (address, det->addr)
5978     {
5979       print (vam->ofp,
5980              "            %-30U%-13d",
5981              is_ipv6 ? format_ip6_address : format_ip4_address,
5982              address->ip, address->prefix_length);
5983     }
5984   }
5985
5986   return 0;
5987 }
5988
5989 static int
5990 dump_ipv4_table (vat_main_t * vam)
5991 {
5992   if (vam->json_output)
5993     {
5994       clib_warning
5995         ("JSON output supported only for VPE API calls and dump_stats_table");
5996       return -99;
5997     }
5998
5999   return dump_ip_table (vam, 0);
6000 }
6001
6002 static int
6003 dump_ipv6_table (vat_main_t * vam)
6004 {
6005   if (vam->json_output)
6006     {
6007       clib_warning
6008         ("JSON output supported only for VPE API calls and dump_stats_table");
6009       return -99;
6010     }
6011
6012   return dump_ip_table (vam, 1);
6013 }
6014
6015 static char *
6016 counter_type_to_str (u8 counter_type, u8 is_combined)
6017 {
6018   if (!is_combined)
6019     {
6020       switch (counter_type)
6021         {
6022         case VNET_INTERFACE_COUNTER_DROP:
6023           return "drop";
6024         case VNET_INTERFACE_COUNTER_PUNT:
6025           return "punt";
6026         case VNET_INTERFACE_COUNTER_IP4:
6027           return "ip4";
6028         case VNET_INTERFACE_COUNTER_IP6:
6029           return "ip6";
6030         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6031           return "rx-no-buf";
6032         case VNET_INTERFACE_COUNTER_RX_MISS:
6033           return "rx-miss";
6034         case VNET_INTERFACE_COUNTER_RX_ERROR:
6035           return "rx-error";
6036         case VNET_INTERFACE_COUNTER_TX_ERROR:
6037           return "tx-error";
6038         default:
6039           return "INVALID-COUNTER-TYPE";
6040         }
6041     }
6042   else
6043     {
6044       switch (counter_type)
6045         {
6046         case VNET_INTERFACE_COUNTER_RX:
6047           return "rx";
6048         case VNET_INTERFACE_COUNTER_TX:
6049           return "tx";
6050         default:
6051           return "INVALID-COUNTER-TYPE";
6052         }
6053     }
6054 }
6055
6056 static int
6057 dump_stats_table (vat_main_t * vam)
6058 {
6059   vat_json_node_t node;
6060   vat_json_node_t *msg_array;
6061   vat_json_node_t *msg;
6062   vat_json_node_t *counter_array;
6063   vat_json_node_t *counter;
6064   interface_counter_t c;
6065   u64 packets;
6066   ip4_fib_counter_t *c4;
6067   ip6_fib_counter_t *c6;
6068   ip4_nbr_counter_t *n4;
6069   ip6_nbr_counter_t *n6;
6070   int i, j;
6071
6072   if (!vam->json_output)
6073     {
6074       clib_warning ("dump_stats_table supported only in JSON format");
6075       return -99;
6076     }
6077
6078   vat_json_init_object (&node);
6079
6080   /* interface counters */
6081   msg_array = vat_json_object_add (&node, "interface_counters");
6082   vat_json_init_array (msg_array);
6083   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6084     {
6085       msg = vat_json_array_add (msg_array);
6086       vat_json_init_object (msg);
6087       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6088                                        (u8 *) counter_type_to_str (i, 0));
6089       vat_json_object_add_int (msg, "is_combined", 0);
6090       counter_array = vat_json_object_add (msg, "data");
6091       vat_json_init_array (counter_array);
6092       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6093         {
6094           packets = vam->simple_interface_counters[i][j];
6095           vat_json_array_add_uint (counter_array, packets);
6096         }
6097     }
6098   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6099     {
6100       msg = vat_json_array_add (msg_array);
6101       vat_json_init_object (msg);
6102       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6103                                        (u8 *) counter_type_to_str (i, 1));
6104       vat_json_object_add_int (msg, "is_combined", 1);
6105       counter_array = vat_json_object_add (msg, "data");
6106       vat_json_init_array (counter_array);
6107       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6108         {
6109           c = vam->combined_interface_counters[i][j];
6110           counter = vat_json_array_add (counter_array);
6111           vat_json_init_object (counter);
6112           vat_json_object_add_uint (counter, "packets", c.packets);
6113           vat_json_object_add_uint (counter, "bytes", c.bytes);
6114         }
6115     }
6116
6117   /* ip4 fib counters */
6118   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6119   vat_json_init_array (msg_array);
6120   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6121     {
6122       msg = vat_json_array_add (msg_array);
6123       vat_json_init_object (msg);
6124       vat_json_object_add_uint (msg, "vrf_id",
6125                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6126       counter_array = vat_json_object_add (msg, "c");
6127       vat_json_init_array (counter_array);
6128       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6129         {
6130           counter = vat_json_array_add (counter_array);
6131           vat_json_init_object (counter);
6132           c4 = &vam->ip4_fib_counters[i][j];
6133           vat_json_object_add_ip4 (counter, "address", c4->address);
6134           vat_json_object_add_uint (counter, "address_length",
6135                                     c4->address_length);
6136           vat_json_object_add_uint (counter, "packets", c4->packets);
6137           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6138         }
6139     }
6140
6141   /* ip6 fib counters */
6142   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6143   vat_json_init_array (msg_array);
6144   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6145     {
6146       msg = vat_json_array_add (msg_array);
6147       vat_json_init_object (msg);
6148       vat_json_object_add_uint (msg, "vrf_id",
6149                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6150       counter_array = vat_json_object_add (msg, "c");
6151       vat_json_init_array (counter_array);
6152       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6153         {
6154           counter = vat_json_array_add (counter_array);
6155           vat_json_init_object (counter);
6156           c6 = &vam->ip6_fib_counters[i][j];
6157           vat_json_object_add_ip6 (counter, "address", c6->address);
6158           vat_json_object_add_uint (counter, "address_length",
6159                                     c6->address_length);
6160           vat_json_object_add_uint (counter, "packets", c6->packets);
6161           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6162         }
6163     }
6164
6165   /* ip4 nbr counters */
6166   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6167   vat_json_init_array (msg_array);
6168   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6169     {
6170       msg = vat_json_array_add (msg_array);
6171       vat_json_init_object (msg);
6172       vat_json_object_add_uint (msg, "sw_if_index", i);
6173       counter_array = vat_json_object_add (msg, "c");
6174       vat_json_init_array (counter_array);
6175       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6176         {
6177           counter = vat_json_array_add (counter_array);
6178           vat_json_init_object (counter);
6179           n4 = &vam->ip4_nbr_counters[i][j];
6180           vat_json_object_add_ip4 (counter, "address", n4->address);
6181           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6182           vat_json_object_add_uint (counter, "packets", n4->packets);
6183           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6184         }
6185     }
6186
6187   /* ip6 nbr counters */
6188   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6189   vat_json_init_array (msg_array);
6190   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6191     {
6192       msg = vat_json_array_add (msg_array);
6193       vat_json_init_object (msg);
6194       vat_json_object_add_uint (msg, "sw_if_index", i);
6195       counter_array = vat_json_object_add (msg, "c");
6196       vat_json_init_array (counter_array);
6197       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6198         {
6199           counter = vat_json_array_add (counter_array);
6200           vat_json_init_object (counter);
6201           n6 = &vam->ip6_nbr_counters[i][j];
6202           vat_json_object_add_ip6 (counter, "address", n6->address);
6203           vat_json_object_add_uint (counter, "packets", n6->packets);
6204           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6205         }
6206     }
6207
6208   vat_json_print (vam->ofp, &node);
6209   vat_json_free (&node);
6210
6211   return 0;
6212 }
6213
6214 /*
6215  * Pass CLI buffers directly in the CLI_INBAND API message,
6216  * instead of an additional shared memory area.
6217  */
6218 static int
6219 exec_inband (vat_main_t * vam)
6220 {
6221   vl_api_cli_inband_t *mp;
6222   unformat_input_t *i = vam->input;
6223   int ret;
6224
6225   if (vec_len (i->buffer) == 0)
6226     return -1;
6227
6228   if (vam->exec_mode == 0 && unformat (i, "mode"))
6229     {
6230       vam->exec_mode = 1;
6231       return 0;
6232     }
6233   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6234     {
6235       vam->exec_mode = 0;
6236       return 0;
6237     }
6238
6239   /*
6240    * In order for the CLI command to work, it
6241    * must be a vector ending in \n, not a C-string ending
6242    * in \n\0.
6243    */
6244   u32 len = vec_len (vam->input->buffer);
6245   M2 (CLI_INBAND, mp, len);
6246   clib_memcpy (mp->cmd, vam->input->buffer, len);
6247   mp->length = htonl (len);
6248
6249   S (mp);
6250   W (ret);
6251   /* json responses may or may not include a useful reply... */
6252   if (vec_len (vam->cmd_reply))
6253     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6254   return ret;
6255 }
6256
6257 int
6258 exec (vat_main_t * vam)
6259 {
6260   return exec_inband (vam);
6261 }
6262
6263 static int
6264 api_create_loopback (vat_main_t * vam)
6265 {
6266   unformat_input_t *i = vam->input;
6267   vl_api_create_loopback_t *mp;
6268   vl_api_create_loopback_instance_t *mp_lbi;
6269   u8 mac_address[6];
6270   u8 mac_set = 0;
6271   u8 is_specified = 0;
6272   u32 user_instance = 0;
6273   int ret;
6274
6275   memset (mac_address, 0, sizeof (mac_address));
6276
6277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6278     {
6279       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6280         mac_set = 1;
6281       if (unformat (i, "instance %d", &user_instance))
6282         is_specified = 1;
6283       else
6284         break;
6285     }
6286
6287   if (is_specified)
6288     {
6289       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6290       mp_lbi->is_specified = is_specified;
6291       if (is_specified)
6292         mp_lbi->user_instance = htonl (user_instance);
6293       if (mac_set)
6294         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6295       S (mp_lbi);
6296     }
6297   else
6298     {
6299       /* Construct the API message */
6300       M (CREATE_LOOPBACK, mp);
6301       if (mac_set)
6302         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6303       S (mp);
6304     }
6305
6306   W (ret);
6307   return ret;
6308 }
6309
6310 static int
6311 api_delete_loopback (vat_main_t * vam)
6312 {
6313   unformat_input_t *i = vam->input;
6314   vl_api_delete_loopback_t *mp;
6315   u32 sw_if_index = ~0;
6316   int ret;
6317
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "sw_if_index %d", &sw_if_index))
6321         ;
6322       else
6323         break;
6324     }
6325
6326   if (sw_if_index == ~0)
6327     {
6328       errmsg ("missing sw_if_index");
6329       return -99;
6330     }
6331
6332   /* Construct the API message */
6333   M (DELETE_LOOPBACK, mp);
6334   mp->sw_if_index = ntohl (sw_if_index);
6335
6336   S (mp);
6337   W (ret);
6338   return ret;
6339 }
6340
6341 static int
6342 api_want_stats (vat_main_t * vam)
6343 {
6344   unformat_input_t *i = vam->input;
6345   vl_api_want_stats_t *mp;
6346   int enable = -1;
6347   int ret;
6348
6349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6350     {
6351       if (unformat (i, "enable"))
6352         enable = 1;
6353       else if (unformat (i, "disable"))
6354         enable = 0;
6355       else
6356         break;
6357     }
6358
6359   if (enable == -1)
6360     {
6361       errmsg ("missing enable|disable");
6362       return -99;
6363     }
6364
6365   M (WANT_STATS, mp);
6366   mp->enable_disable = enable;
6367
6368   S (mp);
6369   W (ret);
6370   return ret;
6371 }
6372
6373 static int
6374 api_want_interface_events (vat_main_t * vam)
6375 {
6376   unformat_input_t *i = vam->input;
6377   vl_api_want_interface_events_t *mp;
6378   int enable = -1;
6379   int ret;
6380
6381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6382     {
6383       if (unformat (i, "enable"))
6384         enable = 1;
6385       else if (unformat (i, "disable"))
6386         enable = 0;
6387       else
6388         break;
6389     }
6390
6391   if (enable == -1)
6392     {
6393       errmsg ("missing enable|disable");
6394       return -99;
6395     }
6396
6397   M (WANT_INTERFACE_EVENTS, mp);
6398   mp->enable_disable = enable;
6399
6400   vam->interface_event_display = enable;
6401
6402   S (mp);
6403   W (ret);
6404   return ret;
6405 }
6406
6407
6408 /* Note: non-static, called once to set up the initial intfc table */
6409 int
6410 api_sw_interface_dump (vat_main_t * vam)
6411 {
6412   vl_api_sw_interface_dump_t *mp;
6413   vl_api_control_ping_t *mp_ping;
6414   hash_pair_t *p;
6415   name_sort_t *nses = 0, *ns;
6416   sw_interface_subif_t *sub = NULL;
6417   int ret;
6418
6419   /* Toss the old name table */
6420   /* *INDENT-OFF* */
6421   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6422   ({
6423     vec_add2 (nses, ns, 1);
6424     ns->name = (u8 *)(p->key);
6425     ns->value = (u32) p->value[0];
6426   }));
6427   /* *INDENT-ON* */
6428
6429   hash_free (vam->sw_if_index_by_interface_name);
6430
6431   vec_foreach (ns, nses) vec_free (ns->name);
6432
6433   vec_free (nses);
6434
6435   vec_foreach (sub, vam->sw_if_subif_table)
6436   {
6437     vec_free (sub->interface_name);
6438   }
6439   vec_free (vam->sw_if_subif_table);
6440
6441   /* recreate the interface name hash table */
6442   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6443
6444   /*
6445    * Ask for all interface names. Otherwise, the epic catalog of
6446    * name filters becomes ridiculously long, and vat ends up needing
6447    * to be taught about new interface types.
6448    */
6449   M (SW_INTERFACE_DUMP, mp);
6450   S (mp);
6451
6452   /* Use a control ping for synchronization */
6453   MPING (CONTROL_PING, mp_ping);
6454   S (mp_ping);
6455
6456   W (ret);
6457   return ret;
6458 }
6459
6460 static int
6461 api_sw_interface_set_flags (vat_main_t * vam)
6462 {
6463   unformat_input_t *i = vam->input;
6464   vl_api_sw_interface_set_flags_t *mp;
6465   u32 sw_if_index;
6466   u8 sw_if_index_set = 0;
6467   u8 admin_up = 0;
6468   int ret;
6469
6470   /* Parse args required to build the message */
6471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6472     {
6473       if (unformat (i, "admin-up"))
6474         admin_up = 1;
6475       else if (unformat (i, "admin-down"))
6476         admin_up = 0;
6477       else
6478         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6479         sw_if_index_set = 1;
6480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6481         sw_if_index_set = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491
6492   /* Construct the API message */
6493   M (SW_INTERFACE_SET_FLAGS, mp);
6494   mp->sw_if_index = ntohl (sw_if_index);
6495   mp->admin_up_down = admin_up;
6496
6497   /* send it... */
6498   S (mp);
6499
6500   /* Wait for a reply, return the good/bad news... */
6501   W (ret);
6502   return ret;
6503 }
6504
6505 static int
6506 api_sw_interface_set_rx_mode (vat_main_t * vam)
6507 {
6508   unformat_input_t *i = vam->input;
6509   vl_api_sw_interface_set_rx_mode_t *mp;
6510   u32 sw_if_index;
6511   u8 sw_if_index_set = 0;
6512   int ret;
6513   u8 queue_id_valid = 0;
6514   u32 queue_id;
6515   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6516
6517   /* Parse args required to build the message */
6518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6519     {
6520       if (unformat (i, "queue %d", &queue_id))
6521         queue_id_valid = 1;
6522       else if (unformat (i, "polling"))
6523         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6524       else if (unformat (i, "interrupt"))
6525         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6526       else if (unformat (i, "adaptive"))
6527         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6528       else
6529         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else
6534         break;
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing interface name or sw_if_index");
6540       return -99;
6541     }
6542   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6543     {
6544       errmsg ("missing rx-mode");
6545       return -99;
6546     }
6547
6548   /* Construct the API message */
6549   M (SW_INTERFACE_SET_RX_MODE, mp);
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->mode = mode;
6552   mp->queue_id_valid = queue_id_valid;
6553   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6554
6555   /* send it... */
6556   S (mp);
6557
6558   /* Wait for a reply, return the good/bad news... */
6559   W (ret);
6560   return ret;
6561 }
6562
6563 static int
6564 api_sw_interface_clear_stats (vat_main_t * vam)
6565 {
6566   unformat_input_t *i = vam->input;
6567   vl_api_sw_interface_clear_stats_t *mp;
6568   u32 sw_if_index;
6569   u8 sw_if_index_set = 0;
6570   int ret;
6571
6572   /* Parse args required to build the message */
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6576         sw_if_index_set = 1;
6577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6578         sw_if_index_set = 1;
6579       else
6580         break;
6581     }
6582
6583   /* Construct the API message */
6584   M (SW_INTERFACE_CLEAR_STATS, mp);
6585
6586   if (sw_if_index_set == 1)
6587     mp->sw_if_index = ntohl (sw_if_index);
6588   else
6589     mp->sw_if_index = ~0;
6590
6591   /* send it... */
6592   S (mp);
6593
6594   /* Wait for a reply, return the good/bad news... */
6595   W (ret);
6596   return ret;
6597 }
6598
6599 static int
6600 api_sw_interface_add_del_address (vat_main_t * vam)
6601 {
6602   unformat_input_t *i = vam->input;
6603   vl_api_sw_interface_add_del_address_t *mp;
6604   u32 sw_if_index;
6605   u8 sw_if_index_set = 0;
6606   u8 is_add = 1, del_all = 0;
6607   u32 address_length = 0;
6608   u8 v4_address_set = 0;
6609   u8 v6_address_set = 0;
6610   ip4_address_t v4address;
6611   ip6_address_t v6address;
6612   int ret;
6613
6614   /* Parse args required to build the message */
6615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6616     {
6617       if (unformat (i, "del-all"))
6618         del_all = 1;
6619       else if (unformat (i, "del"))
6620         is_add = 0;
6621       else
6622         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6623         sw_if_index_set = 1;
6624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6625         sw_if_index_set = 1;
6626       else if (unformat (i, "%U/%d",
6627                          unformat_ip4_address, &v4address, &address_length))
6628         v4_address_set = 1;
6629       else if (unformat (i, "%U/%d",
6630                          unformat_ip6_address, &v6address, &address_length))
6631         v6_address_set = 1;
6632       else
6633         break;
6634     }
6635
6636   if (sw_if_index_set == 0)
6637     {
6638       errmsg ("missing interface name or sw_if_index");
6639       return -99;
6640     }
6641   if (v4_address_set && v6_address_set)
6642     {
6643       errmsg ("both v4 and v6 addresses set");
6644       return -99;
6645     }
6646   if (!v4_address_set && !v6_address_set && !del_all)
6647     {
6648       errmsg ("no addresses set");
6649       return -99;
6650     }
6651
6652   /* Construct the API message */
6653   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6654
6655   mp->sw_if_index = ntohl (sw_if_index);
6656   mp->is_add = is_add;
6657   mp->del_all = del_all;
6658   if (v6_address_set)
6659     {
6660       mp->is_ipv6 = 1;
6661       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6662     }
6663   else
6664     {
6665       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6666     }
6667   mp->address_length = address_length;
6668
6669   /* send it... */
6670   S (mp);
6671
6672   /* Wait for a reply, return good/bad news  */
6673   W (ret);
6674   return ret;
6675 }
6676
6677 static int
6678 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6679 {
6680   unformat_input_t *i = vam->input;
6681   vl_api_sw_interface_set_mpls_enable_t *mp;
6682   u32 sw_if_index;
6683   u8 sw_if_index_set = 0;
6684   u8 enable = 1;
6685   int ret;
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6691         sw_if_index_set = 1;
6692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6693         sw_if_index_set = 1;
6694       else if (unformat (i, "disable"))
6695         enable = 0;
6696       else if (unformat (i, "dis"))
6697         enable = 0;
6698       else
6699         break;
6700     }
6701
6702   if (sw_if_index_set == 0)
6703     {
6704       errmsg ("missing interface name or sw_if_index");
6705       return -99;
6706     }
6707
6708   /* Construct the API message */
6709   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6710
6711   mp->sw_if_index = ntohl (sw_if_index);
6712   mp->enable = enable;
6713
6714   /* send it... */
6715   S (mp);
6716
6717   /* Wait for a reply... */
6718   W (ret);
6719   return ret;
6720 }
6721
6722 static int
6723 api_sw_interface_set_table (vat_main_t * vam)
6724 {
6725   unformat_input_t *i = vam->input;
6726   vl_api_sw_interface_set_table_t *mp;
6727   u32 sw_if_index, vrf_id = 0;
6728   u8 sw_if_index_set = 0;
6729   u8 is_ipv6 = 0;
6730   int ret;
6731
6732   /* Parse args required to build the message */
6733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6734     {
6735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6736         sw_if_index_set = 1;
6737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6738         sw_if_index_set = 1;
6739       else if (unformat (i, "vrf %d", &vrf_id))
6740         ;
6741       else if (unformat (i, "ipv6"))
6742         is_ipv6 = 1;
6743       else
6744         break;
6745     }
6746
6747   if (sw_if_index_set == 0)
6748     {
6749       errmsg ("missing interface name or sw_if_index");
6750       return -99;
6751     }
6752
6753   /* Construct the API message */
6754   M (SW_INTERFACE_SET_TABLE, mp);
6755
6756   mp->sw_if_index = ntohl (sw_if_index);
6757   mp->is_ipv6 = is_ipv6;
6758   mp->vrf_id = ntohl (vrf_id);
6759
6760   /* send it... */
6761   S (mp);
6762
6763   /* Wait for a reply... */
6764   W (ret);
6765   return ret;
6766 }
6767
6768 static void vl_api_sw_interface_get_table_reply_t_handler
6769   (vl_api_sw_interface_get_table_reply_t * mp)
6770 {
6771   vat_main_t *vam = &vat_main;
6772
6773   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6774
6775   vam->retval = ntohl (mp->retval);
6776   vam->result_ready = 1;
6777
6778 }
6779
6780 static void vl_api_sw_interface_get_table_reply_t_handler_json
6781   (vl_api_sw_interface_get_table_reply_t * mp)
6782 {
6783   vat_main_t *vam = &vat_main;
6784   vat_json_node_t node;
6785
6786   vat_json_init_object (&node);
6787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6788   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6789
6790   vat_json_print (vam->ofp, &node);
6791   vat_json_free (&node);
6792
6793   vam->retval = ntohl (mp->retval);
6794   vam->result_ready = 1;
6795 }
6796
6797 static int
6798 api_sw_interface_get_table (vat_main_t * vam)
6799 {
6800   unformat_input_t *i = vam->input;
6801   vl_api_sw_interface_get_table_t *mp;
6802   u32 sw_if_index;
6803   u8 sw_if_index_set = 0;
6804   u8 is_ipv6 = 0;
6805   int ret;
6806
6807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6808     {
6809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6810         sw_if_index_set = 1;
6811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6812         sw_if_index_set = 1;
6813       else if (unformat (i, "ipv6"))
6814         is_ipv6 = 1;
6815       else
6816         break;
6817     }
6818
6819   if (sw_if_index_set == 0)
6820     {
6821       errmsg ("missing interface name or sw_if_index");
6822       return -99;
6823     }
6824
6825   M (SW_INTERFACE_GET_TABLE, mp);
6826   mp->sw_if_index = htonl (sw_if_index);
6827   mp->is_ipv6 = is_ipv6;
6828
6829   S (mp);
6830   W (ret);
6831   return ret;
6832 }
6833
6834 static int
6835 api_sw_interface_set_vpath (vat_main_t * vam)
6836 {
6837   unformat_input_t *i = vam->input;
6838   vl_api_sw_interface_set_vpath_t *mp;
6839   u32 sw_if_index = 0;
6840   u8 sw_if_index_set = 0;
6841   u8 is_enable = 0;
6842   int ret;
6843
6844   /* Parse args required to build the message */
6845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846     {
6847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6848         sw_if_index_set = 1;
6849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6850         sw_if_index_set = 1;
6851       else if (unformat (i, "enable"))
6852         is_enable = 1;
6853       else if (unformat (i, "disable"))
6854         is_enable = 0;
6855       else
6856         break;
6857     }
6858
6859   if (sw_if_index_set == 0)
6860     {
6861       errmsg ("missing interface name or sw_if_index");
6862       return -99;
6863     }
6864
6865   /* Construct the API message */
6866   M (SW_INTERFACE_SET_VPATH, mp);
6867
6868   mp->sw_if_index = ntohl (sw_if_index);
6869   mp->enable = is_enable;
6870
6871   /* send it... */
6872   S (mp);
6873
6874   /* Wait for a reply... */
6875   W (ret);
6876   return ret;
6877 }
6878
6879 static int
6880 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6881 {
6882   unformat_input_t *i = vam->input;
6883   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6884   u32 sw_if_index = 0;
6885   u8 sw_if_index_set = 0;
6886   u8 is_enable = 1;
6887   u8 is_ipv6 = 0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894         sw_if_index_set = 1;
6895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "enable"))
6898         is_enable = 1;
6899       else if (unformat (i, "disable"))
6900         is_enable = 0;
6901       else if (unformat (i, "ip4"))
6902         is_ipv6 = 0;
6903       else if (unformat (i, "ip6"))
6904         is_ipv6 = 1;
6905       else
6906         break;
6907     }
6908
6909   if (sw_if_index_set == 0)
6910     {
6911       errmsg ("missing interface name or sw_if_index");
6912       return -99;
6913     }
6914
6915   /* Construct the API message */
6916   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6917
6918   mp->sw_if_index = ntohl (sw_if_index);
6919   mp->enable = is_enable;
6920   mp->is_ipv6 = is_ipv6;
6921
6922   /* send it... */
6923   S (mp);
6924
6925   /* Wait for a reply... */
6926   W (ret);
6927   return ret;
6928 }
6929
6930 static int
6931 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6932 {
6933   unformat_input_t *i = vam->input;
6934   vl_api_sw_interface_set_geneve_bypass_t *mp;
6935   u32 sw_if_index = 0;
6936   u8 sw_if_index_set = 0;
6937   u8 is_enable = 1;
6938   u8 is_ipv6 = 0;
6939   int ret;
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6945         sw_if_index_set = 1;
6946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "enable"))
6949         is_enable = 1;
6950       else if (unformat (i, "disable"))
6951         is_enable = 0;
6952       else if (unformat (i, "ip4"))
6953         is_ipv6 = 0;
6954       else if (unformat (i, "ip6"))
6955         is_ipv6 = 1;
6956       else
6957         break;
6958     }
6959
6960   if (sw_if_index_set == 0)
6961     {
6962       errmsg ("missing interface name or sw_if_index");
6963       return -99;
6964     }
6965
6966   /* Construct the API message */
6967   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6968
6969   mp->sw_if_index = ntohl (sw_if_index);
6970   mp->enable = is_enable;
6971   mp->is_ipv6 = is_ipv6;
6972
6973   /* send it... */
6974   S (mp);
6975
6976   /* Wait for a reply... */
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static int
6982 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_sw_interface_set_l2_xconnect_t *mp;
6986   u32 rx_sw_if_index;
6987   u8 rx_sw_if_index_set = 0;
6988   u32 tx_sw_if_index;
6989   u8 tx_sw_if_index_set = 0;
6990   u8 enable = 1;
6991   int ret;
6992
6993   /* Parse args required to build the message */
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6997         rx_sw_if_index_set = 1;
6998       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6999         tx_sw_if_index_set = 1;
7000       else if (unformat (i, "rx"))
7001         {
7002           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003             {
7004               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7005                             &rx_sw_if_index))
7006                 rx_sw_if_index_set = 1;
7007             }
7008           else
7009             break;
7010         }
7011       else if (unformat (i, "tx"))
7012         {
7013           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014             {
7015               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7016                             &tx_sw_if_index))
7017                 tx_sw_if_index_set = 1;
7018             }
7019           else
7020             break;
7021         }
7022       else if (unformat (i, "enable"))
7023         enable = 1;
7024       else if (unformat (i, "disable"))
7025         enable = 0;
7026       else
7027         break;
7028     }
7029
7030   if (rx_sw_if_index_set == 0)
7031     {
7032       errmsg ("missing rx interface name or rx_sw_if_index");
7033       return -99;
7034     }
7035
7036   if (enable && (tx_sw_if_index_set == 0))
7037     {
7038       errmsg ("missing tx interface name or tx_sw_if_index");
7039       return -99;
7040     }
7041
7042   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7043
7044   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7045   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7046   mp->enable = enable;
7047
7048   S (mp);
7049   W (ret);
7050   return ret;
7051 }
7052
7053 static int
7054 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7055 {
7056   unformat_input_t *i = vam->input;
7057   vl_api_sw_interface_set_l2_bridge_t *mp;
7058   u32 rx_sw_if_index;
7059   u8 rx_sw_if_index_set = 0;
7060   u32 bd_id;
7061   u8 bd_id_set = 0;
7062   u8 bvi = 0;
7063   u32 shg = 0;
7064   u8 enable = 1;
7065   int ret;
7066
7067   /* Parse args required to build the message */
7068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069     {
7070       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7071         rx_sw_if_index_set = 1;
7072       else if (unformat (i, "bd_id %d", &bd_id))
7073         bd_id_set = 1;
7074       else
7075         if (unformat
7076             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7077         rx_sw_if_index_set = 1;
7078       else if (unformat (i, "shg %d", &shg))
7079         ;
7080       else if (unformat (i, "bvi"))
7081         bvi = 1;
7082       else if (unformat (i, "enable"))
7083         enable = 1;
7084       else if (unformat (i, "disable"))
7085         enable = 0;
7086       else
7087         break;
7088     }
7089
7090   if (rx_sw_if_index_set == 0)
7091     {
7092       errmsg ("missing rx interface name or sw_if_index");
7093       return -99;
7094     }
7095
7096   if (enable && (bd_id_set == 0))
7097     {
7098       errmsg ("missing bridge domain");
7099       return -99;
7100     }
7101
7102   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7103
7104   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7105   mp->bd_id = ntohl (bd_id);
7106   mp->shg = (u8) shg;
7107   mp->bvi = bvi;
7108   mp->enable = enable;
7109
7110   S (mp);
7111   W (ret);
7112   return ret;
7113 }
7114
7115 static int
7116 api_bridge_domain_dump (vat_main_t * vam)
7117 {
7118   unformat_input_t *i = vam->input;
7119   vl_api_bridge_domain_dump_t *mp;
7120   vl_api_control_ping_t *mp_ping;
7121   u32 bd_id = ~0;
7122   int ret;
7123
7124   /* Parse args required to build the message */
7125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7126     {
7127       if (unformat (i, "bd_id %d", &bd_id))
7128         ;
7129       else
7130         break;
7131     }
7132
7133   M (BRIDGE_DOMAIN_DUMP, mp);
7134   mp->bd_id = ntohl (bd_id);
7135   S (mp);
7136
7137   /* Use a control ping for synchronization */
7138   MPING (CONTROL_PING, mp_ping);
7139   S (mp_ping);
7140
7141   W (ret);
7142   return ret;
7143 }
7144
7145 static int
7146 api_bridge_domain_add_del (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_bridge_domain_add_del_t *mp;
7150   u32 bd_id = ~0;
7151   u8 is_add = 1;
7152   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7153   u8 *bd_tag = NULL;
7154   u32 mac_age = 0;
7155   int ret;
7156
7157   /* Parse args required to build the message */
7158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7159     {
7160       if (unformat (i, "bd_id %d", &bd_id))
7161         ;
7162       else if (unformat (i, "flood %d", &flood))
7163         ;
7164       else if (unformat (i, "uu-flood %d", &uu_flood))
7165         ;
7166       else if (unformat (i, "forward %d", &forward))
7167         ;
7168       else if (unformat (i, "learn %d", &learn))
7169         ;
7170       else if (unformat (i, "arp-term %d", &arp_term))
7171         ;
7172       else if (unformat (i, "mac-age %d", &mac_age))
7173         ;
7174       else if (unformat (i, "bd-tag %s", &bd_tag))
7175         ;
7176       else if (unformat (i, "del"))
7177         {
7178           is_add = 0;
7179           flood = uu_flood = forward = learn = 0;
7180         }
7181       else
7182         break;
7183     }
7184
7185   if (bd_id == ~0)
7186     {
7187       errmsg ("missing bridge domain");
7188       ret = -99;
7189       goto done;
7190     }
7191
7192   if (mac_age > 255)
7193     {
7194       errmsg ("mac age must be less than 256 ");
7195       ret = -99;
7196       goto done;
7197     }
7198
7199   if ((bd_tag) && (vec_len (bd_tag) > 63))
7200     {
7201       errmsg ("bd-tag cannot be longer than 63");
7202       ret = -99;
7203       goto done;
7204     }
7205
7206   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7207
7208   mp->bd_id = ntohl (bd_id);
7209   mp->flood = flood;
7210   mp->uu_flood = uu_flood;
7211   mp->forward = forward;
7212   mp->learn = learn;
7213   mp->arp_term = arp_term;
7214   mp->is_add = is_add;
7215   mp->mac_age = (u8) mac_age;
7216   if (bd_tag)
7217     {
7218       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7219       mp->bd_tag[vec_len (bd_tag)] = 0;
7220     }
7221   S (mp);
7222   W (ret);
7223
7224 done:
7225   vec_free (bd_tag);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_flush_bd (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_flush_bd_t *mp;
7234   u32 bd_id = ~0;
7235   int ret;
7236
7237   /* Parse args required to build the message */
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "bd_id %d", &bd_id));
7241       else
7242         break;
7243     }
7244
7245   if (bd_id == ~0)
7246     {
7247       errmsg ("missing bridge domain");
7248       return -99;
7249     }
7250
7251   M (L2FIB_FLUSH_BD, mp);
7252
7253   mp->bd_id = htonl (bd_id);
7254
7255   S (mp);
7256   W (ret);
7257   return ret;
7258 }
7259
7260 static int
7261 api_l2fib_flush_int (vat_main_t * vam)
7262 {
7263   unformat_input_t *i = vam->input;
7264   vl_api_l2fib_flush_int_t *mp;
7265   u32 sw_if_index = ~0;
7266   int ret;
7267
7268   /* Parse args required to build the message */
7269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7270     {
7271       if (unformat (i, "sw_if_index %d", &sw_if_index));
7272       else
7273         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7274       else
7275         break;
7276     }
7277
7278   if (sw_if_index == ~0)
7279     {
7280       errmsg ("missing interface name or sw_if_index");
7281       return -99;
7282     }
7283
7284   M (L2FIB_FLUSH_INT, mp);
7285
7286   mp->sw_if_index = ntohl (sw_if_index);
7287
7288   S (mp);
7289   W (ret);
7290   return ret;
7291 }
7292
7293 static int
7294 api_l2fib_add_del (vat_main_t * vam)
7295 {
7296   unformat_input_t *i = vam->input;
7297   vl_api_l2fib_add_del_t *mp;
7298   f64 timeout;
7299   u8 mac[6] = { 0 };
7300   u8 mac_set = 0;
7301   u32 bd_id;
7302   u8 bd_id_set = 0;
7303   u32 sw_if_index = 0;
7304   u8 sw_if_index_set = 0;
7305   u8 is_add = 1;
7306   u8 static_mac = 0;
7307   u8 filter_mac = 0;
7308   u8 bvi_mac = 0;
7309   int count = 1;
7310   f64 before = 0;
7311   int j;
7312
7313   /* Parse args required to build the message */
7314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7315     {
7316       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7317         mac_set = 1;
7318       else if (unformat (i, "bd_id %d", &bd_id))
7319         bd_id_set = 1;
7320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7321         sw_if_index_set = 1;
7322       else if (unformat (i, "sw_if"))
7323         {
7324           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325             {
7326               if (unformat
7327                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7328                 sw_if_index_set = 1;
7329             }
7330           else
7331             break;
7332         }
7333       else if (unformat (i, "static"))
7334         static_mac = 1;
7335       else if (unformat (i, "filter"))
7336         {
7337           filter_mac = 1;
7338           static_mac = 1;
7339         }
7340       else if (unformat (i, "bvi"))
7341         {
7342           bvi_mac = 1;
7343           static_mac = 1;
7344         }
7345       else if (unformat (i, "del"))
7346         is_add = 0;
7347       else if (unformat (i, "count %d", &count))
7348         ;
7349       else
7350         break;
7351     }
7352
7353   if (mac_set == 0)
7354     {
7355       errmsg ("missing mac address");
7356       return -99;
7357     }
7358
7359   if (bd_id_set == 0)
7360     {
7361       errmsg ("missing bridge domain");
7362       return -99;
7363     }
7364
7365   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7366     {
7367       errmsg ("missing interface name or sw_if_index");
7368       return -99;
7369     }
7370
7371   if (count > 1)
7372     {
7373       /* Turn on async mode */
7374       vam->async_mode = 1;
7375       vam->async_errors = 0;
7376       before = vat_time_now (vam);
7377     }
7378
7379   for (j = 0; j < count; j++)
7380     {
7381       M (L2FIB_ADD_DEL, mp);
7382
7383       clib_memcpy (mp->mac, mac, 6);
7384       mp->bd_id = ntohl (bd_id);
7385       mp->is_add = is_add;
7386       mp->sw_if_index = ntohl (sw_if_index);
7387
7388       if (is_add)
7389         {
7390           mp->static_mac = static_mac;
7391           mp->filter_mac = filter_mac;
7392           mp->bvi_mac = bvi_mac;
7393         }
7394       increment_mac_address (mac);
7395       /* send it... */
7396       S (mp);
7397     }
7398
7399   if (count > 1)
7400     {
7401       vl_api_control_ping_t *mp_ping;
7402       f64 after;
7403
7404       /* Shut off async mode */
7405       vam->async_mode = 0;
7406
7407       MPING (CONTROL_PING, mp_ping);
7408       S (mp_ping);
7409
7410       timeout = vat_time_now (vam) + 1.0;
7411       while (vat_time_now (vam) < timeout)
7412         if (vam->result_ready == 1)
7413           goto out;
7414       vam->retval = -99;
7415
7416     out:
7417       if (vam->retval == -99)
7418         errmsg ("timeout");
7419
7420       if (vam->async_errors > 0)
7421         {
7422           errmsg ("%d asynchronous errors", vam->async_errors);
7423           vam->retval = -98;
7424         }
7425       vam->async_errors = 0;
7426       after = vat_time_now (vam);
7427
7428       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7429              count, after - before, count / (after - before));
7430     }
7431   else
7432     {
7433       int ret;
7434
7435       /* Wait for a reply... */
7436       W (ret);
7437       return ret;
7438     }
7439   /* Return the good/bad news */
7440   return (vam->retval);
7441 }
7442
7443 static int
7444 api_bridge_domain_set_mac_age (vat_main_t * vam)
7445 {
7446   unformat_input_t *i = vam->input;
7447   vl_api_bridge_domain_set_mac_age_t *mp;
7448   u32 bd_id = ~0;
7449   u32 mac_age = 0;
7450   int ret;
7451
7452   /* Parse args required to build the message */
7453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7454     {
7455       if (unformat (i, "bd_id %d", &bd_id));
7456       else if (unformat (i, "mac-age %d", &mac_age));
7457       else
7458         break;
7459     }
7460
7461   if (bd_id == ~0)
7462     {
7463       errmsg ("missing bridge domain");
7464       return -99;
7465     }
7466
7467   if (mac_age > 255)
7468     {
7469       errmsg ("mac age must be less than 256 ");
7470       return -99;
7471     }
7472
7473   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7474
7475   mp->bd_id = htonl (bd_id);
7476   mp->mac_age = (u8) mac_age;
7477
7478   S (mp);
7479   W (ret);
7480   return ret;
7481 }
7482
7483 static int
7484 api_l2_flags (vat_main_t * vam)
7485 {
7486   unformat_input_t *i = vam->input;
7487   vl_api_l2_flags_t *mp;
7488   u32 sw_if_index;
7489   u32 flags = 0;
7490   u8 sw_if_index_set = 0;
7491   u8 is_set = 0;
7492   int ret;
7493
7494   /* Parse args required to build the message */
7495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7496     {
7497       if (unformat (i, "sw_if_index %d", &sw_if_index))
7498         sw_if_index_set = 1;
7499       else if (unformat (i, "sw_if"))
7500         {
7501           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7502             {
7503               if (unformat
7504                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7505                 sw_if_index_set = 1;
7506             }
7507           else
7508             break;
7509         }
7510       else if (unformat (i, "learn"))
7511         flags |= L2_LEARN;
7512       else if (unformat (i, "forward"))
7513         flags |= L2_FWD;
7514       else if (unformat (i, "flood"))
7515         flags |= L2_FLOOD;
7516       else if (unformat (i, "uu-flood"))
7517         flags |= L2_UU_FLOOD;
7518       else if (unformat (i, "arp-term"))
7519         flags |= L2_ARP_TERM;
7520       else if (unformat (i, "off"))
7521         is_set = 0;
7522       else if (unformat (i, "disable"))
7523         is_set = 0;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing interface name or sw_if_index");
7531       return -99;
7532     }
7533
7534   M (L2_FLAGS, mp);
7535
7536   mp->sw_if_index = ntohl (sw_if_index);
7537   mp->feature_bitmap = ntohl (flags);
7538   mp->is_set = is_set;
7539
7540   S (mp);
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_bridge_flags (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_bridge_flags_t *mp;
7550   u32 bd_id;
7551   u8 bd_id_set = 0;
7552   u8 is_set = 1;
7553   u32 flags = 0;
7554   int ret;
7555
7556   /* Parse args required to build the message */
7557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7558     {
7559       if (unformat (i, "bd_id %d", &bd_id))
7560         bd_id_set = 1;
7561       else if (unformat (i, "learn"))
7562         flags |= L2_LEARN;
7563       else if (unformat (i, "forward"))
7564         flags |= L2_FWD;
7565       else if (unformat (i, "flood"))
7566         flags |= L2_FLOOD;
7567       else if (unformat (i, "uu-flood"))
7568         flags |= L2_UU_FLOOD;
7569       else if (unformat (i, "arp-term"))
7570         flags |= L2_ARP_TERM;
7571       else if (unformat (i, "off"))
7572         is_set = 0;
7573       else if (unformat (i, "disable"))
7574         is_set = 0;
7575       else
7576         break;
7577     }
7578
7579   if (bd_id_set == 0)
7580     {
7581       errmsg ("missing bridge domain");
7582       return -99;
7583     }
7584
7585   M (BRIDGE_FLAGS, mp);
7586
7587   mp->bd_id = ntohl (bd_id);
7588   mp->feature_bitmap = ntohl (flags);
7589   mp->is_set = is_set;
7590
7591   S (mp);
7592   W (ret);
7593   return ret;
7594 }
7595
7596 static int
7597 api_bd_ip_mac_add_del (vat_main_t * vam)
7598 {
7599   unformat_input_t *i = vam->input;
7600   vl_api_bd_ip_mac_add_del_t *mp;
7601   u32 bd_id;
7602   u8 is_ipv6 = 0;
7603   u8 is_add = 1;
7604   u8 bd_id_set = 0;
7605   u8 ip_set = 0;
7606   u8 mac_set = 0;
7607   ip4_address_t v4addr;
7608   ip6_address_t v6addr;
7609   u8 macaddr[6];
7610   int ret;
7611
7612
7613   /* Parse args required to build the message */
7614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7615     {
7616       if (unformat (i, "bd_id %d", &bd_id))
7617         {
7618           bd_id_set++;
7619         }
7620       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7621         {
7622           ip_set++;
7623         }
7624       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7625         {
7626           ip_set++;
7627           is_ipv6++;
7628         }
7629       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7630         {
7631           mac_set++;
7632         }
7633       else if (unformat (i, "del"))
7634         is_add = 0;
7635       else
7636         break;
7637     }
7638
7639   if (bd_id_set == 0)
7640     {
7641       errmsg ("missing bridge domain");
7642       return -99;
7643     }
7644   else if (ip_set == 0)
7645     {
7646       errmsg ("missing IP address");
7647       return -99;
7648     }
7649   else if (mac_set == 0)
7650     {
7651       errmsg ("missing MAC address");
7652       return -99;
7653     }
7654
7655   M (BD_IP_MAC_ADD_DEL, mp);
7656
7657   mp->bd_id = ntohl (bd_id);
7658   mp->is_ipv6 = is_ipv6;
7659   mp->is_add = is_add;
7660   if (is_ipv6)
7661     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7662   else
7663     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7664   clib_memcpy (mp->mac_address, macaddr, 6);
7665   S (mp);
7666   W (ret);
7667   return ret;
7668 }
7669
7670 static int
7671 api_tap_connect (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_tap_connect_t *mp;
7675   u8 mac_address[6];
7676   u8 random_mac = 1;
7677   u8 name_set = 0;
7678   u8 *tap_name;
7679   u8 *tag = 0;
7680   ip4_address_t ip4_address;
7681   u32 ip4_mask_width;
7682   int ip4_address_set = 0;
7683   ip6_address_t ip6_address;
7684   u32 ip6_mask_width;
7685   int ip6_address_set = 0;
7686   int ret;
7687
7688   memset (mac_address, 0, sizeof (mac_address));
7689
7690   /* Parse args required to build the message */
7691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7692     {
7693       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7694         {
7695           random_mac = 0;
7696         }
7697       else if (unformat (i, "random-mac"))
7698         random_mac = 1;
7699       else if (unformat (i, "tapname %s", &tap_name))
7700         name_set = 1;
7701       else if (unformat (i, "tag %s", &tag))
7702         ;
7703       else if (unformat (i, "address %U/%d",
7704                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7705         ip4_address_set = 1;
7706       else if (unformat (i, "address %U/%d",
7707                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7708         ip6_address_set = 1;
7709       else
7710         break;
7711     }
7712
7713   if (name_set == 0)
7714     {
7715       errmsg ("missing tap name");
7716       return -99;
7717     }
7718   if (vec_len (tap_name) > 63)
7719     {
7720       errmsg ("tap name too long");
7721       return -99;
7722     }
7723   vec_add1 (tap_name, 0);
7724
7725   if (vec_len (tag) > 63)
7726     {
7727       errmsg ("tag too long");
7728       return -99;
7729     }
7730
7731   /* Construct the API message */
7732   M (TAP_CONNECT, mp);
7733
7734   mp->use_random_mac = random_mac;
7735   clib_memcpy (mp->mac_address, mac_address, 6);
7736   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7737   if (tag)
7738     clib_memcpy (mp->tag, tag, vec_len (tag));
7739
7740   if (ip4_address_set)
7741     {
7742       mp->ip4_address_set = 1;
7743       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7744       mp->ip4_mask_width = ip4_mask_width;
7745     }
7746   if (ip6_address_set)
7747     {
7748       mp->ip6_address_set = 1;
7749       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7750       mp->ip6_mask_width = ip6_mask_width;
7751     }
7752
7753   vec_free (tap_name);
7754   vec_free (tag);
7755
7756   /* send it... */
7757   S (mp);
7758
7759   /* Wait for a reply... */
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_tap_modify (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_tap_modify_t *mp;
7769   u8 mac_address[6];
7770   u8 random_mac = 1;
7771   u8 name_set = 0;
7772   u8 *tap_name;
7773   u32 sw_if_index = ~0;
7774   u8 sw_if_index_set = 0;
7775   int ret;
7776
7777   memset (mac_address, 0, sizeof (mac_address));
7778
7779   /* Parse args required to build the message */
7780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7781     {
7782       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7783         sw_if_index_set = 1;
7784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7785         sw_if_index_set = 1;
7786       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7787         {
7788           random_mac = 0;
7789         }
7790       else if (unformat (i, "random-mac"))
7791         random_mac = 1;
7792       else if (unformat (i, "tapname %s", &tap_name))
7793         name_set = 1;
7794       else
7795         break;
7796     }
7797
7798   if (sw_if_index_set == 0)
7799     {
7800       errmsg ("missing vpp interface name");
7801       return -99;
7802     }
7803   if (name_set == 0)
7804     {
7805       errmsg ("missing tap name");
7806       return -99;
7807     }
7808   if (vec_len (tap_name) > 63)
7809     {
7810       errmsg ("tap name too long");
7811     }
7812   vec_add1 (tap_name, 0);
7813
7814   /* Construct the API message */
7815   M (TAP_MODIFY, mp);
7816
7817   mp->use_random_mac = random_mac;
7818   mp->sw_if_index = ntohl (sw_if_index);
7819   clib_memcpy (mp->mac_address, mac_address, 6);
7820   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7821   vec_free (tap_name);
7822
7823   /* send it... */
7824   S (mp);
7825
7826   /* Wait for a reply... */
7827   W (ret);
7828   return ret;
7829 }
7830
7831 static int
7832 api_tap_delete (vat_main_t * vam)
7833 {
7834   unformat_input_t *i = vam->input;
7835   vl_api_tap_delete_t *mp;
7836   u32 sw_if_index = ~0;
7837   u8 sw_if_index_set = 0;
7838   int ret;
7839
7840   /* Parse args required to build the message */
7841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7842     {
7843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7844         sw_if_index_set = 1;
7845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7846         sw_if_index_set = 1;
7847       else
7848         break;
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing vpp interface name");
7854       return -99;
7855     }
7856
7857   /* Construct the API message */
7858   M (TAP_DELETE, mp);
7859
7860   mp->sw_if_index = ntohl (sw_if_index);
7861
7862   /* send it... */
7863   S (mp);
7864
7865   /* Wait for a reply... */
7866   W (ret);
7867   return ret;
7868 }
7869
7870 static int
7871 api_tap_create_v2 (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_tap_create_v2_t *mp;
7875   u8 mac_address[6];
7876   u8 random_mac = 1;
7877   u32 id = ~0;
7878   u8 *host_if_name = 0;
7879   u8 *host_ns = 0;
7880   u8 host_mac_addr[6];
7881   u8 host_mac_addr_set = 0;
7882   u8 *host_bridge = 0;
7883   ip4_address_t host_ip4_addr;
7884   ip4_address_t host_ip4_gw;
7885   u8 host_ip4_gw_set = 0;
7886   u32 host_ip4_prefix_len = 0;
7887   ip6_address_t host_ip6_addr;
7888   ip6_address_t host_ip6_gw;
7889   u8 host_ip6_gw_set = 0;
7890   u32 host_ip6_prefix_len = 0;
7891   int ret;
7892   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7893
7894   memset (mac_address, 0, sizeof (mac_address));
7895
7896   /* Parse args required to build the message */
7897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7898     {
7899       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7900         {
7901           random_mac = 0;
7902         }
7903       else if (unformat (i, "id %u", &id))
7904         ;
7905       else if (unformat (i, "host-if-name %s", &host_if_name))
7906         ;
7907       else if (unformat (i, "host-ns %s", &host_ns))
7908         ;
7909       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7910                          host_mac_addr))
7911         host_mac_addr_set = 1;
7912       else if (unformat (i, "host-bridge %s", &host_bridge))
7913         ;
7914       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7915                          &host_ip4_addr, &host_ip4_prefix_len))
7916         ;
7917       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7918                          &host_ip6_addr, &host_ip6_prefix_len))
7919         ;
7920       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7921                          &host_ip4_gw))
7922         host_ip4_gw_set = 1;
7923       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7924                          &host_ip6_gw))
7925         host_ip6_gw_set = 1;
7926       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7927         ;
7928       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7929         ;
7930       else
7931         break;
7932     }
7933
7934   if (vec_len (host_if_name) > 63)
7935     {
7936       errmsg ("tap name too long. ");
7937       return -99;
7938     }
7939   if (vec_len (host_ns) > 63)
7940     {
7941       errmsg ("host name space too long. ");
7942       return -99;
7943     }
7944   if (vec_len (host_bridge) > 63)
7945     {
7946       errmsg ("host bridge name too long. ");
7947       return -99;
7948     }
7949   if (host_ip4_prefix_len > 32)
7950     {
7951       errmsg ("host ip4 prefix length not valid. ");
7952       return -99;
7953     }
7954   if (host_ip6_prefix_len > 128)
7955     {
7956       errmsg ("host ip6 prefix length not valid. ");
7957       return -99;
7958     }
7959   if (!is_pow2 (rx_ring_sz))
7960     {
7961       errmsg ("rx ring size must be power of 2. ");
7962       return -99;
7963     }
7964   if (rx_ring_sz > 32768)
7965     {
7966       errmsg ("rx ring size must be 32768 or lower. ");
7967       return -99;
7968     }
7969   if (!is_pow2 (tx_ring_sz))
7970     {
7971       errmsg ("tx ring size must be power of 2. ");
7972       return -99;
7973     }
7974   if (tx_ring_sz > 32768)
7975     {
7976       errmsg ("tx ring size must be 32768 or lower. ");
7977       return -99;
7978     }
7979
7980   /* Construct the API message */
7981   M (TAP_CREATE_V2, mp);
7982
7983   mp->use_random_mac = random_mac;
7984
7985   mp->id = ntohl (id);
7986   mp->host_namespace_set = host_ns != 0;
7987   mp->host_bridge_set = host_bridge != 0;
7988   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7989   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7990   mp->rx_ring_sz = ntohs (rx_ring_sz);
7991   mp->tx_ring_sz = ntohs (tx_ring_sz);
7992
7993   if (random_mac == 0)
7994     clib_memcpy (mp->mac_address, mac_address, 6);
7995   if (host_mac_addr_set)
7996     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7997   if (host_if_name)
7998     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7999   if (host_ns)
8000     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8001   if (host_bridge)
8002     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8003   if (host_ip4_prefix_len)
8004     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8005   if (host_ip4_prefix_len)
8006     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8007   if (host_ip4_gw_set)
8008     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8009   if (host_ip6_gw_set)
8010     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8011
8012   vec_free (host_ns);
8013   vec_free (host_if_name);
8014   vec_free (host_bridge);
8015
8016   /* send it... */
8017   S (mp);
8018
8019   /* Wait for a reply... */
8020   W (ret);
8021   return ret;
8022 }
8023
8024 static int
8025 api_tap_delete_v2 (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_tap_delete_v2_t *mp;
8029   u32 sw_if_index = ~0;
8030   u8 sw_if_index_set = 0;
8031   int ret;
8032
8033   /* Parse args required to build the message */
8034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8035     {
8036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8037         sw_if_index_set = 1;
8038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8039         sw_if_index_set = 1;
8040       else
8041         break;
8042     }
8043
8044   if (sw_if_index_set == 0)
8045     {
8046       errmsg ("missing vpp interface name. ");
8047       return -99;
8048     }
8049
8050   /* Construct the API message */
8051   M (TAP_DELETE_V2, mp);
8052
8053   mp->sw_if_index = ntohl (sw_if_index);
8054
8055   /* send it... */
8056   S (mp);
8057
8058   /* Wait for a reply... */
8059   W (ret);
8060   return ret;
8061 }
8062
8063 static int
8064 api_bond_create (vat_main_t * vam)
8065 {
8066   unformat_input_t *i = vam->input;
8067   vl_api_bond_create_t *mp;
8068   u8 mac_address[6];
8069   u8 custom_mac = 0;
8070   int ret;
8071   u8 mode;
8072   u8 lb;
8073   u8 mode_is_set = 0;
8074
8075   memset (mac_address, 0, sizeof (mac_address));
8076   lb = BOND_LB_L2;
8077
8078   /* Parse args required to build the message */
8079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8080     {
8081       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8082         mode_is_set = 1;
8083       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8084                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8085         ;
8086       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8087                          mac_address))
8088         custom_mac = 1;
8089       else
8090         break;
8091     }
8092
8093   if (mode_is_set == 0)
8094     {
8095       errmsg ("Missing bond mode. ");
8096       return -99;
8097     }
8098
8099   /* Construct the API message */
8100   M (BOND_CREATE, mp);
8101
8102   mp->use_custom_mac = custom_mac;
8103
8104   mp->mode = mode;
8105   mp->lb = lb;
8106
8107   if (custom_mac)
8108     clib_memcpy (mp->mac_address, mac_address, 6);
8109
8110   /* send it... */
8111   S (mp);
8112
8113   /* Wait for a reply... */
8114   W (ret);
8115   return ret;
8116 }
8117
8118 static int
8119 api_bond_delete (vat_main_t * vam)
8120 {
8121   unformat_input_t *i = vam->input;
8122   vl_api_bond_delete_t *mp;
8123   u32 sw_if_index = ~0;
8124   u8 sw_if_index_set = 0;
8125   int ret;
8126
8127   /* Parse args required to build the message */
8128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8129     {
8130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8131         sw_if_index_set = 1;
8132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8133         sw_if_index_set = 1;
8134       else
8135         break;
8136     }
8137
8138   if (sw_if_index_set == 0)
8139     {
8140       errmsg ("missing vpp interface name. ");
8141       return -99;
8142     }
8143
8144   /* Construct the API message */
8145   M (BOND_DELETE, mp);
8146
8147   mp->sw_if_index = ntohl (sw_if_index);
8148
8149   /* send it... */
8150   S (mp);
8151
8152   /* Wait for a reply... */
8153   W (ret);
8154   return ret;
8155 }
8156
8157 static int
8158 api_bond_enslave (vat_main_t * vam)
8159 {
8160   unformat_input_t *i = vam->input;
8161   vl_api_bond_enslave_t *mp;
8162   u32 bond_sw_if_index;
8163   int ret;
8164   u8 is_passive;
8165   u8 is_long_timeout;
8166   u32 bond_sw_if_index_is_set = 0;
8167   u32 sw_if_index;
8168   u8 sw_if_index_is_set = 0;
8169
8170   /* Parse args required to build the message */
8171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8172     {
8173       if (unformat (i, "sw_if_index %d", &sw_if_index))
8174         sw_if_index_is_set = 1;
8175       else if (unformat (i, "bond %u", &bond_sw_if_index))
8176         bond_sw_if_index_is_set = 1;
8177       else if (unformat (i, "passive %d", &is_passive))
8178         ;
8179       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8180         ;
8181       else
8182         break;
8183     }
8184
8185   if (bond_sw_if_index_is_set == 0)
8186     {
8187       errmsg ("Missing bond sw_if_index. ");
8188       return -99;
8189     }
8190   if (sw_if_index_is_set == 0)
8191     {
8192       errmsg ("Missing slave sw_if_index. ");
8193       return -99;
8194     }
8195
8196   /* Construct the API message */
8197   M (BOND_ENSLAVE, mp);
8198
8199   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8200   mp->sw_if_index = ntohl (sw_if_index);
8201   mp->is_long_timeout = is_long_timeout;
8202   mp->is_passive = is_passive;
8203
8204   /* send it... */
8205   S (mp);
8206
8207   /* Wait for a reply... */
8208   W (ret);
8209   return ret;
8210 }
8211
8212 static int
8213 api_bond_detach_slave (vat_main_t * vam)
8214 {
8215   unformat_input_t *i = vam->input;
8216   vl_api_bond_detach_slave_t *mp;
8217   u32 sw_if_index = ~0;
8218   u8 sw_if_index_set = 0;
8219   int ret;
8220
8221   /* Parse args required to build the message */
8222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8225         sw_if_index_set = 1;
8226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8227         sw_if_index_set = 1;
8228       else
8229         break;
8230     }
8231
8232   if (sw_if_index_set == 0)
8233     {
8234       errmsg ("missing vpp interface name. ");
8235       return -99;
8236     }
8237
8238   /* Construct the API message */
8239   M (BOND_DETACH_SLAVE, mp);
8240
8241   mp->sw_if_index = ntohl (sw_if_index);
8242
8243   /* send it... */
8244   S (mp);
8245
8246   /* Wait for a reply... */
8247   W (ret);
8248   return ret;
8249 }
8250
8251 static int
8252 api_ip_table_add_del (vat_main_t * vam)
8253 {
8254   unformat_input_t *i = vam->input;
8255   vl_api_ip_table_add_del_t *mp;
8256   u32 table_id = ~0;
8257   u8 is_ipv6 = 0;
8258   u8 is_add = 1;
8259   int ret = 0;
8260
8261   /* Parse args required to build the message */
8262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8263     {
8264       if (unformat (i, "ipv6"))
8265         is_ipv6 = 1;
8266       else if (unformat (i, "del"))
8267         is_add = 0;
8268       else if (unformat (i, "add"))
8269         is_add = 1;
8270       else if (unformat (i, "table %d", &table_id))
8271         ;
8272       else
8273         {
8274           clib_warning ("parse error '%U'", format_unformat_error, i);
8275           return -99;
8276         }
8277     }
8278
8279   if (~0 == table_id)
8280     {
8281       errmsg ("missing table-ID");
8282       return -99;
8283     }
8284
8285   /* Construct the API message */
8286   M (IP_TABLE_ADD_DEL, mp);
8287
8288   mp->table_id = ntohl (table_id);
8289   mp->is_ipv6 = is_ipv6;
8290   mp->is_add = is_add;
8291
8292   /* send it... */
8293   S (mp);
8294
8295   /* Wait for a reply... */
8296   W (ret);
8297
8298   return ret;
8299 }
8300
8301 static int
8302 api_ip_add_del_route (vat_main_t * vam)
8303 {
8304   unformat_input_t *i = vam->input;
8305   vl_api_ip_add_del_route_t *mp;
8306   u32 sw_if_index = ~0, vrf_id = 0;
8307   u8 is_ipv6 = 0;
8308   u8 is_local = 0, is_drop = 0;
8309   u8 is_unreach = 0, is_prohibit = 0;
8310   u8 is_add = 1;
8311   u32 next_hop_weight = 1;
8312   u8 is_multipath = 0;
8313   u8 address_set = 0;
8314   u8 address_length_set = 0;
8315   u32 next_hop_table_id = 0;
8316   u32 resolve_attempts = 0;
8317   u32 dst_address_length = 0;
8318   u8 next_hop_set = 0;
8319   ip4_address_t v4_dst_address, v4_next_hop_address;
8320   ip6_address_t v6_dst_address, v6_next_hop_address;
8321   int count = 1;
8322   int j;
8323   f64 before = 0;
8324   u32 random_add_del = 0;
8325   u32 *random_vector = 0;
8326   uword *random_hash;
8327   u32 random_seed = 0xdeaddabe;
8328   u32 classify_table_index = ~0;
8329   u8 is_classify = 0;
8330   u8 resolve_host = 0, resolve_attached = 0;
8331   mpls_label_t *next_hop_out_label_stack = NULL;
8332   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8333   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8334
8335   /* Parse args required to build the message */
8336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8339         ;
8340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8341         ;
8342       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8343         {
8344           address_set = 1;
8345           is_ipv6 = 0;
8346         }
8347       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8348         {
8349           address_set = 1;
8350           is_ipv6 = 1;
8351         }
8352       else if (unformat (i, "/%d", &dst_address_length))
8353         {
8354           address_length_set = 1;
8355         }
8356
8357       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8358                                          &v4_next_hop_address))
8359         {
8360           next_hop_set = 1;
8361         }
8362       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8363                                          &v6_next_hop_address))
8364         {
8365           next_hop_set = 1;
8366         }
8367       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8368         ;
8369       else if (unformat (i, "weight %d", &next_hop_weight))
8370         ;
8371       else if (unformat (i, "drop"))
8372         {
8373           is_drop = 1;
8374         }
8375       else if (unformat (i, "null-send-unreach"))
8376         {
8377           is_unreach = 1;
8378         }
8379       else if (unformat (i, "null-send-prohibit"))
8380         {
8381           is_prohibit = 1;
8382         }
8383       else if (unformat (i, "local"))
8384         {
8385           is_local = 1;
8386         }
8387       else if (unformat (i, "classify %d", &classify_table_index))
8388         {
8389           is_classify = 1;
8390         }
8391       else if (unformat (i, "del"))
8392         is_add = 0;
8393       else if (unformat (i, "add"))
8394         is_add = 1;
8395       else if (unformat (i, "resolve-via-host"))
8396         resolve_host = 1;
8397       else if (unformat (i, "resolve-via-attached"))
8398         resolve_attached = 1;
8399       else if (unformat (i, "multipath"))
8400         is_multipath = 1;
8401       else if (unformat (i, "vrf %d", &vrf_id))
8402         ;
8403       else if (unformat (i, "count %d", &count))
8404         ;
8405       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8406         ;
8407       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8408         ;
8409       else if (unformat (i, "out-label %d", &next_hop_out_label))
8410         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8411       else if (unformat (i, "via-label %d", &next_hop_via_label))
8412         ;
8413       else if (unformat (i, "random"))
8414         random_add_del = 1;
8415       else if (unformat (i, "seed %d", &random_seed))
8416         ;
8417       else
8418         {
8419           clib_warning ("parse error '%U'", format_unformat_error, i);
8420           return -99;
8421         }
8422     }
8423
8424   if (!next_hop_set && !is_drop && !is_local &&
8425       !is_classify && !is_unreach && !is_prohibit &&
8426       MPLS_LABEL_INVALID == next_hop_via_label)
8427     {
8428       errmsg
8429         ("next hop / local / drop / unreach / prohibit / classify not set");
8430       return -99;
8431     }
8432
8433   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8434     {
8435       errmsg ("next hop and next-hop via label set");
8436       return -99;
8437     }
8438   if (address_set == 0)
8439     {
8440       errmsg ("missing addresses");
8441       return -99;
8442     }
8443
8444   if (address_length_set == 0)
8445     {
8446       errmsg ("missing address length");
8447       return -99;
8448     }
8449
8450   /* Generate a pile of unique, random routes */
8451   if (random_add_del)
8452     {
8453       u32 this_random_address;
8454       random_hash = hash_create (count, sizeof (uword));
8455
8456       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8457       for (j = 0; j <= count; j++)
8458         {
8459           do
8460             {
8461               this_random_address = random_u32 (&random_seed);
8462               this_random_address =
8463                 clib_host_to_net_u32 (this_random_address);
8464             }
8465           while (hash_get (random_hash, this_random_address));
8466           vec_add1 (random_vector, this_random_address);
8467           hash_set (random_hash, this_random_address, 1);
8468         }
8469       hash_free (random_hash);
8470       v4_dst_address.as_u32 = random_vector[0];
8471     }
8472
8473   if (count > 1)
8474     {
8475       /* Turn on async mode */
8476       vam->async_mode = 1;
8477       vam->async_errors = 0;
8478       before = vat_time_now (vam);
8479     }
8480
8481   for (j = 0; j < count; j++)
8482     {
8483       /* Construct the API message */
8484       M2 (IP_ADD_DEL_ROUTE, mp,
8485           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8486
8487       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8488       mp->table_id = ntohl (vrf_id);
8489
8490       mp->is_add = is_add;
8491       mp->is_drop = is_drop;
8492       mp->is_unreach = is_unreach;
8493       mp->is_prohibit = is_prohibit;
8494       mp->is_ipv6 = is_ipv6;
8495       mp->is_local = is_local;
8496       mp->is_classify = is_classify;
8497       mp->is_multipath = is_multipath;
8498       mp->is_resolve_host = resolve_host;
8499       mp->is_resolve_attached = resolve_attached;
8500       mp->next_hop_weight = next_hop_weight;
8501       mp->dst_address_length = dst_address_length;
8502       mp->next_hop_table_id = ntohl (next_hop_table_id);
8503       mp->classify_table_index = ntohl (classify_table_index);
8504       mp->next_hop_via_label = ntohl (next_hop_via_label);
8505       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8506       if (0 != mp->next_hop_n_out_labels)
8507         {
8508           memcpy (mp->next_hop_out_label_stack,
8509                   next_hop_out_label_stack,
8510                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8511           vec_free (next_hop_out_label_stack);
8512         }
8513
8514       if (is_ipv6)
8515         {
8516           clib_memcpy (mp->dst_address, &v6_dst_address,
8517                        sizeof (v6_dst_address));
8518           if (next_hop_set)
8519             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8520                          sizeof (v6_next_hop_address));
8521           increment_v6_address (&v6_dst_address);
8522         }
8523       else
8524         {
8525           clib_memcpy (mp->dst_address, &v4_dst_address,
8526                        sizeof (v4_dst_address));
8527           if (next_hop_set)
8528             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8529                          sizeof (v4_next_hop_address));
8530           if (random_add_del)
8531             v4_dst_address.as_u32 = random_vector[j + 1];
8532           else
8533             increment_v4_address (&v4_dst_address);
8534         }
8535       /* send it... */
8536       S (mp);
8537       /* If we receive SIGTERM, stop now... */
8538       if (vam->do_exit)
8539         break;
8540     }
8541
8542   /* When testing multiple add/del ops, use a control-ping to sync */
8543   if (count > 1)
8544     {
8545       vl_api_control_ping_t *mp_ping;
8546       f64 after;
8547       f64 timeout;
8548
8549       /* Shut off async mode */
8550       vam->async_mode = 0;
8551
8552       MPING (CONTROL_PING, mp_ping);
8553       S (mp_ping);
8554
8555       timeout = vat_time_now (vam) + 1.0;
8556       while (vat_time_now (vam) < timeout)
8557         if (vam->result_ready == 1)
8558           goto out;
8559       vam->retval = -99;
8560
8561     out:
8562       if (vam->retval == -99)
8563         errmsg ("timeout");
8564
8565       if (vam->async_errors > 0)
8566         {
8567           errmsg ("%d asynchronous errors", vam->async_errors);
8568           vam->retval = -98;
8569         }
8570       vam->async_errors = 0;
8571       after = vat_time_now (vam);
8572
8573       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8574       if (j > 0)
8575         count = j;
8576
8577       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8578              count, after - before, count / (after - before));
8579     }
8580   else
8581     {
8582       int ret;
8583
8584       /* Wait for a reply... */
8585       W (ret);
8586       return ret;
8587     }
8588
8589   /* Return the good/bad news */
8590   return (vam->retval);
8591 }
8592
8593 static int
8594 api_ip_mroute_add_del (vat_main_t * vam)
8595 {
8596   unformat_input_t *i = vam->input;
8597   vl_api_ip_mroute_add_del_t *mp;
8598   u32 sw_if_index = ~0, vrf_id = 0;
8599   u8 is_ipv6 = 0;
8600   u8 is_local = 0;
8601   u8 is_add = 1;
8602   u8 address_set = 0;
8603   u32 grp_address_length = 0;
8604   ip4_address_t v4_grp_address, v4_src_address;
8605   ip6_address_t v6_grp_address, v6_src_address;
8606   mfib_itf_flags_t iflags = 0;
8607   mfib_entry_flags_t eflags = 0;
8608   int ret;
8609
8610   /* Parse args required to build the message */
8611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8612     {
8613       if (unformat (i, "sw_if_index %d", &sw_if_index))
8614         ;
8615       else if (unformat (i, "%U %U",
8616                          unformat_ip4_address, &v4_src_address,
8617                          unformat_ip4_address, &v4_grp_address))
8618         {
8619           grp_address_length = 64;
8620           address_set = 1;
8621           is_ipv6 = 0;
8622         }
8623       else if (unformat (i, "%U %U",
8624                          unformat_ip6_address, &v6_src_address,
8625                          unformat_ip6_address, &v6_grp_address))
8626         {
8627           grp_address_length = 256;
8628           address_set = 1;
8629           is_ipv6 = 1;
8630         }
8631       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8632         {
8633           memset (&v4_src_address, 0, sizeof (v4_src_address));
8634           grp_address_length = 32;
8635           address_set = 1;
8636           is_ipv6 = 0;
8637         }
8638       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8639         {
8640           memset (&v6_src_address, 0, sizeof (v6_src_address));
8641           grp_address_length = 128;
8642           address_set = 1;
8643           is_ipv6 = 1;
8644         }
8645       else if (unformat (i, "/%d", &grp_address_length))
8646         ;
8647       else if (unformat (i, "local"))
8648         {
8649           is_local = 1;
8650         }
8651       else if (unformat (i, "del"))
8652         is_add = 0;
8653       else if (unformat (i, "add"))
8654         is_add = 1;
8655       else if (unformat (i, "vrf %d", &vrf_id))
8656         ;
8657       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8658         ;
8659       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8660         ;
8661       else
8662         {
8663           clib_warning ("parse error '%U'", format_unformat_error, i);
8664           return -99;
8665         }
8666     }
8667
8668   if (address_set == 0)
8669     {
8670       errmsg ("missing addresses\n");
8671       return -99;
8672     }
8673
8674   /* Construct the API message */
8675   M (IP_MROUTE_ADD_DEL, mp);
8676
8677   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8678   mp->table_id = ntohl (vrf_id);
8679
8680   mp->is_add = is_add;
8681   mp->is_ipv6 = is_ipv6;
8682   mp->is_local = is_local;
8683   mp->itf_flags = ntohl (iflags);
8684   mp->entry_flags = ntohl (eflags);
8685   mp->grp_address_length = grp_address_length;
8686   mp->grp_address_length = ntohs (mp->grp_address_length);
8687
8688   if (is_ipv6)
8689     {
8690       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8691       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8692     }
8693   else
8694     {
8695       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8696       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8697
8698     }
8699
8700   /* send it... */
8701   S (mp);
8702   /* Wait for a reply... */
8703   W (ret);
8704   return ret;
8705 }
8706
8707 static int
8708 api_mpls_table_add_del (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_mpls_table_add_del_t *mp;
8712   u32 table_id = ~0;
8713   u8 is_add = 1;
8714   int ret = 0;
8715
8716   /* Parse args required to build the message */
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "table %d", &table_id))
8720         ;
8721       else if (unformat (i, "del"))
8722         is_add = 0;
8723       else if (unformat (i, "add"))
8724         is_add = 1;
8725       else
8726         {
8727           clib_warning ("parse error '%U'", format_unformat_error, i);
8728           return -99;
8729         }
8730     }
8731
8732   if (~0 == table_id)
8733     {
8734       errmsg ("missing table-ID");
8735       return -99;
8736     }
8737
8738   /* Construct the API message */
8739   M (MPLS_TABLE_ADD_DEL, mp);
8740
8741   mp->mt_table_id = ntohl (table_id);
8742   mp->mt_is_add = is_add;
8743
8744   /* send it... */
8745   S (mp);
8746
8747   /* Wait for a reply... */
8748   W (ret);
8749
8750   return ret;
8751 }
8752
8753 static int
8754 api_mpls_route_add_del (vat_main_t * vam)
8755 {
8756   unformat_input_t *i = vam->input;
8757   vl_api_mpls_route_add_del_t *mp;
8758   u32 sw_if_index = ~0, table_id = 0;
8759   u8 is_add = 1;
8760   u32 next_hop_weight = 1;
8761   u8 is_multipath = 0;
8762   u32 next_hop_table_id = 0;
8763   u8 next_hop_set = 0;
8764   ip4_address_t v4_next_hop_address = {
8765     .as_u32 = 0,
8766   };
8767   ip6_address_t v6_next_hop_address = { {0} };
8768   int count = 1;
8769   int j;
8770   f64 before = 0;
8771   u32 classify_table_index = ~0;
8772   u8 is_classify = 0;
8773   u8 resolve_host = 0, resolve_attached = 0;
8774   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8775   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8776   mpls_label_t *next_hop_out_label_stack = NULL;
8777   mpls_label_t local_label = MPLS_LABEL_INVALID;
8778   u8 is_eos = 0;
8779   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8780
8781   /* Parse args required to build the message */
8782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8783     {
8784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8785         ;
8786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8787         ;
8788       else if (unformat (i, "%d", &local_label))
8789         ;
8790       else if (unformat (i, "eos"))
8791         is_eos = 1;
8792       else if (unformat (i, "non-eos"))
8793         is_eos = 0;
8794       else if (unformat (i, "via %U", unformat_ip4_address,
8795                          &v4_next_hop_address))
8796         {
8797           next_hop_set = 1;
8798           next_hop_proto = DPO_PROTO_IP4;
8799         }
8800       else if (unformat (i, "via %U", unformat_ip6_address,
8801                          &v6_next_hop_address))
8802         {
8803           next_hop_set = 1;
8804           next_hop_proto = DPO_PROTO_IP6;
8805         }
8806       else if (unformat (i, "weight %d", &next_hop_weight))
8807         ;
8808       else if (unformat (i, "classify %d", &classify_table_index))
8809         {
8810           is_classify = 1;
8811         }
8812       else if (unformat (i, "del"))
8813         is_add = 0;
8814       else if (unformat (i, "add"))
8815         is_add = 1;
8816       else if (unformat (i, "resolve-via-host"))
8817         resolve_host = 1;
8818       else if (unformat (i, "resolve-via-attached"))
8819         resolve_attached = 1;
8820       else if (unformat (i, "multipath"))
8821         is_multipath = 1;
8822       else if (unformat (i, "count %d", &count))
8823         ;
8824       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8825         {
8826           next_hop_set = 1;
8827           next_hop_proto = DPO_PROTO_IP4;
8828         }
8829       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8830         {
8831           next_hop_set = 1;
8832           next_hop_proto = DPO_PROTO_IP6;
8833         }
8834       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8835         ;
8836       else if (unformat (i, "via-label %d", &next_hop_via_label))
8837         ;
8838       else if (unformat (i, "out-label %d", &next_hop_out_label))
8839         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (!next_hop_set && !is_classify)
8848     {
8849       errmsg ("next hop / classify not set");
8850       return -99;
8851     }
8852
8853   if (MPLS_LABEL_INVALID == local_label)
8854     {
8855       errmsg ("missing label");
8856       return -99;
8857     }
8858
8859   if (count > 1)
8860     {
8861       /* Turn on async mode */
8862       vam->async_mode = 1;
8863       vam->async_errors = 0;
8864       before = vat_time_now (vam);
8865     }
8866
8867   for (j = 0; j < count; j++)
8868     {
8869       /* Construct the API message */
8870       M2 (MPLS_ROUTE_ADD_DEL, mp,
8871           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8872
8873       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8874       mp->mr_table_id = ntohl (table_id);
8875
8876       mp->mr_is_add = is_add;
8877       mp->mr_next_hop_proto = next_hop_proto;
8878       mp->mr_is_classify = is_classify;
8879       mp->mr_is_multipath = is_multipath;
8880       mp->mr_is_resolve_host = resolve_host;
8881       mp->mr_is_resolve_attached = resolve_attached;
8882       mp->mr_next_hop_weight = next_hop_weight;
8883       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8884       mp->mr_classify_table_index = ntohl (classify_table_index);
8885       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8886       mp->mr_label = ntohl (local_label);
8887       mp->mr_eos = is_eos;
8888
8889       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8890       if (0 != mp->mr_next_hop_n_out_labels)
8891         {
8892           memcpy (mp->mr_next_hop_out_label_stack,
8893                   next_hop_out_label_stack,
8894                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8895           vec_free (next_hop_out_label_stack);
8896         }
8897
8898       if (next_hop_set)
8899         {
8900           if (DPO_PROTO_IP4 == next_hop_proto)
8901             {
8902               clib_memcpy (mp->mr_next_hop,
8903                            &v4_next_hop_address,
8904                            sizeof (v4_next_hop_address));
8905             }
8906           else if (DPO_PROTO_IP6 == next_hop_proto)
8907
8908             {
8909               clib_memcpy (mp->mr_next_hop,
8910                            &v6_next_hop_address,
8911                            sizeof (v6_next_hop_address));
8912             }
8913         }
8914       local_label++;
8915
8916       /* send it... */
8917       S (mp);
8918       /* If we receive SIGTERM, stop now... */
8919       if (vam->do_exit)
8920         break;
8921     }
8922
8923   /* When testing multiple add/del ops, use a control-ping to sync */
8924   if (count > 1)
8925     {
8926       vl_api_control_ping_t *mp_ping;
8927       f64 after;
8928       f64 timeout;
8929
8930       /* Shut off async mode */
8931       vam->async_mode = 0;
8932
8933       MPING (CONTROL_PING, mp_ping);
8934       S (mp_ping);
8935
8936       timeout = vat_time_now (vam) + 1.0;
8937       while (vat_time_now (vam) < timeout)
8938         if (vam->result_ready == 1)
8939           goto out;
8940       vam->retval = -99;
8941
8942     out:
8943       if (vam->retval == -99)
8944         errmsg ("timeout");
8945
8946       if (vam->async_errors > 0)
8947         {
8948           errmsg ("%d asynchronous errors", vam->async_errors);
8949           vam->retval = -98;
8950         }
8951       vam->async_errors = 0;
8952       after = vat_time_now (vam);
8953
8954       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8955       if (j > 0)
8956         count = j;
8957
8958       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8959              count, after - before, count / (after - before));
8960     }
8961   else
8962     {
8963       int ret;
8964
8965       /* Wait for a reply... */
8966       W (ret);
8967       return ret;
8968     }
8969
8970   /* Return the good/bad news */
8971   return (vam->retval);
8972 }
8973
8974 static int
8975 api_mpls_ip_bind_unbind (vat_main_t * vam)
8976 {
8977   unformat_input_t *i = vam->input;
8978   vl_api_mpls_ip_bind_unbind_t *mp;
8979   u32 ip_table_id = 0;
8980   u8 is_bind = 1;
8981   u8 is_ip4 = 1;
8982   ip4_address_t v4_address;
8983   ip6_address_t v6_address;
8984   u32 address_length;
8985   u8 address_set = 0;
8986   mpls_label_t local_label = MPLS_LABEL_INVALID;
8987   int ret;
8988
8989   /* Parse args required to build the message */
8990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (i, "%U/%d", unformat_ip4_address,
8993                     &v4_address, &address_length))
8994         {
8995           is_ip4 = 1;
8996           address_set = 1;
8997         }
8998       else if (unformat (i, "%U/%d", unformat_ip6_address,
8999                          &v6_address, &address_length))
9000         {
9001           is_ip4 = 0;
9002           address_set = 1;
9003         }
9004       else if (unformat (i, "%d", &local_label))
9005         ;
9006       else if (unformat (i, "table-id %d", &ip_table_id))
9007         ;
9008       else if (unformat (i, "unbind"))
9009         is_bind = 0;
9010       else if (unformat (i, "bind"))
9011         is_bind = 1;
9012       else
9013         {
9014           clib_warning ("parse error '%U'", format_unformat_error, i);
9015           return -99;
9016         }
9017     }
9018
9019   if (!address_set)
9020     {
9021       errmsg ("IP addres not set");
9022       return -99;
9023     }
9024
9025   if (MPLS_LABEL_INVALID == local_label)
9026     {
9027       errmsg ("missing label");
9028       return -99;
9029     }
9030
9031   /* Construct the API message */
9032   M (MPLS_IP_BIND_UNBIND, mp);
9033
9034   mp->mb_is_bind = is_bind;
9035   mp->mb_is_ip4 = is_ip4;
9036   mp->mb_ip_table_id = ntohl (ip_table_id);
9037   mp->mb_mpls_table_id = 0;
9038   mp->mb_label = ntohl (local_label);
9039   mp->mb_address_length = address_length;
9040
9041   if (is_ip4)
9042     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9043   else
9044     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9045
9046   /* send it... */
9047   S (mp);
9048
9049   /* Wait for a reply... */
9050   W (ret);
9051   return ret;
9052 }
9053
9054 static int
9055 api_bier_table_add_del (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_bier_table_add_del_t *mp;
9059   u8 is_add = 1;
9060   u32 set = 0, sub_domain = 0, hdr_len = 3;
9061   mpls_label_t local_label = MPLS_LABEL_INVALID;
9062   int ret;
9063
9064   /* Parse args required to build the message */
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "sub-domain %d", &sub_domain))
9068         ;
9069       else if (unformat (i, "set %d", &set))
9070         ;
9071       else if (unformat (i, "label %d", &local_label))
9072         ;
9073       else if (unformat (i, "hdr-len %d", &hdr_len))
9074         ;
9075       else if (unformat (i, "add"))
9076         is_add = 1;
9077       else if (unformat (i, "del"))
9078         is_add = 0;
9079       else
9080         {
9081           clib_warning ("parse error '%U'", format_unformat_error, i);
9082           return -99;
9083         }
9084     }
9085
9086   if (MPLS_LABEL_INVALID == local_label)
9087     {
9088       errmsg ("missing label\n");
9089       return -99;
9090     }
9091
9092   /* Construct the API message */
9093   M (BIER_TABLE_ADD_DEL, mp);
9094
9095   mp->bt_is_add = is_add;
9096   mp->bt_label = ntohl (local_label);
9097   mp->bt_tbl_id.bt_set = set;
9098   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9099   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9100
9101   /* send it... */
9102   S (mp);
9103
9104   /* Wait for a reply... */
9105   W (ret);
9106
9107   return (ret);
9108 }
9109
9110 static int
9111 api_bier_route_add_del (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_bier_route_add_del_t *mp;
9115   u8 is_add = 1;
9116   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9117   ip4_address_t v4_next_hop_address;
9118   ip6_address_t v6_next_hop_address;
9119   u8 next_hop_set = 0;
9120   u8 next_hop_proto_is_ip4 = 1;
9121   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9122   int ret;
9123
9124   /* Parse args required to build the message */
9125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9126     {
9127       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9128         {
9129           next_hop_proto_is_ip4 = 1;
9130           next_hop_set = 1;
9131         }
9132       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9133         {
9134           next_hop_proto_is_ip4 = 0;
9135           next_hop_set = 1;
9136         }
9137       if (unformat (i, "sub-domain %d", &sub_domain))
9138         ;
9139       else if (unformat (i, "set %d", &set))
9140         ;
9141       else if (unformat (i, "hdr-len %d", &hdr_len))
9142         ;
9143       else if (unformat (i, "bp %d", &bp))
9144         ;
9145       else if (unformat (i, "add"))
9146         is_add = 1;
9147       else if (unformat (i, "del"))
9148         is_add = 0;
9149       else if (unformat (i, "out-label %d", &next_hop_out_label))
9150         ;
9151       else
9152         {
9153           clib_warning ("parse error '%U'", format_unformat_error, i);
9154           return -99;
9155         }
9156     }
9157
9158   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9159     {
9160       errmsg ("next hop / label set\n");
9161       return -99;
9162     }
9163   if (0 == bp)
9164     {
9165       errmsg ("bit=position not set\n");
9166       return -99;
9167     }
9168
9169   /* Construct the API message */
9170   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9171
9172   mp->br_is_add = is_add;
9173   mp->br_tbl_id.bt_set = set;
9174   mp->br_tbl_id.bt_sub_domain = sub_domain;
9175   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9176   mp->br_bp = ntohs (bp);
9177   mp->br_n_paths = 1;
9178   mp->br_paths[0].n_labels = 1;
9179   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9180   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9181
9182   if (next_hop_proto_is_ip4)
9183     {
9184       clib_memcpy (mp->br_paths[0].next_hop,
9185                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9186     }
9187   else
9188     {
9189       clib_memcpy (mp->br_paths[0].next_hop,
9190                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9191     }
9192
9193   /* send it... */
9194   S (mp);
9195
9196   /* Wait for a reply... */
9197   W (ret);
9198
9199   return (ret);
9200 }
9201
9202 static int
9203 api_proxy_arp_add_del (vat_main_t * vam)
9204 {
9205   unformat_input_t *i = vam->input;
9206   vl_api_proxy_arp_add_del_t *mp;
9207   u32 vrf_id = 0;
9208   u8 is_add = 1;
9209   ip4_address_t lo, hi;
9210   u8 range_set = 0;
9211   int ret;
9212
9213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (i, "vrf %d", &vrf_id))
9216         ;
9217       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9218                          unformat_ip4_address, &hi))
9219         range_set = 1;
9220       else if (unformat (i, "del"))
9221         is_add = 0;
9222       else
9223         {
9224           clib_warning ("parse error '%U'", format_unformat_error, i);
9225           return -99;
9226         }
9227     }
9228
9229   if (range_set == 0)
9230     {
9231       errmsg ("address range not set");
9232       return -99;
9233     }
9234
9235   M (PROXY_ARP_ADD_DEL, mp);
9236
9237   mp->proxy.vrf_id = ntohl (vrf_id);
9238   mp->is_add = is_add;
9239   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9240   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247 static int
9248 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9249 {
9250   unformat_input_t *i = vam->input;
9251   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9252   u32 sw_if_index;
9253   u8 enable = 1;
9254   u8 sw_if_index_set = 0;
9255   int ret;
9256
9257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9258     {
9259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9260         sw_if_index_set = 1;
9261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9262         sw_if_index_set = 1;
9263       else if (unformat (i, "enable"))
9264         enable = 1;
9265       else if (unformat (i, "disable"))
9266         enable = 0;
9267       else
9268         {
9269           clib_warning ("parse error '%U'", format_unformat_error, i);
9270           return -99;
9271         }
9272     }
9273
9274   if (sw_if_index_set == 0)
9275     {
9276       errmsg ("missing interface name or sw_if_index");
9277       return -99;
9278     }
9279
9280   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9281
9282   mp->sw_if_index = ntohl (sw_if_index);
9283   mp->enable_disable = enable;
9284
9285   S (mp);
9286   W (ret);
9287   return ret;
9288 }
9289
9290 static int
9291 api_mpls_tunnel_add_del (vat_main_t * vam)
9292 {
9293   unformat_input_t *i = vam->input;
9294   vl_api_mpls_tunnel_add_del_t *mp;
9295
9296   u8 is_add = 1;
9297   u8 l2_only = 0;
9298   u32 sw_if_index = ~0;
9299   u32 next_hop_sw_if_index = ~0;
9300   u32 next_hop_proto_is_ip4 = 1;
9301
9302   u32 next_hop_table_id = 0;
9303   ip4_address_t v4_next_hop_address = {
9304     .as_u32 = 0,
9305   };
9306   ip6_address_t v6_next_hop_address = { {0} };
9307   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9308   int ret;
9309
9310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (i, "add"))
9313         is_add = 1;
9314       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9315         is_add = 0;
9316       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9317         ;
9318       else if (unformat (i, "via %U",
9319                          unformat_ip4_address, &v4_next_hop_address))
9320         {
9321           next_hop_proto_is_ip4 = 1;
9322         }
9323       else if (unformat (i, "via %U",
9324                          unformat_ip6_address, &v6_next_hop_address))
9325         {
9326           next_hop_proto_is_ip4 = 0;
9327         }
9328       else if (unformat (i, "l2-only"))
9329         l2_only = 1;
9330       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9331         ;
9332       else if (unformat (i, "out-label %d", &next_hop_out_label))
9333         vec_add1 (labels, ntohl (next_hop_out_label));
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9342
9343   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9344   mp->mt_sw_if_index = ntohl (sw_if_index);
9345   mp->mt_is_add = is_add;
9346   mp->mt_l2_only = l2_only;
9347   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9348   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9349
9350   mp->mt_next_hop_n_out_labels = vec_len (labels);
9351
9352   if (0 != mp->mt_next_hop_n_out_labels)
9353     {
9354       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9355                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9356       vec_free (labels);
9357     }
9358
9359   if (next_hop_proto_is_ip4)
9360     {
9361       clib_memcpy (mp->mt_next_hop,
9362                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9363     }
9364   else
9365     {
9366       clib_memcpy (mp->mt_next_hop,
9367                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9368     }
9369
9370   S (mp);
9371   W (ret);
9372   return ret;
9373 }
9374
9375 static int
9376 api_sw_interface_set_unnumbered (vat_main_t * vam)
9377 {
9378   unformat_input_t *i = vam->input;
9379   vl_api_sw_interface_set_unnumbered_t *mp;
9380   u32 sw_if_index;
9381   u32 unnum_sw_index = ~0;
9382   u8 is_add = 1;
9383   u8 sw_if_index_set = 0;
9384   int ret;
9385
9386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9391         sw_if_index_set = 1;
9392       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9393         ;
9394       else if (unformat (i, "del"))
9395         is_add = 0;
9396       else
9397         {
9398           clib_warning ("parse error '%U'", format_unformat_error, i);
9399           return -99;
9400         }
9401     }
9402
9403   if (sw_if_index_set == 0)
9404     {
9405       errmsg ("missing interface name or sw_if_index");
9406       return -99;
9407     }
9408
9409   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9410
9411   mp->sw_if_index = ntohl (sw_if_index);
9412   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9413   mp->is_add = is_add;
9414
9415   S (mp);
9416   W (ret);
9417   return ret;
9418 }
9419
9420 static int
9421 api_ip_neighbor_add_del (vat_main_t * vam)
9422 {
9423   unformat_input_t *i = vam->input;
9424   vl_api_ip_neighbor_add_del_t *mp;
9425   u32 sw_if_index;
9426   u8 sw_if_index_set = 0;
9427   u8 is_add = 1;
9428   u8 is_static = 0;
9429   u8 is_no_fib_entry = 0;
9430   u8 mac_address[6];
9431   u8 mac_set = 0;
9432   u8 v4_address_set = 0;
9433   u8 v6_address_set = 0;
9434   ip4_address_t v4address;
9435   ip6_address_t v6address;
9436   int ret;
9437
9438   memset (mac_address, 0, sizeof (mac_address));
9439
9440   /* Parse args required to build the message */
9441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9442     {
9443       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9444         {
9445           mac_set = 1;
9446         }
9447       else if (unformat (i, "del"))
9448         is_add = 0;
9449       else
9450         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9451         sw_if_index_set = 1;
9452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9453         sw_if_index_set = 1;
9454       else if (unformat (i, "is_static"))
9455         is_static = 1;
9456       else if (unformat (i, "no-fib-entry"))
9457         is_no_fib_entry = 1;
9458       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9459         v4_address_set = 1;
9460       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9461         v6_address_set = 1;
9462       else
9463         {
9464           clib_warning ("parse error '%U'", format_unformat_error, i);
9465           return -99;
9466         }
9467     }
9468
9469   if (sw_if_index_set == 0)
9470     {
9471       errmsg ("missing interface name or sw_if_index");
9472       return -99;
9473     }
9474   if (v4_address_set && v6_address_set)
9475     {
9476       errmsg ("both v4 and v6 addresses set");
9477       return -99;
9478     }
9479   if (!v4_address_set && !v6_address_set)
9480     {
9481       errmsg ("no address set");
9482       return -99;
9483     }
9484
9485   /* Construct the API message */
9486   M (IP_NEIGHBOR_ADD_DEL, mp);
9487
9488   mp->sw_if_index = ntohl (sw_if_index);
9489   mp->is_add = is_add;
9490   mp->is_static = is_static;
9491   mp->is_no_adj_fib = is_no_fib_entry;
9492   if (mac_set)
9493     clib_memcpy (mp->mac_address, mac_address, 6);
9494   if (v6_address_set)
9495     {
9496       mp->is_ipv6 = 1;
9497       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9498     }
9499   else
9500     {
9501       /* mp->is_ipv6 = 0; via memset in M macro above */
9502       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9503     }
9504
9505   /* send it... */
9506   S (mp);
9507
9508   /* Wait for a reply, return good/bad news  */
9509   W (ret);
9510   return ret;
9511 }
9512
9513 static int
9514 api_create_vlan_subif (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_create_vlan_subif_t *mp;
9518   u32 sw_if_index;
9519   u8 sw_if_index_set = 0;
9520   u32 vlan_id;
9521   u8 vlan_id_set = 0;
9522   int ret;
9523
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "sw_if_index %d", &sw_if_index))
9527         sw_if_index_set = 1;
9528       else
9529         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9530         sw_if_index_set = 1;
9531       else if (unformat (i, "vlan %d", &vlan_id))
9532         vlan_id_set = 1;
9533       else
9534         {
9535           clib_warning ("parse error '%U'", format_unformat_error, i);
9536           return -99;
9537         }
9538     }
9539
9540   if (sw_if_index_set == 0)
9541     {
9542       errmsg ("missing interface name or sw_if_index");
9543       return -99;
9544     }
9545
9546   if (vlan_id_set == 0)
9547     {
9548       errmsg ("missing vlan_id");
9549       return -99;
9550     }
9551   M (CREATE_VLAN_SUBIF, mp);
9552
9553   mp->sw_if_index = ntohl (sw_if_index);
9554   mp->vlan_id = ntohl (vlan_id);
9555
9556   S (mp);
9557   W (ret);
9558   return ret;
9559 }
9560
9561 #define foreach_create_subif_bit                \
9562 _(no_tags)                                      \
9563 _(one_tag)                                      \
9564 _(two_tags)                                     \
9565 _(dot1ad)                                       \
9566 _(exact_match)                                  \
9567 _(default_sub)                                  \
9568 _(outer_vlan_id_any)                            \
9569 _(inner_vlan_id_any)
9570
9571 static int
9572 api_create_subif (vat_main_t * vam)
9573 {
9574   unformat_input_t *i = vam->input;
9575   vl_api_create_subif_t *mp;
9576   u32 sw_if_index;
9577   u8 sw_if_index_set = 0;
9578   u32 sub_id;
9579   u8 sub_id_set = 0;
9580   u32 no_tags = 0;
9581   u32 one_tag = 0;
9582   u32 two_tags = 0;
9583   u32 dot1ad = 0;
9584   u32 exact_match = 0;
9585   u32 default_sub = 0;
9586   u32 outer_vlan_id_any = 0;
9587   u32 inner_vlan_id_any = 0;
9588   u32 tmp;
9589   u16 outer_vlan_id = 0;
9590   u16 inner_vlan_id = 0;
9591   int ret;
9592
9593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9594     {
9595       if (unformat (i, "sw_if_index %d", &sw_if_index))
9596         sw_if_index_set = 1;
9597       else
9598         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9599         sw_if_index_set = 1;
9600       else if (unformat (i, "sub_id %d", &sub_id))
9601         sub_id_set = 1;
9602       else if (unformat (i, "outer_vlan_id %d", &tmp))
9603         outer_vlan_id = tmp;
9604       else if (unformat (i, "inner_vlan_id %d", &tmp))
9605         inner_vlan_id = tmp;
9606
9607 #define _(a) else if (unformat (i, #a)) a = 1 ;
9608       foreach_create_subif_bit
9609 #undef _
9610         else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (sw_if_index_set == 0)
9618     {
9619       errmsg ("missing interface name or sw_if_index");
9620       return -99;
9621     }
9622
9623   if (sub_id_set == 0)
9624     {
9625       errmsg ("missing sub_id");
9626       return -99;
9627     }
9628   M (CREATE_SUBIF, mp);
9629
9630   mp->sw_if_index = ntohl (sw_if_index);
9631   mp->sub_id = ntohl (sub_id);
9632
9633 #define _(a) mp->a = a;
9634   foreach_create_subif_bit;
9635 #undef _
9636
9637   mp->outer_vlan_id = ntohs (outer_vlan_id);
9638   mp->inner_vlan_id = ntohs (inner_vlan_id);
9639
9640   S (mp);
9641   W (ret);
9642   return ret;
9643 }
9644
9645 static int
9646 api_oam_add_del (vat_main_t * vam)
9647 {
9648   unformat_input_t *i = vam->input;
9649   vl_api_oam_add_del_t *mp;
9650   u32 vrf_id = 0;
9651   u8 is_add = 1;
9652   ip4_address_t src, dst;
9653   u8 src_set = 0;
9654   u8 dst_set = 0;
9655   int ret;
9656
9657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9658     {
9659       if (unformat (i, "vrf %d", &vrf_id))
9660         ;
9661       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9662         src_set = 1;
9663       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9664         dst_set = 1;
9665       else if (unformat (i, "del"))
9666         is_add = 0;
9667       else
9668         {
9669           clib_warning ("parse error '%U'", format_unformat_error, i);
9670           return -99;
9671         }
9672     }
9673
9674   if (src_set == 0)
9675     {
9676       errmsg ("missing src addr");
9677       return -99;
9678     }
9679
9680   if (dst_set == 0)
9681     {
9682       errmsg ("missing dst addr");
9683       return -99;
9684     }
9685
9686   M (OAM_ADD_DEL, mp);
9687
9688   mp->vrf_id = ntohl (vrf_id);
9689   mp->is_add = is_add;
9690   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9691   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9692
9693   S (mp);
9694   W (ret);
9695   return ret;
9696 }
9697
9698 static int
9699 api_reset_fib (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_reset_fib_t *mp;
9703   u32 vrf_id = 0;
9704   u8 is_ipv6 = 0;
9705   u8 vrf_id_set = 0;
9706
9707   int ret;
9708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9709     {
9710       if (unformat (i, "vrf %d", &vrf_id))
9711         vrf_id_set = 1;
9712       else if (unformat (i, "ipv6"))
9713         is_ipv6 = 1;
9714       else
9715         {
9716           clib_warning ("parse error '%U'", format_unformat_error, i);
9717           return -99;
9718         }
9719     }
9720
9721   if (vrf_id_set == 0)
9722     {
9723       errmsg ("missing vrf id");
9724       return -99;
9725     }
9726
9727   M (RESET_FIB, mp);
9728
9729   mp->vrf_id = ntohl (vrf_id);
9730   mp->is_ipv6 = is_ipv6;
9731
9732   S (mp);
9733   W (ret);
9734   return ret;
9735 }
9736
9737 static int
9738 api_dhcp_proxy_config (vat_main_t * vam)
9739 {
9740   unformat_input_t *i = vam->input;
9741   vl_api_dhcp_proxy_config_t *mp;
9742   u32 rx_vrf_id = 0;
9743   u32 server_vrf_id = 0;
9744   u8 is_add = 1;
9745   u8 v4_address_set = 0;
9746   u8 v6_address_set = 0;
9747   ip4_address_t v4address;
9748   ip6_address_t v6address;
9749   u8 v4_src_address_set = 0;
9750   u8 v6_src_address_set = 0;
9751   ip4_address_t v4srcaddress;
9752   ip6_address_t v6srcaddress;
9753   int ret;
9754
9755   /* Parse args required to build the message */
9756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (i, "del"))
9759         is_add = 0;
9760       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9761         ;
9762       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9763         ;
9764       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9765         v4_address_set = 1;
9766       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9767         v6_address_set = 1;
9768       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9769         v4_src_address_set = 1;
9770       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9771         v6_src_address_set = 1;
9772       else
9773         break;
9774     }
9775
9776   if (v4_address_set && v6_address_set)
9777     {
9778       errmsg ("both v4 and v6 server addresses set");
9779       return -99;
9780     }
9781   if (!v4_address_set && !v6_address_set)
9782     {
9783       errmsg ("no server addresses set");
9784       return -99;
9785     }
9786
9787   if (v4_src_address_set && v6_src_address_set)
9788     {
9789       errmsg ("both v4 and v6  src addresses set");
9790       return -99;
9791     }
9792   if (!v4_src_address_set && !v6_src_address_set)
9793     {
9794       errmsg ("no src addresses set");
9795       return -99;
9796     }
9797
9798   if (!(v4_src_address_set && v4_address_set) &&
9799       !(v6_src_address_set && v6_address_set))
9800     {
9801       errmsg ("no matching server and src addresses set");
9802       return -99;
9803     }
9804
9805   /* Construct the API message */
9806   M (DHCP_PROXY_CONFIG, mp);
9807
9808   mp->is_add = is_add;
9809   mp->rx_vrf_id = ntohl (rx_vrf_id);
9810   mp->server_vrf_id = ntohl (server_vrf_id);
9811   if (v6_address_set)
9812     {
9813       mp->is_ipv6 = 1;
9814       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9815       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9816     }
9817   else
9818     {
9819       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9820       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9821     }
9822
9823   /* send it... */
9824   S (mp);
9825
9826   /* Wait for a reply, return good/bad news  */
9827   W (ret);
9828   return ret;
9829 }
9830
9831 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9832 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9833
9834 static void
9835 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9836 {
9837   vat_main_t *vam = &vat_main;
9838   u32 i, count = mp->count;
9839   vl_api_dhcp_server_t *s;
9840
9841   if (mp->is_ipv6)
9842     print (vam->ofp,
9843            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9844            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9845            ntohl (mp->rx_vrf_id),
9846            format_ip6_address, mp->dhcp_src_address,
9847            mp->vss_type, mp->vss_vpn_ascii_id,
9848            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9849   else
9850     print (vam->ofp,
9851            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9852            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9853            ntohl (mp->rx_vrf_id),
9854            format_ip4_address, mp->dhcp_src_address,
9855            mp->vss_type, mp->vss_vpn_ascii_id,
9856            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9857
9858   for (i = 0; i < count; i++)
9859     {
9860       s = &mp->servers[i];
9861
9862       if (mp->is_ipv6)
9863         print (vam->ofp,
9864                " Server Table-ID %d, Server Address %U",
9865                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9866       else
9867         print (vam->ofp,
9868                " Server Table-ID %d, Server Address %U",
9869                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9870     }
9871 }
9872
9873 static void vl_api_dhcp_proxy_details_t_handler_json
9874   (vl_api_dhcp_proxy_details_t * mp)
9875 {
9876   vat_main_t *vam = &vat_main;
9877   vat_json_node_t *node = NULL;
9878   u32 i, count = mp->count;
9879   struct in_addr ip4;
9880   struct in6_addr ip6;
9881   vl_api_dhcp_server_t *s;
9882
9883   if (VAT_JSON_ARRAY != vam->json_tree.type)
9884     {
9885       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9886       vat_json_init_array (&vam->json_tree);
9887     }
9888   node = vat_json_array_add (&vam->json_tree);
9889
9890   vat_json_init_object (node);
9891   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9892   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9893                              sizeof (mp->vss_type));
9894   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9895                                    mp->vss_vpn_ascii_id);
9896   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9897   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9898
9899   if (mp->is_ipv6)
9900     {
9901       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9902       vat_json_object_add_ip6 (node, "src_address", ip6);
9903     }
9904   else
9905     {
9906       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9907       vat_json_object_add_ip4 (node, "src_address", ip4);
9908     }
9909
9910   for (i = 0; i < count; i++)
9911     {
9912       s = &mp->servers[i];
9913
9914       vat_json_object_add_uint (node, "server-table-id",
9915                                 ntohl (s->server_vrf_id));
9916
9917       if (mp->is_ipv6)
9918         {
9919           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9920           vat_json_object_add_ip4 (node, "src_address", ip4);
9921         }
9922       else
9923         {
9924           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9925           vat_json_object_add_ip6 (node, "server_address", ip6);
9926         }
9927     }
9928 }
9929
9930 static int
9931 api_dhcp_proxy_dump (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_control_ping_t *mp_ping;
9935   vl_api_dhcp_proxy_dump_t *mp;
9936   u8 is_ipv6 = 0;
9937   int ret;
9938
9939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9940     {
9941       if (unformat (i, "ipv6"))
9942         is_ipv6 = 1;
9943       else
9944         {
9945           clib_warning ("parse error '%U'", format_unformat_error, i);
9946           return -99;
9947         }
9948     }
9949
9950   M (DHCP_PROXY_DUMP, mp);
9951
9952   mp->is_ip6 = is_ipv6;
9953   S (mp);
9954
9955   /* Use a control ping for synchronization */
9956   MPING (CONTROL_PING, mp_ping);
9957   S (mp_ping);
9958
9959   W (ret);
9960   return ret;
9961 }
9962
9963 static int
9964 api_dhcp_proxy_set_vss (vat_main_t * vam)
9965 {
9966   unformat_input_t *i = vam->input;
9967   vl_api_dhcp_proxy_set_vss_t *mp;
9968   u8 is_ipv6 = 0;
9969   u8 is_add = 1;
9970   u32 tbl_id = ~0;
9971   u8 vss_type = VSS_TYPE_DEFAULT;
9972   u8 *vpn_ascii_id = 0;
9973   u32 oui = 0;
9974   u32 fib_id = 0;
9975   int ret;
9976
9977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9978     {
9979       if (unformat (i, "tbl_id %d", &tbl_id))
9980         ;
9981       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9982         vss_type = VSS_TYPE_ASCII;
9983       else if (unformat (i, "fib_id %d", &fib_id))
9984         vss_type = VSS_TYPE_VPN_ID;
9985       else if (unformat (i, "oui %d", &oui))
9986         vss_type = VSS_TYPE_VPN_ID;
9987       else if (unformat (i, "ipv6"))
9988         is_ipv6 = 1;
9989       else if (unformat (i, "del"))
9990         is_add = 0;
9991       else
9992         break;
9993     }
9994
9995   if (tbl_id == ~0)
9996     {
9997       errmsg ("missing tbl_id ");
9998       vec_free (vpn_ascii_id);
9999       return -99;
10000     }
10001
10002   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10003     {
10004       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10005       vec_free (vpn_ascii_id);
10006       return -99;
10007     }
10008
10009   M (DHCP_PROXY_SET_VSS, mp);
10010   mp->tbl_id = ntohl (tbl_id);
10011   mp->vss_type = vss_type;
10012   if (vpn_ascii_id)
10013     {
10014       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10015       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10016     }
10017   mp->vpn_index = ntohl (fib_id);
10018   mp->oui = ntohl (oui);
10019   mp->is_ipv6 = is_ipv6;
10020   mp->is_add = is_add;
10021
10022   S (mp);
10023   W (ret);
10024
10025   vec_free (vpn_ascii_id);
10026   return ret;
10027 }
10028
10029 static int
10030 api_dhcp_client_config (vat_main_t * vam)
10031 {
10032   unformat_input_t *i = vam->input;
10033   vl_api_dhcp_client_config_t *mp;
10034   u32 sw_if_index;
10035   u8 sw_if_index_set = 0;
10036   u8 is_add = 1;
10037   u8 *hostname = 0;
10038   u8 disable_event = 0;
10039   int ret;
10040
10041   /* Parse args required to build the message */
10042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10043     {
10044       if (unformat (i, "del"))
10045         is_add = 0;
10046       else
10047         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10048         sw_if_index_set = 1;
10049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10050         sw_if_index_set = 1;
10051       else if (unformat (i, "hostname %s", &hostname))
10052         ;
10053       else if (unformat (i, "disable_event"))
10054         disable_event = 1;
10055       else
10056         break;
10057     }
10058
10059   if (sw_if_index_set == 0)
10060     {
10061       errmsg ("missing interface name or sw_if_index");
10062       return -99;
10063     }
10064
10065   if (vec_len (hostname) > 63)
10066     {
10067       errmsg ("hostname too long");
10068     }
10069   vec_add1 (hostname, 0);
10070
10071   /* Construct the API message */
10072   M (DHCP_CLIENT_CONFIG, mp);
10073
10074   mp->is_add = is_add;
10075   mp->client.sw_if_index = htonl (sw_if_index);
10076   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10077   vec_free (hostname);
10078   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10079   mp->client.pid = htonl (getpid ());
10080
10081   /* send it... */
10082   S (mp);
10083
10084   /* Wait for a reply, return good/bad news  */
10085   W (ret);
10086   return ret;
10087 }
10088
10089 static int
10090 api_set_ip_flow_hash (vat_main_t * vam)
10091 {
10092   unformat_input_t *i = vam->input;
10093   vl_api_set_ip_flow_hash_t *mp;
10094   u32 vrf_id = 0;
10095   u8 is_ipv6 = 0;
10096   u8 vrf_id_set = 0;
10097   u8 src = 0;
10098   u8 dst = 0;
10099   u8 sport = 0;
10100   u8 dport = 0;
10101   u8 proto = 0;
10102   u8 reverse = 0;
10103   int ret;
10104
10105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (i, "vrf %d", &vrf_id))
10108         vrf_id_set = 1;
10109       else if (unformat (i, "ipv6"))
10110         is_ipv6 = 1;
10111       else if (unformat (i, "src"))
10112         src = 1;
10113       else if (unformat (i, "dst"))
10114         dst = 1;
10115       else if (unformat (i, "sport"))
10116         sport = 1;
10117       else if (unformat (i, "dport"))
10118         dport = 1;
10119       else if (unformat (i, "proto"))
10120         proto = 1;
10121       else if (unformat (i, "reverse"))
10122         reverse = 1;
10123
10124       else
10125         {
10126           clib_warning ("parse error '%U'", format_unformat_error, i);
10127           return -99;
10128         }
10129     }
10130
10131   if (vrf_id_set == 0)
10132     {
10133       errmsg ("missing vrf id");
10134       return -99;
10135     }
10136
10137   M (SET_IP_FLOW_HASH, mp);
10138   mp->src = src;
10139   mp->dst = dst;
10140   mp->sport = sport;
10141   mp->dport = dport;
10142   mp->proto = proto;
10143   mp->reverse = reverse;
10144   mp->vrf_id = ntohl (vrf_id);
10145   mp->is_ipv6 = is_ipv6;
10146
10147   S (mp);
10148   W (ret);
10149   return ret;
10150 }
10151
10152 static int
10153 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10154 {
10155   unformat_input_t *i = vam->input;
10156   vl_api_sw_interface_ip6_enable_disable_t *mp;
10157   u32 sw_if_index;
10158   u8 sw_if_index_set = 0;
10159   u8 enable = 0;
10160   int ret;
10161
10162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "enable"))
10169         enable = 1;
10170       else if (unformat (i, "disable"))
10171         enable = 0;
10172       else
10173         {
10174           clib_warning ("parse error '%U'", format_unformat_error, i);
10175           return -99;
10176         }
10177     }
10178
10179   if (sw_if_index_set == 0)
10180     {
10181       errmsg ("missing interface name or sw_if_index");
10182       return -99;
10183     }
10184
10185   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10186
10187   mp->sw_if_index = ntohl (sw_if_index);
10188   mp->enable = enable;
10189
10190   S (mp);
10191   W (ret);
10192   return ret;
10193 }
10194
10195 static int
10196 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10197 {
10198   unformat_input_t *i = vam->input;
10199   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10200   u32 sw_if_index;
10201   u8 sw_if_index_set = 0;
10202   u8 v6_address_set = 0;
10203   ip6_address_t v6address;
10204   int ret;
10205
10206   /* Parse args required to build the message */
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10210         sw_if_index_set = 1;
10211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10212         sw_if_index_set = 1;
10213       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10214         v6_address_set = 1;
10215       else
10216         break;
10217     }
10218
10219   if (sw_if_index_set == 0)
10220     {
10221       errmsg ("missing interface name or sw_if_index");
10222       return -99;
10223     }
10224   if (!v6_address_set)
10225     {
10226       errmsg ("no address set");
10227       return -99;
10228     }
10229
10230   /* Construct the API message */
10231   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10232
10233   mp->sw_if_index = ntohl (sw_if_index);
10234   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10235
10236   /* send it... */
10237   S (mp);
10238
10239   /* Wait for a reply, return good/bad news  */
10240   W (ret);
10241   return ret;
10242 }
10243
10244 static int
10245 api_ip6nd_proxy_add_del (vat_main_t * vam)
10246 {
10247   unformat_input_t *i = vam->input;
10248   vl_api_ip6nd_proxy_add_del_t *mp;
10249   u32 sw_if_index = ~0;
10250   u8 v6_address_set = 0;
10251   ip6_address_t v6address;
10252   u8 is_del = 0;
10253   int ret;
10254
10255   /* Parse args required to build the message */
10256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10257     {
10258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10259         ;
10260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10261         ;
10262       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10263         v6_address_set = 1;
10264       if (unformat (i, "del"))
10265         is_del = 1;
10266       else
10267         {
10268           clib_warning ("parse error '%U'", format_unformat_error, i);
10269           return -99;
10270         }
10271     }
10272
10273   if (sw_if_index == ~0)
10274     {
10275       errmsg ("missing interface name or sw_if_index");
10276       return -99;
10277     }
10278   if (!v6_address_set)
10279     {
10280       errmsg ("no address set");
10281       return -99;
10282     }
10283
10284   /* Construct the API message */
10285   M (IP6ND_PROXY_ADD_DEL, mp);
10286
10287   mp->is_del = is_del;
10288   mp->sw_if_index = ntohl (sw_if_index);
10289   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10290
10291   /* send it... */
10292   S (mp);
10293
10294   /* Wait for a reply, return good/bad news  */
10295   W (ret);
10296   return ret;
10297 }
10298
10299 static int
10300 api_ip6nd_proxy_dump (vat_main_t * vam)
10301 {
10302   vl_api_ip6nd_proxy_dump_t *mp;
10303   vl_api_control_ping_t *mp_ping;
10304   int ret;
10305
10306   M (IP6ND_PROXY_DUMP, mp);
10307
10308   S (mp);
10309
10310   /* Use a control ping for synchronization */
10311   MPING (CONTROL_PING, mp_ping);
10312   S (mp_ping);
10313
10314   W (ret);
10315   return ret;
10316 }
10317
10318 static void vl_api_ip6nd_proxy_details_t_handler
10319   (vl_api_ip6nd_proxy_details_t * mp)
10320 {
10321   vat_main_t *vam = &vat_main;
10322
10323   print (vam->ofp, "host %U sw_if_index %d",
10324          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10325 }
10326
10327 static void vl_api_ip6nd_proxy_details_t_handler_json
10328   (vl_api_ip6nd_proxy_details_t * mp)
10329 {
10330   vat_main_t *vam = &vat_main;
10331   struct in6_addr ip6;
10332   vat_json_node_t *node = NULL;
10333
10334   if (VAT_JSON_ARRAY != vam->json_tree.type)
10335     {
10336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10337       vat_json_init_array (&vam->json_tree);
10338     }
10339   node = vat_json_array_add (&vam->json_tree);
10340
10341   vat_json_init_object (node);
10342   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10343
10344   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10345   vat_json_object_add_ip6 (node, "host", ip6);
10346 }
10347
10348 static int
10349 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10350 {
10351   unformat_input_t *i = vam->input;
10352   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10353   u32 sw_if_index;
10354   u8 sw_if_index_set = 0;
10355   u32 address_length = 0;
10356   u8 v6_address_set = 0;
10357   ip6_address_t v6address;
10358   u8 use_default = 0;
10359   u8 no_advertise = 0;
10360   u8 off_link = 0;
10361   u8 no_autoconfig = 0;
10362   u8 no_onlink = 0;
10363   u8 is_no = 0;
10364   u32 val_lifetime = 0;
10365   u32 pref_lifetime = 0;
10366   int ret;
10367
10368   /* Parse args required to build the message */
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10372         sw_if_index_set = 1;
10373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10374         sw_if_index_set = 1;
10375       else if (unformat (i, "%U/%d",
10376                          unformat_ip6_address, &v6address, &address_length))
10377         v6_address_set = 1;
10378       else if (unformat (i, "val_life %d", &val_lifetime))
10379         ;
10380       else if (unformat (i, "pref_life %d", &pref_lifetime))
10381         ;
10382       else if (unformat (i, "def"))
10383         use_default = 1;
10384       else if (unformat (i, "noadv"))
10385         no_advertise = 1;
10386       else if (unformat (i, "offl"))
10387         off_link = 1;
10388       else if (unformat (i, "noauto"))
10389         no_autoconfig = 1;
10390       else if (unformat (i, "nolink"))
10391         no_onlink = 1;
10392       else if (unformat (i, "isno"))
10393         is_no = 1;
10394       else
10395         {
10396           clib_warning ("parse error '%U'", format_unformat_error, i);
10397           return -99;
10398         }
10399     }
10400
10401   if (sw_if_index_set == 0)
10402     {
10403       errmsg ("missing interface name or sw_if_index");
10404       return -99;
10405     }
10406   if (!v6_address_set)
10407     {
10408       errmsg ("no address set");
10409       return -99;
10410     }
10411
10412   /* Construct the API message */
10413   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10414
10415   mp->sw_if_index = ntohl (sw_if_index);
10416   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10417   mp->address_length = address_length;
10418   mp->use_default = use_default;
10419   mp->no_advertise = no_advertise;
10420   mp->off_link = off_link;
10421   mp->no_autoconfig = no_autoconfig;
10422   mp->no_onlink = no_onlink;
10423   mp->is_no = is_no;
10424   mp->val_lifetime = ntohl (val_lifetime);
10425   mp->pref_lifetime = ntohl (pref_lifetime);
10426
10427   /* send it... */
10428   S (mp);
10429
10430   /* Wait for a reply, return good/bad news  */
10431   W (ret);
10432   return ret;
10433 }
10434
10435 static int
10436 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10437 {
10438   unformat_input_t *i = vam->input;
10439   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10440   u32 sw_if_index;
10441   u8 sw_if_index_set = 0;
10442   u8 suppress = 0;
10443   u8 managed = 0;
10444   u8 other = 0;
10445   u8 ll_option = 0;
10446   u8 send_unicast = 0;
10447   u8 cease = 0;
10448   u8 is_no = 0;
10449   u8 default_router = 0;
10450   u32 max_interval = 0;
10451   u32 min_interval = 0;
10452   u32 lifetime = 0;
10453   u32 initial_count = 0;
10454   u32 initial_interval = 0;
10455   int ret;
10456
10457
10458   /* Parse args required to build the message */
10459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10460     {
10461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10462         sw_if_index_set = 1;
10463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10464         sw_if_index_set = 1;
10465       else if (unformat (i, "maxint %d", &max_interval))
10466         ;
10467       else if (unformat (i, "minint %d", &min_interval))
10468         ;
10469       else if (unformat (i, "life %d", &lifetime))
10470         ;
10471       else if (unformat (i, "count %d", &initial_count))
10472         ;
10473       else if (unformat (i, "interval %d", &initial_interval))
10474         ;
10475       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10476         suppress = 1;
10477       else if (unformat (i, "managed"))
10478         managed = 1;
10479       else if (unformat (i, "other"))
10480         other = 1;
10481       else if (unformat (i, "ll"))
10482         ll_option = 1;
10483       else if (unformat (i, "send"))
10484         send_unicast = 1;
10485       else if (unformat (i, "cease"))
10486         cease = 1;
10487       else if (unformat (i, "isno"))
10488         is_no = 1;
10489       else if (unformat (i, "def"))
10490         default_router = 1;
10491       else
10492         {
10493           clib_warning ("parse error '%U'", format_unformat_error, i);
10494           return -99;
10495         }
10496     }
10497
10498   if (sw_if_index_set == 0)
10499     {
10500       errmsg ("missing interface name or sw_if_index");
10501       return -99;
10502     }
10503
10504   /* Construct the API message */
10505   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10506
10507   mp->sw_if_index = ntohl (sw_if_index);
10508   mp->max_interval = ntohl (max_interval);
10509   mp->min_interval = ntohl (min_interval);
10510   mp->lifetime = ntohl (lifetime);
10511   mp->initial_count = ntohl (initial_count);
10512   mp->initial_interval = ntohl (initial_interval);
10513   mp->suppress = suppress;
10514   mp->managed = managed;
10515   mp->other = other;
10516   mp->ll_option = ll_option;
10517   mp->send_unicast = send_unicast;
10518   mp->cease = cease;
10519   mp->is_no = is_no;
10520   mp->default_router = default_router;
10521
10522   /* send it... */
10523   S (mp);
10524
10525   /* Wait for a reply, return good/bad news  */
10526   W (ret);
10527   return ret;
10528 }
10529
10530 static int
10531 api_set_arp_neighbor_limit (vat_main_t * vam)
10532 {
10533   unformat_input_t *i = vam->input;
10534   vl_api_set_arp_neighbor_limit_t *mp;
10535   u32 arp_nbr_limit;
10536   u8 limit_set = 0;
10537   u8 is_ipv6 = 0;
10538   int ret;
10539
10540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10543         limit_set = 1;
10544       else if (unformat (i, "ipv6"))
10545         is_ipv6 = 1;
10546       else
10547         {
10548           clib_warning ("parse error '%U'", format_unformat_error, i);
10549           return -99;
10550         }
10551     }
10552
10553   if (limit_set == 0)
10554     {
10555       errmsg ("missing limit value");
10556       return -99;
10557     }
10558
10559   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10560
10561   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10562   mp->is_ipv6 = is_ipv6;
10563
10564   S (mp);
10565   W (ret);
10566   return ret;
10567 }
10568
10569 static int
10570 api_l2_patch_add_del (vat_main_t * vam)
10571 {
10572   unformat_input_t *i = vam->input;
10573   vl_api_l2_patch_add_del_t *mp;
10574   u32 rx_sw_if_index;
10575   u8 rx_sw_if_index_set = 0;
10576   u32 tx_sw_if_index;
10577   u8 tx_sw_if_index_set = 0;
10578   u8 is_add = 1;
10579   int ret;
10580
10581   /* Parse args required to build the message */
10582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10583     {
10584       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10585         rx_sw_if_index_set = 1;
10586       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10587         tx_sw_if_index_set = 1;
10588       else if (unformat (i, "rx"))
10589         {
10590           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591             {
10592               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10593                             &rx_sw_if_index))
10594                 rx_sw_if_index_set = 1;
10595             }
10596           else
10597             break;
10598         }
10599       else if (unformat (i, "tx"))
10600         {
10601           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10602             {
10603               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10604                             &tx_sw_if_index))
10605                 tx_sw_if_index_set = 1;
10606             }
10607           else
10608             break;
10609         }
10610       else if (unformat (i, "del"))
10611         is_add = 0;
10612       else
10613         break;
10614     }
10615
10616   if (rx_sw_if_index_set == 0)
10617     {
10618       errmsg ("missing rx interface name or rx_sw_if_index");
10619       return -99;
10620     }
10621
10622   if (tx_sw_if_index_set == 0)
10623     {
10624       errmsg ("missing tx interface name or tx_sw_if_index");
10625       return -99;
10626     }
10627
10628   M (L2_PATCH_ADD_DEL, mp);
10629
10630   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10631   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10632   mp->is_add = is_add;
10633
10634   S (mp);
10635   W (ret);
10636   return ret;
10637 }
10638
10639 u8 is_del;
10640 u8 localsid_addr[16];
10641 u8 end_psp;
10642 u8 behavior;
10643 u32 sw_if_index;
10644 u32 vlan_index;
10645 u32 fib_table;
10646 u8 nh_addr[16];
10647
10648 static int
10649 api_sr_localsid_add_del (vat_main_t * vam)
10650 {
10651   unformat_input_t *i = vam->input;
10652   vl_api_sr_localsid_add_del_t *mp;
10653
10654   u8 is_del;
10655   ip6_address_t localsid;
10656   u8 end_psp = 0;
10657   u8 behavior = ~0;
10658   u32 sw_if_index;
10659   u32 fib_table = ~(u32) 0;
10660   ip6_address_t nh_addr6;
10661   ip4_address_t nh_addr4;
10662   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10663   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10664
10665   bool nexthop_set = 0;
10666
10667   int ret;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "del"))
10672         is_del = 1;
10673       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10674       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10675         nexthop_set = 1;
10676       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10677         nexthop_set = 1;
10678       else if (unformat (i, "behavior %u", &behavior));
10679       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10680       else if (unformat (i, "fib-table %u", &fib_table));
10681       else if (unformat (i, "end.psp %u", &behavior));
10682       else
10683         break;
10684     }
10685
10686   M (SR_LOCALSID_ADD_DEL, mp);
10687
10688   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10689   if (nexthop_set)
10690     {
10691       clib_memcpy (mp->nh_addr6, &nh_addr4, sizeof (mp->nh_addr6));
10692       clib_memcpy (mp->nh_addr4, &nh_addr6, sizeof (mp->nh_addr4));
10693     }
10694   mp->behavior = behavior;
10695   mp->sw_if_index = ntohl (sw_if_index);
10696   mp->fib_table = ntohl (fib_table);
10697   mp->end_psp = end_psp;
10698   mp->is_del = is_del;
10699
10700   S (mp);
10701   W (ret);
10702   return ret;
10703 }
10704
10705 static int
10706 api_ioam_enable (vat_main_t * vam)
10707 {
10708   unformat_input_t *input = vam->input;
10709   vl_api_ioam_enable_t *mp;
10710   u32 id = 0;
10711   int has_trace_option = 0;
10712   int has_pot_option = 0;
10713   int has_seqno_option = 0;
10714   int has_analyse_option = 0;
10715   int ret;
10716
10717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (input, "trace"))
10720         has_trace_option = 1;
10721       else if (unformat (input, "pot"))
10722         has_pot_option = 1;
10723       else if (unformat (input, "seqno"))
10724         has_seqno_option = 1;
10725       else if (unformat (input, "analyse"))
10726         has_analyse_option = 1;
10727       else
10728         break;
10729     }
10730   M (IOAM_ENABLE, mp);
10731   mp->id = htons (id);
10732   mp->seqno = has_seqno_option;
10733   mp->analyse = has_analyse_option;
10734   mp->pot_enable = has_pot_option;
10735   mp->trace_enable = has_trace_option;
10736
10737   S (mp);
10738   W (ret);
10739   return ret;
10740 }
10741
10742
10743 static int
10744 api_ioam_disable (vat_main_t * vam)
10745 {
10746   vl_api_ioam_disable_t *mp;
10747   int ret;
10748
10749   M (IOAM_DISABLE, mp);
10750   S (mp);
10751   W (ret);
10752   return ret;
10753 }
10754
10755 #define foreach_tcp_proto_field                 \
10756 _(src_port)                                     \
10757 _(dst_port)
10758
10759 #define foreach_udp_proto_field                 \
10760 _(src_port)                                     \
10761 _(dst_port)
10762
10763 #define foreach_ip4_proto_field                 \
10764 _(src_address)                                  \
10765 _(dst_address)                                  \
10766 _(tos)                                          \
10767 _(length)                                       \
10768 _(fragment_id)                                  \
10769 _(ttl)                                          \
10770 _(protocol)                                     \
10771 _(checksum)
10772
10773 typedef struct
10774 {
10775   u16 src_port, dst_port;
10776 } tcpudp_header_t;
10777
10778 #if VPP_API_TEST_BUILTIN == 0
10779 uword
10780 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10781 {
10782   u8 **maskp = va_arg (*args, u8 **);
10783   u8 *mask = 0;
10784   u8 found_something = 0;
10785   tcp_header_t *tcp;
10786
10787 #define _(a) u8 a=0;
10788   foreach_tcp_proto_field;
10789 #undef _
10790
10791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10792     {
10793       if (0);
10794 #define _(a) else if (unformat (input, #a)) a=1;
10795       foreach_tcp_proto_field
10796 #undef _
10797         else
10798         break;
10799     }
10800
10801 #define _(a) found_something += a;
10802   foreach_tcp_proto_field;
10803 #undef _
10804
10805   if (found_something == 0)
10806     return 0;
10807
10808   vec_validate (mask, sizeof (*tcp) - 1);
10809
10810   tcp = (tcp_header_t *) mask;
10811
10812 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10813   foreach_tcp_proto_field;
10814 #undef _
10815
10816   *maskp = mask;
10817   return 1;
10818 }
10819
10820 uword
10821 unformat_udp_mask (unformat_input_t * input, va_list * args)
10822 {
10823   u8 **maskp = va_arg (*args, u8 **);
10824   u8 *mask = 0;
10825   u8 found_something = 0;
10826   udp_header_t *udp;
10827
10828 #define _(a) u8 a=0;
10829   foreach_udp_proto_field;
10830 #undef _
10831
10832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10833     {
10834       if (0);
10835 #define _(a) else if (unformat (input, #a)) a=1;
10836       foreach_udp_proto_field
10837 #undef _
10838         else
10839         break;
10840     }
10841
10842 #define _(a) found_something += a;
10843   foreach_udp_proto_field;
10844 #undef _
10845
10846   if (found_something == 0)
10847     return 0;
10848
10849   vec_validate (mask, sizeof (*udp) - 1);
10850
10851   udp = (udp_header_t *) mask;
10852
10853 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10854   foreach_udp_proto_field;
10855 #undef _
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_l4_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u16 src_port = 0, dst_port = 0;
10866   tcpudp_header_t *tcpudp;
10867
10868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10869     {
10870       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10871         return 1;
10872       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10873         return 1;
10874       else if (unformat (input, "src_port"))
10875         src_port = 0xFFFF;
10876       else if (unformat (input, "dst_port"))
10877         dst_port = 0xFFFF;
10878       else
10879         return 0;
10880     }
10881
10882   if (!src_port && !dst_port)
10883     return 0;
10884
10885   u8 *mask = 0;
10886   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10887
10888   tcpudp = (tcpudp_header_t *) mask;
10889   tcpudp->src_port = src_port;
10890   tcpudp->dst_port = dst_port;
10891
10892   *maskp = mask;
10893
10894   return 1;
10895 }
10896
10897 uword
10898 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10899 {
10900   u8 **maskp = va_arg (*args, u8 **);
10901   u8 *mask = 0;
10902   u8 found_something = 0;
10903   ip4_header_t *ip;
10904
10905 #define _(a) u8 a=0;
10906   foreach_ip4_proto_field;
10907 #undef _
10908   u8 version = 0;
10909   u8 hdr_length = 0;
10910
10911
10912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10913     {
10914       if (unformat (input, "version"))
10915         version = 1;
10916       else if (unformat (input, "hdr_length"))
10917         hdr_length = 1;
10918       else if (unformat (input, "src"))
10919         src_address = 1;
10920       else if (unformat (input, "dst"))
10921         dst_address = 1;
10922       else if (unformat (input, "proto"))
10923         protocol = 1;
10924
10925 #define _(a) else if (unformat (input, #a)) a=1;
10926       foreach_ip4_proto_field
10927 #undef _
10928         else
10929         break;
10930     }
10931
10932 #define _(a) found_something += a;
10933   foreach_ip4_proto_field;
10934 #undef _
10935
10936   if (found_something == 0)
10937     return 0;
10938
10939   vec_validate (mask, sizeof (*ip) - 1);
10940
10941   ip = (ip4_header_t *) mask;
10942
10943 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10944   foreach_ip4_proto_field;
10945 #undef _
10946
10947   ip->ip_version_and_header_length = 0;
10948
10949   if (version)
10950     ip->ip_version_and_header_length |= 0xF0;
10951
10952   if (hdr_length)
10953     ip->ip_version_and_header_length |= 0x0F;
10954
10955   *maskp = mask;
10956   return 1;
10957 }
10958
10959 #define foreach_ip6_proto_field                 \
10960 _(src_address)                                  \
10961 _(dst_address)                                  \
10962 _(payload_length)                               \
10963 _(hop_limit)                                    \
10964 _(protocol)
10965
10966 uword
10967 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10968 {
10969   u8 **maskp = va_arg (*args, u8 **);
10970   u8 *mask = 0;
10971   u8 found_something = 0;
10972   ip6_header_t *ip;
10973   u32 ip_version_traffic_class_and_flow_label;
10974
10975 #define _(a) u8 a=0;
10976   foreach_ip6_proto_field;
10977 #undef _
10978   u8 version = 0;
10979   u8 traffic_class = 0;
10980   u8 flow_label = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "version"))
10985         version = 1;
10986       else if (unformat (input, "traffic-class"))
10987         traffic_class = 1;
10988       else if (unformat (input, "flow-label"))
10989         flow_label = 1;
10990       else if (unformat (input, "src"))
10991         src_address = 1;
10992       else if (unformat (input, "dst"))
10993         dst_address = 1;
10994       else if (unformat (input, "proto"))
10995         protocol = 1;
10996
10997 #define _(a) else if (unformat (input, #a)) a=1;
10998       foreach_ip6_proto_field
10999 #undef _
11000         else
11001         break;
11002     }
11003
11004 #define _(a) found_something += a;
11005   foreach_ip6_proto_field;
11006 #undef _
11007
11008   if (found_something == 0)
11009     return 0;
11010
11011   vec_validate (mask, sizeof (*ip) - 1);
11012
11013   ip = (ip6_header_t *) mask;
11014
11015 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11016   foreach_ip6_proto_field;
11017 #undef _
11018
11019   ip_version_traffic_class_and_flow_label = 0;
11020
11021   if (version)
11022     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11023
11024   if (traffic_class)
11025     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11026
11027   if (flow_label)
11028     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11029
11030   ip->ip_version_traffic_class_and_flow_label =
11031     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11032
11033   *maskp = mask;
11034   return 1;
11035 }
11036
11037 uword
11038 unformat_l3_mask (unformat_input_t * input, va_list * args)
11039 {
11040   u8 **maskp = va_arg (*args, u8 **);
11041
11042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11045         return 1;
11046       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11047         return 1;
11048       else
11049         break;
11050     }
11051   return 0;
11052 }
11053
11054 uword
11055 unformat_l2_mask (unformat_input_t * input, va_list * args)
11056 {
11057   u8 **maskp = va_arg (*args, u8 **);
11058   u8 *mask = 0;
11059   u8 src = 0;
11060   u8 dst = 0;
11061   u8 proto = 0;
11062   u8 tag1 = 0;
11063   u8 tag2 = 0;
11064   u8 ignore_tag1 = 0;
11065   u8 ignore_tag2 = 0;
11066   u8 cos1 = 0;
11067   u8 cos2 = 0;
11068   u8 dot1q = 0;
11069   u8 dot1ad = 0;
11070   int len = 14;
11071
11072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11073     {
11074       if (unformat (input, "src"))
11075         src = 1;
11076       else if (unformat (input, "dst"))
11077         dst = 1;
11078       else if (unformat (input, "proto"))
11079         proto = 1;
11080       else if (unformat (input, "tag1"))
11081         tag1 = 1;
11082       else if (unformat (input, "tag2"))
11083         tag2 = 1;
11084       else if (unformat (input, "ignore-tag1"))
11085         ignore_tag1 = 1;
11086       else if (unformat (input, "ignore-tag2"))
11087         ignore_tag2 = 1;
11088       else if (unformat (input, "cos1"))
11089         cos1 = 1;
11090       else if (unformat (input, "cos2"))
11091         cos2 = 1;
11092       else if (unformat (input, "dot1q"))
11093         dot1q = 1;
11094       else if (unformat (input, "dot1ad"))
11095         dot1ad = 1;
11096       else
11097         break;
11098     }
11099   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11100        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11101     return 0;
11102
11103   if (tag1 || ignore_tag1 || cos1 || dot1q)
11104     len = 18;
11105   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11106     len = 22;
11107
11108   vec_validate (mask, len - 1);
11109
11110   if (dst)
11111     memset (mask, 0xff, 6);
11112
11113   if (src)
11114     memset (mask + 6, 0xff, 6);
11115
11116   if (tag2 || dot1ad)
11117     {
11118       /* inner vlan tag */
11119       if (tag2)
11120         {
11121           mask[19] = 0xff;
11122           mask[18] = 0x0f;
11123         }
11124       if (cos2)
11125         mask[18] |= 0xe0;
11126       if (proto)
11127         mask[21] = mask[20] = 0xff;
11128       if (tag1)
11129         {
11130           mask[15] = 0xff;
11131           mask[14] = 0x0f;
11132         }
11133       if (cos1)
11134         mask[14] |= 0xe0;
11135       *maskp = mask;
11136       return 1;
11137     }
11138   if (tag1 | dot1q)
11139     {
11140       if (tag1)
11141         {
11142           mask[15] = 0xff;
11143           mask[14] = 0x0f;
11144         }
11145       if (cos1)
11146         mask[14] |= 0xe0;
11147       if (proto)
11148         mask[16] = mask[17] = 0xff;
11149
11150       *maskp = mask;
11151       return 1;
11152     }
11153   if (cos2)
11154     mask[18] |= 0xe0;
11155   if (cos1)
11156     mask[14] |= 0xe0;
11157   if (proto)
11158     mask[12] = mask[13] = 0xff;
11159
11160   *maskp = mask;
11161   return 1;
11162 }
11163
11164 uword
11165 unformat_classify_mask (unformat_input_t * input, va_list * args)
11166 {
11167   u8 **maskp = va_arg (*args, u8 **);
11168   u32 *skipp = va_arg (*args, u32 *);
11169   u32 *matchp = va_arg (*args, u32 *);
11170   u32 match;
11171   u8 *mask = 0;
11172   u8 *l2 = 0;
11173   u8 *l3 = 0;
11174   u8 *l4 = 0;
11175   int i;
11176
11177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11180         ;
11181       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11182         ;
11183       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11184         ;
11185       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11186         ;
11187       else
11188         break;
11189     }
11190
11191   if (l4 && !l3)
11192     {
11193       vec_free (mask);
11194       vec_free (l2);
11195       vec_free (l4);
11196       return 0;
11197     }
11198
11199   if (mask || l2 || l3 || l4)
11200     {
11201       if (l2 || l3 || l4)
11202         {
11203           /* "With a free Ethernet header in every package" */
11204           if (l2 == 0)
11205             vec_validate (l2, 13);
11206           mask = l2;
11207           if (vec_len (l3))
11208             {
11209               vec_append (mask, l3);
11210               vec_free (l3);
11211             }
11212           if (vec_len (l4))
11213             {
11214               vec_append (mask, l4);
11215               vec_free (l4);
11216             }
11217         }
11218
11219       /* Scan forward looking for the first significant mask octet */
11220       for (i = 0; i < vec_len (mask); i++)
11221         if (mask[i])
11222           break;
11223
11224       /* compute (skip, match) params */
11225       *skipp = i / sizeof (u32x4);
11226       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11227
11228       /* Pad mask to an even multiple of the vector size */
11229       while (vec_len (mask) % sizeof (u32x4))
11230         vec_add1 (mask, 0);
11231
11232       match = vec_len (mask) / sizeof (u32x4);
11233
11234       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11235         {
11236           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11237           if (*tmp || *(tmp + 1))
11238             break;
11239           match--;
11240         }
11241       if (match == 0)
11242         clib_warning ("BUG: match 0");
11243
11244       _vec_len (mask) = match * sizeof (u32x4);
11245
11246       *matchp = match;
11247       *maskp = mask;
11248
11249       return 1;
11250     }
11251
11252   return 0;
11253 }
11254 #endif /* VPP_API_TEST_BUILTIN */
11255
11256 #define foreach_l2_next                         \
11257 _(drop, DROP)                                   \
11258 _(ethernet, ETHERNET_INPUT)                     \
11259 _(ip4, IP4_INPUT)                               \
11260 _(ip6, IP6_INPUT)
11261
11262 uword
11263 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11264 {
11265   u32 *miss_next_indexp = va_arg (*args, u32 *);
11266   u32 next_index = 0;
11267   u32 tmp;
11268
11269 #define _(n,N) \
11270   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11271   foreach_l2_next;
11272 #undef _
11273
11274   if (unformat (input, "%d", &tmp))
11275     {
11276       next_index = tmp;
11277       goto out;
11278     }
11279
11280   return 0;
11281
11282 out:
11283   *miss_next_indexp = next_index;
11284   return 1;
11285 }
11286
11287 #define foreach_ip_next                         \
11288 _(drop, DROP)                                   \
11289 _(local, LOCAL)                                 \
11290 _(rewrite, REWRITE)
11291
11292 uword
11293 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11294 {
11295   u32 *miss_next_indexp = va_arg (*args, u32 *);
11296   u32 next_index = 0;
11297   u32 tmp;
11298
11299 #define _(n,N) \
11300   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11301   foreach_ip_next;
11302 #undef _
11303
11304   if (unformat (input, "%d", &tmp))
11305     {
11306       next_index = tmp;
11307       goto out;
11308     }
11309
11310   return 0;
11311
11312 out:
11313   *miss_next_indexp = next_index;
11314   return 1;
11315 }
11316
11317 #define foreach_acl_next                        \
11318 _(deny, DENY)
11319
11320 uword
11321 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11322 {
11323   u32 *miss_next_indexp = va_arg (*args, u32 *);
11324   u32 next_index = 0;
11325   u32 tmp;
11326
11327 #define _(n,N) \
11328   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11329   foreach_acl_next;
11330 #undef _
11331
11332   if (unformat (input, "permit"))
11333     {
11334       next_index = ~0;
11335       goto out;
11336     }
11337   else if (unformat (input, "%d", &tmp))
11338     {
11339       next_index = tmp;
11340       goto out;
11341     }
11342
11343   return 0;
11344
11345 out:
11346   *miss_next_indexp = next_index;
11347   return 1;
11348 }
11349
11350 uword
11351 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11352 {
11353   u32 *r = va_arg (*args, u32 *);
11354
11355   if (unformat (input, "conform-color"))
11356     *r = POLICE_CONFORM;
11357   else if (unformat (input, "exceed-color"))
11358     *r = POLICE_EXCEED;
11359   else
11360     return 0;
11361
11362   return 1;
11363 }
11364
11365 static int
11366 api_classify_add_del_table (vat_main_t * vam)
11367 {
11368   unformat_input_t *i = vam->input;
11369   vl_api_classify_add_del_table_t *mp;
11370
11371   u32 nbuckets = 2;
11372   u32 skip = ~0;
11373   u32 match = ~0;
11374   int is_add = 1;
11375   int del_chain = 0;
11376   u32 table_index = ~0;
11377   u32 next_table_index = ~0;
11378   u32 miss_next_index = ~0;
11379   u32 memory_size = 32 << 20;
11380   u8 *mask = 0;
11381   u32 current_data_flag = 0;
11382   int current_data_offset = 0;
11383   int ret;
11384
11385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11386     {
11387       if (unformat (i, "del"))
11388         is_add = 0;
11389       else if (unformat (i, "del-chain"))
11390         {
11391           is_add = 0;
11392           del_chain = 1;
11393         }
11394       else if (unformat (i, "buckets %d", &nbuckets))
11395         ;
11396       else if (unformat (i, "memory_size %d", &memory_size))
11397         ;
11398       else if (unformat (i, "skip %d", &skip))
11399         ;
11400       else if (unformat (i, "match %d", &match))
11401         ;
11402       else if (unformat (i, "table %d", &table_index))
11403         ;
11404       else if (unformat (i, "mask %U", unformat_classify_mask,
11405                          &mask, &skip, &match))
11406         ;
11407       else if (unformat (i, "next-table %d", &next_table_index))
11408         ;
11409       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11410                          &miss_next_index))
11411         ;
11412       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11413                          &miss_next_index))
11414         ;
11415       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11416                          &miss_next_index))
11417         ;
11418       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11419         ;
11420       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11421         ;
11422       else
11423         break;
11424     }
11425
11426   if (is_add && mask == 0)
11427     {
11428       errmsg ("Mask required");
11429       return -99;
11430     }
11431
11432   if (is_add && skip == ~0)
11433     {
11434       errmsg ("skip count required");
11435       return -99;
11436     }
11437
11438   if (is_add && match == ~0)
11439     {
11440       errmsg ("match count required");
11441       return -99;
11442     }
11443
11444   if (!is_add && table_index == ~0)
11445     {
11446       errmsg ("table index required for delete");
11447       return -99;
11448     }
11449
11450   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11451
11452   mp->is_add = is_add;
11453   mp->del_chain = del_chain;
11454   mp->table_index = ntohl (table_index);
11455   mp->nbuckets = ntohl (nbuckets);
11456   mp->memory_size = ntohl (memory_size);
11457   mp->skip_n_vectors = ntohl (skip);
11458   mp->match_n_vectors = ntohl (match);
11459   mp->next_table_index = ntohl (next_table_index);
11460   mp->miss_next_index = ntohl (miss_next_index);
11461   mp->current_data_flag = ntohl (current_data_flag);
11462   mp->current_data_offset = ntohl (current_data_offset);
11463   clib_memcpy (mp->mask, mask, vec_len (mask));
11464
11465   vec_free (mask);
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 #if VPP_API_TEST_BUILTIN == 0
11473 uword
11474 unformat_l4_match (unformat_input_t * input, va_list * args)
11475 {
11476   u8 **matchp = va_arg (*args, u8 **);
11477
11478   u8 *proto_header = 0;
11479   int src_port = 0;
11480   int dst_port = 0;
11481
11482   tcpudp_header_t h;
11483
11484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (input, "src_port %d", &src_port))
11487         ;
11488       else if (unformat (input, "dst_port %d", &dst_port))
11489         ;
11490       else
11491         return 0;
11492     }
11493
11494   h.src_port = clib_host_to_net_u16 (src_port);
11495   h.dst_port = clib_host_to_net_u16 (dst_port);
11496   vec_validate (proto_header, sizeof (h) - 1);
11497   memcpy (proto_header, &h, sizeof (h));
11498
11499   *matchp = proto_header;
11500
11501   return 1;
11502 }
11503
11504 uword
11505 unformat_ip4_match (unformat_input_t * input, va_list * args)
11506 {
11507   u8 **matchp = va_arg (*args, u8 **);
11508   u8 *match = 0;
11509   ip4_header_t *ip;
11510   int version = 0;
11511   u32 version_val;
11512   int hdr_length = 0;
11513   u32 hdr_length_val;
11514   int src = 0, dst = 0;
11515   ip4_address_t src_val, dst_val;
11516   int proto = 0;
11517   u32 proto_val;
11518   int tos = 0;
11519   u32 tos_val;
11520   int length = 0;
11521   u32 length_val;
11522   int fragment_id = 0;
11523   u32 fragment_id_val;
11524   int ttl = 0;
11525   int ttl_val;
11526   int checksum = 0;
11527   u32 checksum_val;
11528
11529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (input, "version %d", &version_val))
11532         version = 1;
11533       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11534         hdr_length = 1;
11535       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11536         src = 1;
11537       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11538         dst = 1;
11539       else if (unformat (input, "proto %d", &proto_val))
11540         proto = 1;
11541       else if (unformat (input, "tos %d", &tos_val))
11542         tos = 1;
11543       else if (unformat (input, "length %d", &length_val))
11544         length = 1;
11545       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11546         fragment_id = 1;
11547       else if (unformat (input, "ttl %d", &ttl_val))
11548         ttl = 1;
11549       else if (unformat (input, "checksum %d", &checksum_val))
11550         checksum = 1;
11551       else
11552         break;
11553     }
11554
11555   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11556       + ttl + checksum == 0)
11557     return 0;
11558
11559   /*
11560    * Aligned because we use the real comparison functions
11561    */
11562   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11563
11564   ip = (ip4_header_t *) match;
11565
11566   /* These are realistically matched in practice */
11567   if (src)
11568     ip->src_address.as_u32 = src_val.as_u32;
11569
11570   if (dst)
11571     ip->dst_address.as_u32 = dst_val.as_u32;
11572
11573   if (proto)
11574     ip->protocol = proto_val;
11575
11576
11577   /* These are not, but they're included for completeness */
11578   if (version)
11579     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11580
11581   if (hdr_length)
11582     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11583
11584   if (tos)
11585     ip->tos = tos_val;
11586
11587   if (length)
11588     ip->length = clib_host_to_net_u16 (length_val);
11589
11590   if (ttl)
11591     ip->ttl = ttl_val;
11592
11593   if (checksum)
11594     ip->checksum = clib_host_to_net_u16 (checksum_val);
11595
11596   *matchp = match;
11597   return 1;
11598 }
11599
11600 uword
11601 unformat_ip6_match (unformat_input_t * input, va_list * args)
11602 {
11603   u8 **matchp = va_arg (*args, u8 **);
11604   u8 *match = 0;
11605   ip6_header_t *ip;
11606   int version = 0;
11607   u32 version_val;
11608   u8 traffic_class = 0;
11609   u32 traffic_class_val = 0;
11610   u8 flow_label = 0;
11611   u8 flow_label_val;
11612   int src = 0, dst = 0;
11613   ip6_address_t src_val, dst_val;
11614   int proto = 0;
11615   u32 proto_val;
11616   int payload_length = 0;
11617   u32 payload_length_val;
11618   int hop_limit = 0;
11619   int hop_limit_val;
11620   u32 ip_version_traffic_class_and_flow_label;
11621
11622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11623     {
11624       if (unformat (input, "version %d", &version_val))
11625         version = 1;
11626       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11627         traffic_class = 1;
11628       else if (unformat (input, "flow_label %d", &flow_label_val))
11629         flow_label = 1;
11630       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11631         src = 1;
11632       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11633         dst = 1;
11634       else if (unformat (input, "proto %d", &proto_val))
11635         proto = 1;
11636       else if (unformat (input, "payload_length %d", &payload_length_val))
11637         payload_length = 1;
11638       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11639         hop_limit = 1;
11640       else
11641         break;
11642     }
11643
11644   if (version + traffic_class + flow_label + src + dst + proto +
11645       payload_length + hop_limit == 0)
11646     return 0;
11647
11648   /*
11649    * Aligned because we use the real comparison functions
11650    */
11651   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11652
11653   ip = (ip6_header_t *) match;
11654
11655   if (src)
11656     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11657
11658   if (dst)
11659     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11660
11661   if (proto)
11662     ip->protocol = proto_val;
11663
11664   ip_version_traffic_class_and_flow_label = 0;
11665
11666   if (version)
11667     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11668
11669   if (traffic_class)
11670     ip_version_traffic_class_and_flow_label |=
11671       (traffic_class_val & 0xFF) << 20;
11672
11673   if (flow_label)
11674     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11675
11676   ip->ip_version_traffic_class_and_flow_label =
11677     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11678
11679   if (payload_length)
11680     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11681
11682   if (hop_limit)
11683     ip->hop_limit = hop_limit_val;
11684
11685   *matchp = match;
11686   return 1;
11687 }
11688
11689 uword
11690 unformat_l3_match (unformat_input_t * input, va_list * args)
11691 {
11692   u8 **matchp = va_arg (*args, u8 **);
11693
11694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11695     {
11696       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11697         return 1;
11698       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11699         return 1;
11700       else
11701         break;
11702     }
11703   return 0;
11704 }
11705
11706 uword
11707 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11708 {
11709   u8 *tagp = va_arg (*args, u8 *);
11710   u32 tag;
11711
11712   if (unformat (input, "%d", &tag))
11713     {
11714       tagp[0] = (tag >> 8) & 0x0F;
11715       tagp[1] = tag & 0xFF;
11716       return 1;
11717     }
11718
11719   return 0;
11720 }
11721
11722 uword
11723 unformat_l2_match (unformat_input_t * input, va_list * args)
11724 {
11725   u8 **matchp = va_arg (*args, u8 **);
11726   u8 *match = 0;
11727   u8 src = 0;
11728   u8 src_val[6];
11729   u8 dst = 0;
11730   u8 dst_val[6];
11731   u8 proto = 0;
11732   u16 proto_val;
11733   u8 tag1 = 0;
11734   u8 tag1_val[2];
11735   u8 tag2 = 0;
11736   u8 tag2_val[2];
11737   int len = 14;
11738   u8 ignore_tag1 = 0;
11739   u8 ignore_tag2 = 0;
11740   u8 cos1 = 0;
11741   u8 cos2 = 0;
11742   u32 cos1_val = 0;
11743   u32 cos2_val = 0;
11744
11745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11748         src = 1;
11749       else
11750         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11751         dst = 1;
11752       else if (unformat (input, "proto %U",
11753                          unformat_ethernet_type_host_byte_order, &proto_val))
11754         proto = 1;
11755       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11756         tag1 = 1;
11757       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11758         tag2 = 1;
11759       else if (unformat (input, "ignore-tag1"))
11760         ignore_tag1 = 1;
11761       else if (unformat (input, "ignore-tag2"))
11762         ignore_tag2 = 1;
11763       else if (unformat (input, "cos1 %d", &cos1_val))
11764         cos1 = 1;
11765       else if (unformat (input, "cos2 %d", &cos2_val))
11766         cos2 = 1;
11767       else
11768         break;
11769     }
11770   if ((src + dst + proto + tag1 + tag2 +
11771        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11772     return 0;
11773
11774   if (tag1 || ignore_tag1 || cos1)
11775     len = 18;
11776   if (tag2 || ignore_tag2 || cos2)
11777     len = 22;
11778
11779   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11780
11781   if (dst)
11782     clib_memcpy (match, dst_val, 6);
11783
11784   if (src)
11785     clib_memcpy (match + 6, src_val, 6);
11786
11787   if (tag2)
11788     {
11789       /* inner vlan tag */
11790       match[19] = tag2_val[1];
11791       match[18] = tag2_val[0];
11792       if (cos2)
11793         match[18] |= (cos2_val & 0x7) << 5;
11794       if (proto)
11795         {
11796           match[21] = proto_val & 0xff;
11797           match[20] = proto_val >> 8;
11798         }
11799       if (tag1)
11800         {
11801           match[15] = tag1_val[1];
11802           match[14] = tag1_val[0];
11803         }
11804       if (cos1)
11805         match[14] |= (cos1_val & 0x7) << 5;
11806       *matchp = match;
11807       return 1;
11808     }
11809   if (tag1)
11810     {
11811       match[15] = tag1_val[1];
11812       match[14] = tag1_val[0];
11813       if (proto)
11814         {
11815           match[17] = proto_val & 0xff;
11816           match[16] = proto_val >> 8;
11817         }
11818       if (cos1)
11819         match[14] |= (cos1_val & 0x7) << 5;
11820
11821       *matchp = match;
11822       return 1;
11823     }
11824   if (cos2)
11825     match[18] |= (cos2_val & 0x7) << 5;
11826   if (cos1)
11827     match[14] |= (cos1_val & 0x7) << 5;
11828   if (proto)
11829     {
11830       match[13] = proto_val & 0xff;
11831       match[12] = proto_val >> 8;
11832     }
11833
11834   *matchp = match;
11835   return 1;
11836 }
11837
11838 uword
11839 unformat_qos_source (unformat_input_t * input, va_list * args)
11840 {
11841   int *qs = va_arg (*args, int *);
11842
11843   if (unformat (input, "ip"))
11844     *qs = QOS_SOURCE_IP;
11845   else if (unformat (input, "mpls"))
11846     *qs = QOS_SOURCE_MPLS;
11847   else if (unformat (input, "ext"))
11848     *qs = QOS_SOURCE_EXT;
11849   else if (unformat (input, "vlan"))
11850     *qs = QOS_SOURCE_VLAN;
11851   else
11852     return 0;
11853
11854   return 1;
11855 }
11856 #endif
11857
11858 uword
11859 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11860 {
11861   u8 **matchp = va_arg (*args, u8 **);
11862   u32 skip_n_vectors = va_arg (*args, u32);
11863   u32 match_n_vectors = va_arg (*args, u32);
11864
11865   u8 *match = 0;
11866   u8 *l2 = 0;
11867   u8 *l3 = 0;
11868   u8 *l4 = 0;
11869
11870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11871     {
11872       if (unformat (input, "hex %U", unformat_hex_string, &match))
11873         ;
11874       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11875         ;
11876       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11877         ;
11878       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11879         ;
11880       else
11881         break;
11882     }
11883
11884   if (l4 && !l3)
11885     {
11886       vec_free (match);
11887       vec_free (l2);
11888       vec_free (l4);
11889       return 0;
11890     }
11891
11892   if (match || l2 || l3 || l4)
11893     {
11894       if (l2 || l3 || l4)
11895         {
11896           /* "Win a free Ethernet header in every packet" */
11897           if (l2 == 0)
11898             vec_validate_aligned (l2, 13, sizeof (u32x4));
11899           match = l2;
11900           if (vec_len (l3))
11901             {
11902               vec_append_aligned (match, l3, sizeof (u32x4));
11903               vec_free (l3);
11904             }
11905           if (vec_len (l4))
11906             {
11907               vec_append_aligned (match, l4, sizeof (u32x4));
11908               vec_free (l4);
11909             }
11910         }
11911
11912       /* Make sure the vector is big enough even if key is all 0's */
11913       vec_validate_aligned
11914         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11915          sizeof (u32x4));
11916
11917       /* Set size, include skipped vectors */
11918       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11919
11920       *matchp = match;
11921
11922       return 1;
11923     }
11924
11925   return 0;
11926 }
11927
11928 static int
11929 api_classify_add_del_session (vat_main_t * vam)
11930 {
11931   unformat_input_t *i = vam->input;
11932   vl_api_classify_add_del_session_t *mp;
11933   int is_add = 1;
11934   u32 table_index = ~0;
11935   u32 hit_next_index = ~0;
11936   u32 opaque_index = ~0;
11937   u8 *match = 0;
11938   i32 advance = 0;
11939   u32 skip_n_vectors = 0;
11940   u32 match_n_vectors = 0;
11941   u32 action = 0;
11942   u32 metadata = 0;
11943   int ret;
11944
11945   /*
11946    * Warning: you have to supply skip_n and match_n
11947    * because the API client cant simply look at the classify
11948    * table object.
11949    */
11950
11951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (i, "del"))
11954         is_add = 0;
11955       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11956                          &hit_next_index))
11957         ;
11958       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11959                          &hit_next_index))
11960         ;
11961       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11962                          &hit_next_index))
11963         ;
11964       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11965         ;
11966       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11967         ;
11968       else if (unformat (i, "opaque-index %d", &opaque_index))
11969         ;
11970       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11971         ;
11972       else if (unformat (i, "match_n %d", &match_n_vectors))
11973         ;
11974       else if (unformat (i, "match %U", api_unformat_classify_match,
11975                          &match, skip_n_vectors, match_n_vectors))
11976         ;
11977       else if (unformat (i, "advance %d", &advance))
11978         ;
11979       else if (unformat (i, "table-index %d", &table_index))
11980         ;
11981       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11982         action = 1;
11983       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11984         action = 2;
11985       else if (unformat (i, "action %d", &action))
11986         ;
11987       else if (unformat (i, "metadata %d", &metadata))
11988         ;
11989       else
11990         break;
11991     }
11992
11993   if (table_index == ~0)
11994     {
11995       errmsg ("Table index required");
11996       return -99;
11997     }
11998
11999   if (is_add && match == 0)
12000     {
12001       errmsg ("Match value required");
12002       return -99;
12003     }
12004
12005   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12006
12007   mp->is_add = is_add;
12008   mp->table_index = ntohl (table_index);
12009   mp->hit_next_index = ntohl (hit_next_index);
12010   mp->opaque_index = ntohl (opaque_index);
12011   mp->advance = ntohl (advance);
12012   mp->action = action;
12013   mp->metadata = ntohl (metadata);
12014   clib_memcpy (mp->match, match, vec_len (match));
12015   vec_free (match);
12016
12017   S (mp);
12018   W (ret);
12019   return ret;
12020 }
12021
12022 static int
12023 api_classify_set_interface_ip_table (vat_main_t * vam)
12024 {
12025   unformat_input_t *i = vam->input;
12026   vl_api_classify_set_interface_ip_table_t *mp;
12027   u32 sw_if_index;
12028   int sw_if_index_set;
12029   u32 table_index = ~0;
12030   u8 is_ipv6 = 0;
12031   int ret;
12032
12033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12034     {
12035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12036         sw_if_index_set = 1;
12037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "table %d", &table_index))
12040         ;
12041       else
12042         {
12043           clib_warning ("parse error '%U'", format_unformat_error, i);
12044           return -99;
12045         }
12046     }
12047
12048   if (sw_if_index_set == 0)
12049     {
12050       errmsg ("missing interface name or sw_if_index");
12051       return -99;
12052     }
12053
12054
12055   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12056
12057   mp->sw_if_index = ntohl (sw_if_index);
12058   mp->table_index = ntohl (table_index);
12059   mp->is_ipv6 = is_ipv6;
12060
12061   S (mp);
12062   W (ret);
12063   return ret;
12064 }
12065
12066 static int
12067 api_classify_set_interface_l2_tables (vat_main_t * vam)
12068 {
12069   unformat_input_t *i = vam->input;
12070   vl_api_classify_set_interface_l2_tables_t *mp;
12071   u32 sw_if_index;
12072   int sw_if_index_set;
12073   u32 ip4_table_index = ~0;
12074   u32 ip6_table_index = ~0;
12075   u32 other_table_index = ~0;
12076   u32 is_input = 1;
12077   int ret;
12078
12079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12082         sw_if_index_set = 1;
12083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12084         sw_if_index_set = 1;
12085       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12086         ;
12087       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12088         ;
12089       else if (unformat (i, "other-table %d", &other_table_index))
12090         ;
12091       else if (unformat (i, "is-input %d", &is_input))
12092         ;
12093       else
12094         {
12095           clib_warning ("parse error '%U'", format_unformat_error, i);
12096           return -99;
12097         }
12098     }
12099
12100   if (sw_if_index_set == 0)
12101     {
12102       errmsg ("missing interface name or sw_if_index");
12103       return -99;
12104     }
12105
12106
12107   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12108
12109   mp->sw_if_index = ntohl (sw_if_index);
12110   mp->ip4_table_index = ntohl (ip4_table_index);
12111   mp->ip6_table_index = ntohl (ip6_table_index);
12112   mp->other_table_index = ntohl (other_table_index);
12113   mp->is_input = (u8) is_input;
12114
12115   S (mp);
12116   W (ret);
12117   return ret;
12118 }
12119
12120 static int
12121 api_set_ipfix_exporter (vat_main_t * vam)
12122 {
12123   unformat_input_t *i = vam->input;
12124   vl_api_set_ipfix_exporter_t *mp;
12125   ip4_address_t collector_address;
12126   u8 collector_address_set = 0;
12127   u32 collector_port = ~0;
12128   ip4_address_t src_address;
12129   u8 src_address_set = 0;
12130   u32 vrf_id = ~0;
12131   u32 path_mtu = ~0;
12132   u32 template_interval = ~0;
12133   u8 udp_checksum = 0;
12134   int ret;
12135
12136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12137     {
12138       if (unformat (i, "collector_address %U", unformat_ip4_address,
12139                     &collector_address))
12140         collector_address_set = 1;
12141       else if (unformat (i, "collector_port %d", &collector_port))
12142         ;
12143       else if (unformat (i, "src_address %U", unformat_ip4_address,
12144                          &src_address))
12145         src_address_set = 1;
12146       else if (unformat (i, "vrf_id %d", &vrf_id))
12147         ;
12148       else if (unformat (i, "path_mtu %d", &path_mtu))
12149         ;
12150       else if (unformat (i, "template_interval %d", &template_interval))
12151         ;
12152       else if (unformat (i, "udp_checksum"))
12153         udp_checksum = 1;
12154       else
12155         break;
12156     }
12157
12158   if (collector_address_set == 0)
12159     {
12160       errmsg ("collector_address required");
12161       return -99;
12162     }
12163
12164   if (src_address_set == 0)
12165     {
12166       errmsg ("src_address required");
12167       return -99;
12168     }
12169
12170   M (SET_IPFIX_EXPORTER, mp);
12171
12172   memcpy (mp->collector_address, collector_address.data,
12173           sizeof (collector_address.data));
12174   mp->collector_port = htons ((u16) collector_port);
12175   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12176   mp->vrf_id = htonl (vrf_id);
12177   mp->path_mtu = htonl (path_mtu);
12178   mp->template_interval = htonl (template_interval);
12179   mp->udp_checksum = udp_checksum;
12180
12181   S (mp);
12182   W (ret);
12183   return ret;
12184 }
12185
12186 static int
12187 api_set_ipfix_classify_stream (vat_main_t * vam)
12188 {
12189   unformat_input_t *i = vam->input;
12190   vl_api_set_ipfix_classify_stream_t *mp;
12191   u32 domain_id = 0;
12192   u32 src_port = UDP_DST_PORT_ipfix;
12193   int ret;
12194
12195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12196     {
12197       if (unformat (i, "domain %d", &domain_id))
12198         ;
12199       else if (unformat (i, "src_port %d", &src_port))
12200         ;
12201       else
12202         {
12203           errmsg ("unknown input `%U'", format_unformat_error, i);
12204           return -99;
12205         }
12206     }
12207
12208   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12209
12210   mp->domain_id = htonl (domain_id);
12211   mp->src_port = htons ((u16) src_port);
12212
12213   S (mp);
12214   W (ret);
12215   return ret;
12216 }
12217
12218 static int
12219 api_ipfix_classify_table_add_del (vat_main_t * vam)
12220 {
12221   unformat_input_t *i = vam->input;
12222   vl_api_ipfix_classify_table_add_del_t *mp;
12223   int is_add = -1;
12224   u32 classify_table_index = ~0;
12225   u8 ip_version = 0;
12226   u8 transport_protocol = 255;
12227   int ret;
12228
12229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12230     {
12231       if (unformat (i, "add"))
12232         is_add = 1;
12233       else if (unformat (i, "del"))
12234         is_add = 0;
12235       else if (unformat (i, "table %d", &classify_table_index))
12236         ;
12237       else if (unformat (i, "ip4"))
12238         ip_version = 4;
12239       else if (unformat (i, "ip6"))
12240         ip_version = 6;
12241       else if (unformat (i, "tcp"))
12242         transport_protocol = 6;
12243       else if (unformat (i, "udp"))
12244         transport_protocol = 17;
12245       else
12246         {
12247           errmsg ("unknown input `%U'", format_unformat_error, i);
12248           return -99;
12249         }
12250     }
12251
12252   if (is_add == -1)
12253     {
12254       errmsg ("expecting: add|del");
12255       return -99;
12256     }
12257   if (classify_table_index == ~0)
12258     {
12259       errmsg ("classifier table not specified");
12260       return -99;
12261     }
12262   if (ip_version == 0)
12263     {
12264       errmsg ("IP version not specified");
12265       return -99;
12266     }
12267
12268   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12269
12270   mp->is_add = is_add;
12271   mp->table_id = htonl (classify_table_index);
12272   mp->ip_version = ip_version;
12273   mp->transport_protocol = transport_protocol;
12274
12275   S (mp);
12276   W (ret);
12277   return ret;
12278 }
12279
12280 static int
12281 api_get_node_index (vat_main_t * vam)
12282 {
12283   unformat_input_t *i = vam->input;
12284   vl_api_get_node_index_t *mp;
12285   u8 *name = 0;
12286   int ret;
12287
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "node %s", &name))
12291         ;
12292       else
12293         break;
12294     }
12295   if (name == 0)
12296     {
12297       errmsg ("node name required");
12298       return -99;
12299     }
12300   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12301     {
12302       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12303       return -99;
12304     }
12305
12306   M (GET_NODE_INDEX, mp);
12307   clib_memcpy (mp->node_name, name, vec_len (name));
12308   vec_free (name);
12309
12310   S (mp);
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static int
12316 api_get_next_index (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_get_next_index_t *mp;
12320   u8 *node_name = 0, *next_node_name = 0;
12321   int ret;
12322
12323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12324     {
12325       if (unformat (i, "node-name %s", &node_name))
12326         ;
12327       else if (unformat (i, "next-node-name %s", &next_node_name))
12328         break;
12329     }
12330
12331   if (node_name == 0)
12332     {
12333       errmsg ("node name required");
12334       return -99;
12335     }
12336   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12337     {
12338       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12339       return -99;
12340     }
12341
12342   if (next_node_name == 0)
12343     {
12344       errmsg ("next node name required");
12345       return -99;
12346     }
12347   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12348     {
12349       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12350       return -99;
12351     }
12352
12353   M (GET_NEXT_INDEX, mp);
12354   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12355   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12356   vec_free (node_name);
12357   vec_free (next_node_name);
12358
12359   S (mp);
12360   W (ret);
12361   return ret;
12362 }
12363
12364 static int
12365 api_add_node_next (vat_main_t * vam)
12366 {
12367   unformat_input_t *i = vam->input;
12368   vl_api_add_node_next_t *mp;
12369   u8 *name = 0;
12370   u8 *next = 0;
12371   int ret;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "node %s", &name))
12376         ;
12377       else if (unformat (i, "next %s", &next))
12378         ;
12379       else
12380         break;
12381     }
12382   if (name == 0)
12383     {
12384       errmsg ("node name required");
12385       return -99;
12386     }
12387   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12388     {
12389       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12390       return -99;
12391     }
12392   if (next == 0)
12393     {
12394       errmsg ("next node required");
12395       return -99;
12396     }
12397   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12398     {
12399       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12400       return -99;
12401     }
12402
12403   M (ADD_NODE_NEXT, mp);
12404   clib_memcpy (mp->node_name, name, vec_len (name));
12405   clib_memcpy (mp->next_name, next, vec_len (next));
12406   vec_free (name);
12407   vec_free (next);
12408
12409   S (mp);
12410   W (ret);
12411   return ret;
12412 }
12413
12414 static int
12415 api_l2tpv3_create_tunnel (vat_main_t * vam)
12416 {
12417   unformat_input_t *i = vam->input;
12418   ip6_address_t client_address, our_address;
12419   int client_address_set = 0;
12420   int our_address_set = 0;
12421   u32 local_session_id = 0;
12422   u32 remote_session_id = 0;
12423   u64 local_cookie = 0;
12424   u64 remote_cookie = 0;
12425   u8 l2_sublayer_present = 0;
12426   vl_api_l2tpv3_create_tunnel_t *mp;
12427   int ret;
12428
12429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (i, "client_address %U", unformat_ip6_address,
12432                     &client_address))
12433         client_address_set = 1;
12434       else if (unformat (i, "our_address %U", unformat_ip6_address,
12435                          &our_address))
12436         our_address_set = 1;
12437       else if (unformat (i, "local_session_id %d", &local_session_id))
12438         ;
12439       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12440         ;
12441       else if (unformat (i, "local_cookie %lld", &local_cookie))
12442         ;
12443       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12444         ;
12445       else if (unformat (i, "l2-sublayer-present"))
12446         l2_sublayer_present = 1;
12447       else
12448         break;
12449     }
12450
12451   if (client_address_set == 0)
12452     {
12453       errmsg ("client_address required");
12454       return -99;
12455     }
12456
12457   if (our_address_set == 0)
12458     {
12459       errmsg ("our_address required");
12460       return -99;
12461     }
12462
12463   M (L2TPV3_CREATE_TUNNEL, mp);
12464
12465   clib_memcpy (mp->client_address, client_address.as_u8,
12466                sizeof (mp->client_address));
12467
12468   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12469
12470   mp->local_session_id = ntohl (local_session_id);
12471   mp->remote_session_id = ntohl (remote_session_id);
12472   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12473   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12474   mp->l2_sublayer_present = l2_sublayer_present;
12475   mp->is_ipv6 = 1;
12476
12477   S (mp);
12478   W (ret);
12479   return ret;
12480 }
12481
12482 static int
12483 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12484 {
12485   unformat_input_t *i = vam->input;
12486   u32 sw_if_index;
12487   u8 sw_if_index_set = 0;
12488   u64 new_local_cookie = 0;
12489   u64 new_remote_cookie = 0;
12490   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12491   int ret;
12492
12493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12494     {
12495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12496         sw_if_index_set = 1;
12497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12498         sw_if_index_set = 1;
12499       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12500         ;
12501       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12502         ;
12503       else
12504         break;
12505     }
12506
12507   if (sw_if_index_set == 0)
12508     {
12509       errmsg ("missing interface name or sw_if_index");
12510       return -99;
12511     }
12512
12513   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12514
12515   mp->sw_if_index = ntohl (sw_if_index);
12516   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12517   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12518
12519   S (mp);
12520   W (ret);
12521   return ret;
12522 }
12523
12524 static int
12525 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12526 {
12527   unformat_input_t *i = vam->input;
12528   vl_api_l2tpv3_interface_enable_disable_t *mp;
12529   u32 sw_if_index;
12530   u8 sw_if_index_set = 0;
12531   u8 enable_disable = 1;
12532   int ret;
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12537         sw_if_index_set = 1;
12538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12539         sw_if_index_set = 1;
12540       else if (unformat (i, "enable"))
12541         enable_disable = 1;
12542       else if (unformat (i, "disable"))
12543         enable_disable = 0;
12544       else
12545         break;
12546     }
12547
12548   if (sw_if_index_set == 0)
12549     {
12550       errmsg ("missing interface name or sw_if_index");
12551       return -99;
12552     }
12553
12554   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12555
12556   mp->sw_if_index = ntohl (sw_if_index);
12557   mp->enable_disable = enable_disable;
12558
12559   S (mp);
12560   W (ret);
12561   return ret;
12562 }
12563
12564 static int
12565 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12566 {
12567   unformat_input_t *i = vam->input;
12568   vl_api_l2tpv3_set_lookup_key_t *mp;
12569   u8 key = ~0;
12570   int ret;
12571
12572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12573     {
12574       if (unformat (i, "lookup_v6_src"))
12575         key = L2T_LOOKUP_SRC_ADDRESS;
12576       else if (unformat (i, "lookup_v6_dst"))
12577         key = L2T_LOOKUP_DST_ADDRESS;
12578       else if (unformat (i, "lookup_session_id"))
12579         key = L2T_LOOKUP_SESSION_ID;
12580       else
12581         break;
12582     }
12583
12584   if (key == (u8) ~ 0)
12585     {
12586       errmsg ("l2tp session lookup key unset");
12587       return -99;
12588     }
12589
12590   M (L2TPV3_SET_LOOKUP_KEY, mp);
12591
12592   mp->key = key;
12593
12594   S (mp);
12595   W (ret);
12596   return ret;
12597 }
12598
12599 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12600   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12601 {
12602   vat_main_t *vam = &vat_main;
12603
12604   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12605          format_ip6_address, mp->our_address,
12606          format_ip6_address, mp->client_address,
12607          clib_net_to_host_u32 (mp->sw_if_index));
12608
12609   print (vam->ofp,
12610          "   local cookies %016llx %016llx remote cookie %016llx",
12611          clib_net_to_host_u64 (mp->local_cookie[0]),
12612          clib_net_to_host_u64 (mp->local_cookie[1]),
12613          clib_net_to_host_u64 (mp->remote_cookie));
12614
12615   print (vam->ofp, "   local session-id %d remote session-id %d",
12616          clib_net_to_host_u32 (mp->local_session_id),
12617          clib_net_to_host_u32 (mp->remote_session_id));
12618
12619   print (vam->ofp, "   l2 specific sublayer %s\n",
12620          mp->l2_sublayer_present ? "preset" : "absent");
12621
12622 }
12623
12624 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12625   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12626 {
12627   vat_main_t *vam = &vat_main;
12628   vat_json_node_t *node = NULL;
12629   struct in6_addr addr;
12630
12631   if (VAT_JSON_ARRAY != vam->json_tree.type)
12632     {
12633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12634       vat_json_init_array (&vam->json_tree);
12635     }
12636   node = vat_json_array_add (&vam->json_tree);
12637
12638   vat_json_init_object (node);
12639
12640   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12641   vat_json_object_add_ip6 (node, "our_address", addr);
12642   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12643   vat_json_object_add_ip6 (node, "client_address", addr);
12644
12645   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12646   vat_json_init_array (lc);
12647   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12648   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12649   vat_json_object_add_uint (node, "remote_cookie",
12650                             clib_net_to_host_u64 (mp->remote_cookie));
12651
12652   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12653   vat_json_object_add_uint (node, "local_session_id",
12654                             clib_net_to_host_u32 (mp->local_session_id));
12655   vat_json_object_add_uint (node, "remote_session_id",
12656                             clib_net_to_host_u32 (mp->remote_session_id));
12657   vat_json_object_add_string_copy (node, "l2_sublayer",
12658                                    mp->l2_sublayer_present ? (u8 *) "present"
12659                                    : (u8 *) "absent");
12660 }
12661
12662 static int
12663 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12664 {
12665   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12666   vl_api_control_ping_t *mp_ping;
12667   int ret;
12668
12669   /* Get list of l2tpv3-tunnel interfaces */
12670   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12671   S (mp);
12672
12673   /* Use a control ping for synchronization */
12674   MPING (CONTROL_PING, mp_ping);
12675   S (mp_ping);
12676
12677   W (ret);
12678   return ret;
12679 }
12680
12681
12682 static void vl_api_sw_interface_tap_details_t_handler
12683   (vl_api_sw_interface_tap_details_t * mp)
12684 {
12685   vat_main_t *vam = &vat_main;
12686
12687   print (vam->ofp, "%-16s %d",
12688          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12689 }
12690
12691 static void vl_api_sw_interface_tap_details_t_handler_json
12692   (vl_api_sw_interface_tap_details_t * mp)
12693 {
12694   vat_main_t *vam = &vat_main;
12695   vat_json_node_t *node = NULL;
12696
12697   if (VAT_JSON_ARRAY != vam->json_tree.type)
12698     {
12699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12700       vat_json_init_array (&vam->json_tree);
12701     }
12702   node = vat_json_array_add (&vam->json_tree);
12703
12704   vat_json_init_object (node);
12705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12706   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12707 }
12708
12709 static int
12710 api_sw_interface_tap_dump (vat_main_t * vam)
12711 {
12712   vl_api_sw_interface_tap_dump_t *mp;
12713   vl_api_control_ping_t *mp_ping;
12714   int ret;
12715
12716   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12717   /* Get list of tap interfaces */
12718   M (SW_INTERFACE_TAP_DUMP, mp);
12719   S (mp);
12720
12721   /* Use a control ping for synchronization */
12722   MPING (CONTROL_PING, mp_ping);
12723   S (mp_ping);
12724
12725   W (ret);
12726   return ret;
12727 }
12728
12729 static void vl_api_sw_interface_tap_v2_details_t_handler
12730   (vl_api_sw_interface_tap_v2_details_t * mp)
12731 {
12732   vat_main_t *vam = &vat_main;
12733
12734   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12735                     mp->host_ip4_prefix_len);
12736   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12737                     mp->host_ip6_prefix_len);
12738
12739   print (vam->ofp,
12740          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12741          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12742          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12743          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12744          mp->host_bridge, ip4, ip6);
12745
12746   vec_free (ip4);
12747   vec_free (ip6);
12748 }
12749
12750 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12751   (vl_api_sw_interface_tap_v2_details_t * mp)
12752 {
12753   vat_main_t *vam = &vat_main;
12754   vat_json_node_t *node = NULL;
12755
12756   if (VAT_JSON_ARRAY != vam->json_tree.type)
12757     {
12758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12759       vat_json_init_array (&vam->json_tree);
12760     }
12761   node = vat_json_array_add (&vam->json_tree);
12762
12763   vat_json_init_object (node);
12764   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12765   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12766   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12767   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12768   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12769   vat_json_object_add_string_copy (node, "host_mac_addr",
12770                                    format (0, "%U", format_ethernet_address,
12771                                            &mp->host_mac_addr));
12772   vat_json_object_add_string_copy (node, "host_namespace",
12773                                    mp->host_namespace);
12774   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12775   vat_json_object_add_string_copy (node, "host_ip4_addr",
12776                                    format (0, "%U/%d", format_ip4_address,
12777                                            mp->host_ip4_addr,
12778                                            mp->host_ip4_prefix_len));
12779   vat_json_object_add_string_copy (node, "host_ip6_addr",
12780                                    format (0, "%U/%d", format_ip6_address,
12781                                            mp->host_ip6_addr,
12782                                            mp->host_ip6_prefix_len));
12783
12784 }
12785
12786 static int
12787 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12788 {
12789   vl_api_sw_interface_tap_v2_dump_t *mp;
12790   vl_api_control_ping_t *mp_ping;
12791   int ret;
12792
12793   print (vam->ofp,
12794          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12795          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12796          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12797          "host_ip6_addr");
12798
12799   /* Get list of tap interfaces */
12800   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12801   S (mp);
12802
12803   /* Use a control ping for synchronization */
12804   MPING (CONTROL_PING, mp_ping);
12805   S (mp_ping);
12806
12807   W (ret);
12808   return ret;
12809 }
12810
12811 static int
12812 api_vxlan_offload_rx (vat_main_t * vam)
12813 {
12814   unformat_input_t *line_input = vam->input;
12815   vl_api_vxlan_offload_rx_t *mp;
12816   u32 hw_if_index = ~0, rx_if_index = ~0;
12817   u8 is_add = 1;
12818   int ret;
12819
12820   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12821     {
12822       if (unformat (line_input, "del"))
12823         is_add = 0;
12824       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12825                          &hw_if_index))
12826         ;
12827       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12828         ;
12829       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12830                          &rx_if_index))
12831         ;
12832       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12833         ;
12834       else
12835         {
12836           errmsg ("parse error '%U'", format_unformat_error, line_input);
12837           return -99;
12838         }
12839     }
12840
12841   if (hw_if_index == ~0)
12842     {
12843       errmsg ("no hw interface");
12844       return -99;
12845     }
12846
12847   if (rx_if_index == ~0)
12848     {
12849       errmsg ("no rx tunnel");
12850       return -99;
12851     }
12852
12853   M (VXLAN_OFFLOAD_RX, mp);
12854
12855   mp->hw_if_index = ntohl (hw_if_index);
12856   mp->sw_if_index = ntohl (rx_if_index);
12857   mp->enable = is_add;
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 static uword unformat_vxlan_decap_next
12865   (unformat_input_t * input, va_list * args)
12866 {
12867   u32 *result = va_arg (*args, u32 *);
12868   u32 tmp;
12869
12870   if (unformat (input, "l2"))
12871     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12872   else if (unformat (input, "%d", &tmp))
12873     *result = tmp;
12874   else
12875     return 0;
12876   return 1;
12877 }
12878
12879 static int
12880 api_vxlan_add_del_tunnel (vat_main_t * vam)
12881 {
12882   unformat_input_t *line_input = vam->input;
12883   vl_api_vxlan_add_del_tunnel_t *mp;
12884   ip46_address_t src, dst;
12885   u8 is_add = 1;
12886   u8 ipv4_set = 0, ipv6_set = 0;
12887   u8 src_set = 0;
12888   u8 dst_set = 0;
12889   u8 grp_set = 0;
12890   u32 instance = ~0;
12891   u32 mcast_sw_if_index = ~0;
12892   u32 encap_vrf_id = 0;
12893   u32 decap_next_index = ~0;
12894   u32 vni = 0;
12895   int ret;
12896
12897   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12898   memset (&src, 0, sizeof src);
12899   memset (&dst, 0, sizeof dst);
12900
12901   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12902     {
12903       if (unformat (line_input, "del"))
12904         is_add = 0;
12905       else if (unformat (line_input, "instance %d", &instance))
12906         ;
12907       else
12908         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12909         {
12910           ipv4_set = 1;
12911           src_set = 1;
12912         }
12913       else
12914         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12915         {
12916           ipv4_set = 1;
12917           dst_set = 1;
12918         }
12919       else
12920         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12921         {
12922           ipv6_set = 1;
12923           src_set = 1;
12924         }
12925       else
12926         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12927         {
12928           ipv6_set = 1;
12929           dst_set = 1;
12930         }
12931       else if (unformat (line_input, "group %U %U",
12932                          unformat_ip4_address, &dst.ip4,
12933                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12934         {
12935           grp_set = dst_set = 1;
12936           ipv4_set = 1;
12937         }
12938       else if (unformat (line_input, "group %U",
12939                          unformat_ip4_address, &dst.ip4))
12940         {
12941           grp_set = dst_set = 1;
12942           ipv4_set = 1;
12943         }
12944       else if (unformat (line_input, "group %U %U",
12945                          unformat_ip6_address, &dst.ip6,
12946                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12947         {
12948           grp_set = dst_set = 1;
12949           ipv6_set = 1;
12950         }
12951       else if (unformat (line_input, "group %U",
12952                          unformat_ip6_address, &dst.ip6))
12953         {
12954           grp_set = dst_set = 1;
12955           ipv6_set = 1;
12956         }
12957       else
12958         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12959         ;
12960       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12961         ;
12962       else if (unformat (line_input, "decap-next %U",
12963                          unformat_vxlan_decap_next, &decap_next_index))
12964         ;
12965       else if (unformat (line_input, "vni %d", &vni))
12966         ;
12967       else
12968         {
12969           errmsg ("parse error '%U'", format_unformat_error, line_input);
12970           return -99;
12971         }
12972     }
12973
12974   if (src_set == 0)
12975     {
12976       errmsg ("tunnel src address not specified");
12977       return -99;
12978     }
12979   if (dst_set == 0)
12980     {
12981       errmsg ("tunnel dst address not specified");
12982       return -99;
12983     }
12984
12985   if (grp_set && !ip46_address_is_multicast (&dst))
12986     {
12987       errmsg ("tunnel group address not multicast");
12988       return -99;
12989     }
12990   if (grp_set && mcast_sw_if_index == ~0)
12991     {
12992       errmsg ("tunnel nonexistent multicast device");
12993       return -99;
12994     }
12995   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12996     {
12997       errmsg ("tunnel dst address must be unicast");
12998       return -99;
12999     }
13000
13001
13002   if (ipv4_set && ipv6_set)
13003     {
13004       errmsg ("both IPv4 and IPv6 addresses specified");
13005       return -99;
13006     }
13007
13008   if ((vni == 0) || (vni >> 24))
13009     {
13010       errmsg ("vni not specified or out of range");
13011       return -99;
13012     }
13013
13014   M (VXLAN_ADD_DEL_TUNNEL, mp);
13015
13016   if (ipv6_set)
13017     {
13018       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13019       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13020     }
13021   else
13022     {
13023       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13024       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13025     }
13026
13027   mp->instance = htonl (instance);
13028   mp->encap_vrf_id = ntohl (encap_vrf_id);
13029   mp->decap_next_index = ntohl (decap_next_index);
13030   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13031   mp->vni = ntohl (vni);
13032   mp->is_add = is_add;
13033   mp->is_ipv6 = ipv6_set;
13034
13035   S (mp);
13036   W (ret);
13037   return ret;
13038 }
13039
13040 static void vl_api_vxlan_tunnel_details_t_handler
13041   (vl_api_vxlan_tunnel_details_t * mp)
13042 {
13043   vat_main_t *vam = &vat_main;
13044   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13045   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13046
13047   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13048          ntohl (mp->sw_if_index),
13049          ntohl (mp->instance),
13050          format_ip46_address, &src, IP46_TYPE_ANY,
13051          format_ip46_address, &dst, IP46_TYPE_ANY,
13052          ntohl (mp->encap_vrf_id),
13053          ntohl (mp->decap_next_index), ntohl (mp->vni),
13054          ntohl (mp->mcast_sw_if_index));
13055 }
13056
13057 static void vl_api_vxlan_tunnel_details_t_handler_json
13058   (vl_api_vxlan_tunnel_details_t * mp)
13059 {
13060   vat_main_t *vam = &vat_main;
13061   vat_json_node_t *node = NULL;
13062
13063   if (VAT_JSON_ARRAY != vam->json_tree.type)
13064     {
13065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13066       vat_json_init_array (&vam->json_tree);
13067     }
13068   node = vat_json_array_add (&vam->json_tree);
13069
13070   vat_json_init_object (node);
13071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13072
13073   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13074
13075   if (mp->is_ipv6)
13076     {
13077       struct in6_addr ip6;
13078
13079       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13080       vat_json_object_add_ip6 (node, "src_address", ip6);
13081       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13082       vat_json_object_add_ip6 (node, "dst_address", ip6);
13083     }
13084   else
13085     {
13086       struct in_addr ip4;
13087
13088       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13089       vat_json_object_add_ip4 (node, "src_address", ip4);
13090       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13091       vat_json_object_add_ip4 (node, "dst_address", ip4);
13092     }
13093   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13094   vat_json_object_add_uint (node, "decap_next_index",
13095                             ntohl (mp->decap_next_index));
13096   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13097   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13098   vat_json_object_add_uint (node, "mcast_sw_if_index",
13099                             ntohl (mp->mcast_sw_if_index));
13100 }
13101
13102 static int
13103 api_vxlan_tunnel_dump (vat_main_t * vam)
13104 {
13105   unformat_input_t *i = vam->input;
13106   vl_api_vxlan_tunnel_dump_t *mp;
13107   vl_api_control_ping_t *mp_ping;
13108   u32 sw_if_index;
13109   u8 sw_if_index_set = 0;
13110   int ret;
13111
13112   /* Parse args required to build the message */
13113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13114     {
13115       if (unformat (i, "sw_if_index %d", &sw_if_index))
13116         sw_if_index_set = 1;
13117       else
13118         break;
13119     }
13120
13121   if (sw_if_index_set == 0)
13122     {
13123       sw_if_index = ~0;
13124     }
13125
13126   if (!vam->json_output)
13127     {
13128       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13129              "sw_if_index", "instance", "src_address", "dst_address",
13130              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13131     }
13132
13133   /* Get list of vxlan-tunnel interfaces */
13134   M (VXLAN_TUNNEL_DUMP, mp);
13135
13136   mp->sw_if_index = htonl (sw_if_index);
13137
13138   S (mp);
13139
13140   /* Use a control ping for synchronization */
13141   MPING (CONTROL_PING, mp_ping);
13142   S (mp_ping);
13143
13144   W (ret);
13145   return ret;
13146 }
13147
13148 static uword unformat_geneve_decap_next
13149   (unformat_input_t * input, va_list * args)
13150 {
13151   u32 *result = va_arg (*args, u32 *);
13152   u32 tmp;
13153
13154   if (unformat (input, "l2"))
13155     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13156   else if (unformat (input, "%d", &tmp))
13157     *result = tmp;
13158   else
13159     return 0;
13160   return 1;
13161 }
13162
13163 static int
13164 api_geneve_add_del_tunnel (vat_main_t * vam)
13165 {
13166   unformat_input_t *line_input = vam->input;
13167   vl_api_geneve_add_del_tunnel_t *mp;
13168   ip46_address_t src, dst;
13169   u8 is_add = 1;
13170   u8 ipv4_set = 0, ipv6_set = 0;
13171   u8 src_set = 0;
13172   u8 dst_set = 0;
13173   u8 grp_set = 0;
13174   u32 mcast_sw_if_index = ~0;
13175   u32 encap_vrf_id = 0;
13176   u32 decap_next_index = ~0;
13177   u32 vni = 0;
13178   int ret;
13179
13180   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13181   memset (&src, 0, sizeof src);
13182   memset (&dst, 0, sizeof dst);
13183
13184   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13185     {
13186       if (unformat (line_input, "del"))
13187         is_add = 0;
13188       else
13189         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13190         {
13191           ipv4_set = 1;
13192           src_set = 1;
13193         }
13194       else
13195         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13196         {
13197           ipv4_set = 1;
13198           dst_set = 1;
13199         }
13200       else
13201         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13202         {
13203           ipv6_set = 1;
13204           src_set = 1;
13205         }
13206       else
13207         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13208         {
13209           ipv6_set = 1;
13210           dst_set = 1;
13211         }
13212       else if (unformat (line_input, "group %U %U",
13213                          unformat_ip4_address, &dst.ip4,
13214                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13215         {
13216           grp_set = dst_set = 1;
13217           ipv4_set = 1;
13218         }
13219       else if (unformat (line_input, "group %U",
13220                          unformat_ip4_address, &dst.ip4))
13221         {
13222           grp_set = dst_set = 1;
13223           ipv4_set = 1;
13224         }
13225       else if (unformat (line_input, "group %U %U",
13226                          unformat_ip6_address, &dst.ip6,
13227                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13228         {
13229           grp_set = dst_set = 1;
13230           ipv6_set = 1;
13231         }
13232       else if (unformat (line_input, "group %U",
13233                          unformat_ip6_address, &dst.ip6))
13234         {
13235           grp_set = dst_set = 1;
13236           ipv6_set = 1;
13237         }
13238       else
13239         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13240         ;
13241       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13242         ;
13243       else if (unformat (line_input, "decap-next %U",
13244                          unformat_geneve_decap_next, &decap_next_index))
13245         ;
13246       else if (unformat (line_input, "vni %d", &vni))
13247         ;
13248       else
13249         {
13250           errmsg ("parse error '%U'", format_unformat_error, line_input);
13251           return -99;
13252         }
13253     }
13254
13255   if (src_set == 0)
13256     {
13257       errmsg ("tunnel src address not specified");
13258       return -99;
13259     }
13260   if (dst_set == 0)
13261     {
13262       errmsg ("tunnel dst address not specified");
13263       return -99;
13264     }
13265
13266   if (grp_set && !ip46_address_is_multicast (&dst))
13267     {
13268       errmsg ("tunnel group address not multicast");
13269       return -99;
13270     }
13271   if (grp_set && mcast_sw_if_index == ~0)
13272     {
13273       errmsg ("tunnel nonexistent multicast device");
13274       return -99;
13275     }
13276   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13277     {
13278       errmsg ("tunnel dst address must be unicast");
13279       return -99;
13280     }
13281
13282
13283   if (ipv4_set && ipv6_set)
13284     {
13285       errmsg ("both IPv4 and IPv6 addresses specified");
13286       return -99;
13287     }
13288
13289   if ((vni == 0) || (vni >> 24))
13290     {
13291       errmsg ("vni not specified or out of range");
13292       return -99;
13293     }
13294
13295   M (GENEVE_ADD_DEL_TUNNEL, mp);
13296
13297   if (ipv6_set)
13298     {
13299       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13300       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13301     }
13302   else
13303     {
13304       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13305       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13306     }
13307   mp->encap_vrf_id = ntohl (encap_vrf_id);
13308   mp->decap_next_index = ntohl (decap_next_index);
13309   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13310   mp->vni = ntohl (vni);
13311   mp->is_add = is_add;
13312   mp->is_ipv6 = ipv6_set;
13313
13314   S (mp);
13315   W (ret);
13316   return ret;
13317 }
13318
13319 static void vl_api_geneve_tunnel_details_t_handler
13320   (vl_api_geneve_tunnel_details_t * mp)
13321 {
13322   vat_main_t *vam = &vat_main;
13323   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13324   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13325
13326   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13327          ntohl (mp->sw_if_index),
13328          format_ip46_address, &src, IP46_TYPE_ANY,
13329          format_ip46_address, &dst, IP46_TYPE_ANY,
13330          ntohl (mp->encap_vrf_id),
13331          ntohl (mp->decap_next_index), ntohl (mp->vni),
13332          ntohl (mp->mcast_sw_if_index));
13333 }
13334
13335 static void vl_api_geneve_tunnel_details_t_handler_json
13336   (vl_api_geneve_tunnel_details_t * mp)
13337 {
13338   vat_main_t *vam = &vat_main;
13339   vat_json_node_t *node = NULL;
13340
13341   if (VAT_JSON_ARRAY != vam->json_tree.type)
13342     {
13343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13344       vat_json_init_array (&vam->json_tree);
13345     }
13346   node = vat_json_array_add (&vam->json_tree);
13347
13348   vat_json_init_object (node);
13349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13350   if (mp->is_ipv6)
13351     {
13352       struct in6_addr ip6;
13353
13354       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13355       vat_json_object_add_ip6 (node, "src_address", ip6);
13356       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13357       vat_json_object_add_ip6 (node, "dst_address", ip6);
13358     }
13359   else
13360     {
13361       struct in_addr ip4;
13362
13363       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13364       vat_json_object_add_ip4 (node, "src_address", ip4);
13365       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13366       vat_json_object_add_ip4 (node, "dst_address", ip4);
13367     }
13368   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13369   vat_json_object_add_uint (node, "decap_next_index",
13370                             ntohl (mp->decap_next_index));
13371   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13372   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13373   vat_json_object_add_uint (node, "mcast_sw_if_index",
13374                             ntohl (mp->mcast_sw_if_index));
13375 }
13376
13377 static int
13378 api_geneve_tunnel_dump (vat_main_t * vam)
13379 {
13380   unformat_input_t *i = vam->input;
13381   vl_api_geneve_tunnel_dump_t *mp;
13382   vl_api_control_ping_t *mp_ping;
13383   u32 sw_if_index;
13384   u8 sw_if_index_set = 0;
13385   int ret;
13386
13387   /* Parse args required to build the message */
13388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (i, "sw_if_index %d", &sw_if_index))
13391         sw_if_index_set = 1;
13392       else
13393         break;
13394     }
13395
13396   if (sw_if_index_set == 0)
13397     {
13398       sw_if_index = ~0;
13399     }
13400
13401   if (!vam->json_output)
13402     {
13403       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13404              "sw_if_index", "local_address", "remote_address",
13405              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13406     }
13407
13408   /* Get list of geneve-tunnel interfaces */
13409   M (GENEVE_TUNNEL_DUMP, mp);
13410
13411   mp->sw_if_index = htonl (sw_if_index);
13412
13413   S (mp);
13414
13415   /* Use a control ping for synchronization */
13416   M (CONTROL_PING, mp_ping);
13417   S (mp_ping);
13418
13419   W (ret);
13420   return ret;
13421 }
13422
13423 static int
13424 api_gre_add_del_tunnel (vat_main_t * vam)
13425 {
13426   unformat_input_t *line_input = vam->input;
13427   vl_api_gre_add_del_tunnel_t *mp;
13428   ip4_address_t src4, dst4;
13429   ip6_address_t src6, dst6;
13430   u8 is_add = 1;
13431   u8 ipv4_set = 0;
13432   u8 ipv6_set = 0;
13433   u8 t_type = GRE_TUNNEL_TYPE_L3;
13434   u8 src_set = 0;
13435   u8 dst_set = 0;
13436   u32 outer_fib_id = 0;
13437   u32 session_id = 0;
13438   u32 instance = ~0;
13439   int ret;
13440
13441   memset (&src4, 0, sizeof src4);
13442   memset (&dst4, 0, sizeof dst4);
13443   memset (&src6, 0, sizeof src6);
13444   memset (&dst6, 0, sizeof dst6);
13445
13446   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13447     {
13448       if (unformat (line_input, "del"))
13449         is_add = 0;
13450       else if (unformat (line_input, "instance %d", &instance))
13451         ;
13452       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13453         {
13454           src_set = 1;
13455           ipv4_set = 1;
13456         }
13457       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13458         {
13459           dst_set = 1;
13460           ipv4_set = 1;
13461         }
13462       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13463         {
13464           src_set = 1;
13465           ipv6_set = 1;
13466         }
13467       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13468         {
13469           dst_set = 1;
13470           ipv6_set = 1;
13471         }
13472       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13473         ;
13474       else if (unformat (line_input, "teb"))
13475         t_type = GRE_TUNNEL_TYPE_TEB;
13476       else if (unformat (line_input, "erspan %d", &session_id))
13477         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13478       else
13479         {
13480           errmsg ("parse error '%U'", format_unformat_error, line_input);
13481           return -99;
13482         }
13483     }
13484
13485   if (src_set == 0)
13486     {
13487       errmsg ("tunnel src address not specified");
13488       return -99;
13489     }
13490   if (dst_set == 0)
13491     {
13492       errmsg ("tunnel dst address not specified");
13493       return -99;
13494     }
13495   if (ipv4_set && ipv6_set)
13496     {
13497       errmsg ("both IPv4 and IPv6 addresses specified");
13498       return -99;
13499     }
13500
13501
13502   M (GRE_ADD_DEL_TUNNEL, mp);
13503
13504   if (ipv4_set)
13505     {
13506       clib_memcpy (&mp->src_address, &src4, 4);
13507       clib_memcpy (&mp->dst_address, &dst4, 4);
13508     }
13509   else
13510     {
13511       clib_memcpy (&mp->src_address, &src6, 16);
13512       clib_memcpy (&mp->dst_address, &dst6, 16);
13513     }
13514   mp->instance = htonl (instance);
13515   mp->outer_fib_id = htonl (outer_fib_id);
13516   mp->is_add = is_add;
13517   mp->session_id = htons ((u16) session_id);
13518   mp->tunnel_type = t_type;
13519   mp->is_ipv6 = ipv6_set;
13520
13521   S (mp);
13522   W (ret);
13523   return ret;
13524 }
13525
13526 static void vl_api_gre_tunnel_details_t_handler
13527   (vl_api_gre_tunnel_details_t * mp)
13528 {
13529   vat_main_t *vam = &vat_main;
13530   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13531   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13532
13533   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13534          ntohl (mp->sw_if_index),
13535          ntohl (mp->instance),
13536          format_ip46_address, &src, IP46_TYPE_ANY,
13537          format_ip46_address, &dst, IP46_TYPE_ANY,
13538          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13539 }
13540
13541 static void vl_api_gre_tunnel_details_t_handler_json
13542   (vl_api_gre_tunnel_details_t * mp)
13543 {
13544   vat_main_t *vam = &vat_main;
13545   vat_json_node_t *node = NULL;
13546   struct in_addr ip4;
13547   struct in6_addr ip6;
13548
13549   if (VAT_JSON_ARRAY != vam->json_tree.type)
13550     {
13551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13552       vat_json_init_array (&vam->json_tree);
13553     }
13554   node = vat_json_array_add (&vam->json_tree);
13555
13556   vat_json_init_object (node);
13557   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13558   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13559   if (!mp->is_ipv6)
13560     {
13561       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13562       vat_json_object_add_ip4 (node, "src_address", ip4);
13563       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13564       vat_json_object_add_ip4 (node, "dst_address", ip4);
13565     }
13566   else
13567     {
13568       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13569       vat_json_object_add_ip6 (node, "src_address", ip6);
13570       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13571       vat_json_object_add_ip6 (node, "dst_address", ip6);
13572     }
13573   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13574   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13575   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13576   vat_json_object_add_uint (node, "session_id", mp->session_id);
13577 }
13578
13579 static int
13580 api_gre_tunnel_dump (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_gre_tunnel_dump_t *mp;
13584   vl_api_control_ping_t *mp_ping;
13585   u32 sw_if_index;
13586   u8 sw_if_index_set = 0;
13587   int ret;
13588
13589   /* Parse args required to build the message */
13590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13591     {
13592       if (unformat (i, "sw_if_index %d", &sw_if_index))
13593         sw_if_index_set = 1;
13594       else
13595         break;
13596     }
13597
13598   if (sw_if_index_set == 0)
13599     {
13600       sw_if_index = ~0;
13601     }
13602
13603   if (!vam->json_output)
13604     {
13605       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13606              "sw_if_index", "instance", "src_address", "dst_address",
13607              "tunnel_type", "outer_fib_id", "session_id");
13608     }
13609
13610   /* Get list of gre-tunnel interfaces */
13611   M (GRE_TUNNEL_DUMP, mp);
13612
13613   mp->sw_if_index = htonl (sw_if_index);
13614
13615   S (mp);
13616
13617   /* Use a control ping for synchronization */
13618   MPING (CONTROL_PING, mp_ping);
13619   S (mp_ping);
13620
13621   W (ret);
13622   return ret;
13623 }
13624
13625 static int
13626 api_l2_fib_clear_table (vat_main_t * vam)
13627 {
13628 //  unformat_input_t * i = vam->input;
13629   vl_api_l2_fib_clear_table_t *mp;
13630   int ret;
13631
13632   M (L2_FIB_CLEAR_TABLE, mp);
13633
13634   S (mp);
13635   W (ret);
13636   return ret;
13637 }
13638
13639 static int
13640 api_l2_interface_efp_filter (vat_main_t * vam)
13641 {
13642   unformat_input_t *i = vam->input;
13643   vl_api_l2_interface_efp_filter_t *mp;
13644   u32 sw_if_index;
13645   u8 enable = 1;
13646   u8 sw_if_index_set = 0;
13647   int ret;
13648
13649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13650     {
13651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13652         sw_if_index_set = 1;
13653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13654         sw_if_index_set = 1;
13655       else if (unformat (i, "enable"))
13656         enable = 1;
13657       else if (unformat (i, "disable"))
13658         enable = 0;
13659       else
13660         {
13661           clib_warning ("parse error '%U'", format_unformat_error, i);
13662           return -99;
13663         }
13664     }
13665
13666   if (sw_if_index_set == 0)
13667     {
13668       errmsg ("missing sw_if_index");
13669       return -99;
13670     }
13671
13672   M (L2_INTERFACE_EFP_FILTER, mp);
13673
13674   mp->sw_if_index = ntohl (sw_if_index);
13675   mp->enable_disable = enable;
13676
13677   S (mp);
13678   W (ret);
13679   return ret;
13680 }
13681
13682 #define foreach_vtr_op                          \
13683 _("disable",  L2_VTR_DISABLED)                  \
13684 _("push-1",  L2_VTR_PUSH_1)                     \
13685 _("push-2",  L2_VTR_PUSH_2)                     \
13686 _("pop-1",  L2_VTR_POP_1)                       \
13687 _("pop-2",  L2_VTR_POP_2)                       \
13688 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13689 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13690 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13691 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13692
13693 static int
13694 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13695 {
13696   unformat_input_t *i = vam->input;
13697   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13698   u32 sw_if_index;
13699   u8 sw_if_index_set = 0;
13700   u8 vtr_op_set = 0;
13701   u32 vtr_op = 0;
13702   u32 push_dot1q = 1;
13703   u32 tag1 = ~0;
13704   u32 tag2 = ~0;
13705   int ret;
13706
13707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13708     {
13709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13710         sw_if_index_set = 1;
13711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13712         sw_if_index_set = 1;
13713       else if (unformat (i, "vtr_op %d", &vtr_op))
13714         vtr_op_set = 1;
13715 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13716       foreach_vtr_op
13717 #undef _
13718         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13719         ;
13720       else if (unformat (i, "tag1 %d", &tag1))
13721         ;
13722       else if (unformat (i, "tag2 %d", &tag2))
13723         ;
13724       else
13725         {
13726           clib_warning ("parse error '%U'", format_unformat_error, i);
13727           return -99;
13728         }
13729     }
13730
13731   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13732     {
13733       errmsg ("missing vtr operation or sw_if_index");
13734       return -99;
13735     }
13736
13737   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13738   mp->sw_if_index = ntohl (sw_if_index);
13739   mp->vtr_op = ntohl (vtr_op);
13740   mp->push_dot1q = ntohl (push_dot1q);
13741   mp->tag1 = ntohl (tag1);
13742   mp->tag2 = ntohl (tag2);
13743
13744   S (mp);
13745   W (ret);
13746   return ret;
13747 }
13748
13749 static int
13750 api_create_vhost_user_if (vat_main_t * vam)
13751 {
13752   unformat_input_t *i = vam->input;
13753   vl_api_create_vhost_user_if_t *mp;
13754   u8 *file_name;
13755   u8 is_server = 0;
13756   u8 file_name_set = 0;
13757   u32 custom_dev_instance = ~0;
13758   u8 hwaddr[6];
13759   u8 use_custom_mac = 0;
13760   u8 *tag = 0;
13761   int ret;
13762
13763   /* Shut up coverity */
13764   memset (hwaddr, 0, sizeof (hwaddr));
13765
13766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13767     {
13768       if (unformat (i, "socket %s", &file_name))
13769         {
13770           file_name_set = 1;
13771         }
13772       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13773         ;
13774       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13775         use_custom_mac = 1;
13776       else if (unformat (i, "server"))
13777         is_server = 1;
13778       else if (unformat (i, "tag %s", &tag))
13779         ;
13780       else
13781         break;
13782     }
13783
13784   if (file_name_set == 0)
13785     {
13786       errmsg ("missing socket file name");
13787       return -99;
13788     }
13789
13790   if (vec_len (file_name) > 255)
13791     {
13792       errmsg ("socket file name too long");
13793       return -99;
13794     }
13795   vec_add1 (file_name, 0);
13796
13797   M (CREATE_VHOST_USER_IF, mp);
13798
13799   mp->is_server = is_server;
13800   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13801   vec_free (file_name);
13802   if (custom_dev_instance != ~0)
13803     {
13804       mp->renumber = 1;
13805       mp->custom_dev_instance = ntohl (custom_dev_instance);
13806     }
13807   mp->use_custom_mac = use_custom_mac;
13808   clib_memcpy (mp->mac_address, hwaddr, 6);
13809   if (tag)
13810     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13811   vec_free (tag);
13812
13813   S (mp);
13814   W (ret);
13815   return ret;
13816 }
13817
13818 static int
13819 api_modify_vhost_user_if (vat_main_t * vam)
13820 {
13821   unformat_input_t *i = vam->input;
13822   vl_api_modify_vhost_user_if_t *mp;
13823   u8 *file_name;
13824   u8 is_server = 0;
13825   u8 file_name_set = 0;
13826   u32 custom_dev_instance = ~0;
13827   u8 sw_if_index_set = 0;
13828   u32 sw_if_index = (u32) ~ 0;
13829   int ret;
13830
13831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13834         sw_if_index_set = 1;
13835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13836         sw_if_index_set = 1;
13837       else if (unformat (i, "socket %s", &file_name))
13838         {
13839           file_name_set = 1;
13840         }
13841       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13842         ;
13843       else if (unformat (i, "server"))
13844         is_server = 1;
13845       else
13846         break;
13847     }
13848
13849   if (sw_if_index_set == 0)
13850     {
13851       errmsg ("missing sw_if_index or interface name");
13852       return -99;
13853     }
13854
13855   if (file_name_set == 0)
13856     {
13857       errmsg ("missing socket file name");
13858       return -99;
13859     }
13860
13861   if (vec_len (file_name) > 255)
13862     {
13863       errmsg ("socket file name too long");
13864       return -99;
13865     }
13866   vec_add1 (file_name, 0);
13867
13868   M (MODIFY_VHOST_USER_IF, mp);
13869
13870   mp->sw_if_index = ntohl (sw_if_index);
13871   mp->is_server = is_server;
13872   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13873   vec_free (file_name);
13874   if (custom_dev_instance != ~0)
13875     {
13876       mp->renumber = 1;
13877       mp->custom_dev_instance = ntohl (custom_dev_instance);
13878     }
13879
13880   S (mp);
13881   W (ret);
13882   return ret;
13883 }
13884
13885 static int
13886 api_delete_vhost_user_if (vat_main_t * vam)
13887 {
13888   unformat_input_t *i = vam->input;
13889   vl_api_delete_vhost_user_if_t *mp;
13890   u32 sw_if_index = ~0;
13891   u8 sw_if_index_set = 0;
13892   int ret;
13893
13894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13895     {
13896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13897         sw_if_index_set = 1;
13898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13899         sw_if_index_set = 1;
13900       else
13901         break;
13902     }
13903
13904   if (sw_if_index_set == 0)
13905     {
13906       errmsg ("missing sw_if_index or interface name");
13907       return -99;
13908     }
13909
13910
13911   M (DELETE_VHOST_USER_IF, mp);
13912
13913   mp->sw_if_index = ntohl (sw_if_index);
13914
13915   S (mp);
13916   W (ret);
13917   return ret;
13918 }
13919
13920 static void vl_api_sw_interface_vhost_user_details_t_handler
13921   (vl_api_sw_interface_vhost_user_details_t * mp)
13922 {
13923   vat_main_t *vam = &vat_main;
13924
13925   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13926          (char *) mp->interface_name,
13927          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13928          clib_net_to_host_u64 (mp->features), mp->is_server,
13929          ntohl (mp->num_regions), (char *) mp->sock_filename);
13930   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13931 }
13932
13933 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13934   (vl_api_sw_interface_vhost_user_details_t * mp)
13935 {
13936   vat_main_t *vam = &vat_main;
13937   vat_json_node_t *node = NULL;
13938
13939   if (VAT_JSON_ARRAY != vam->json_tree.type)
13940     {
13941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13942       vat_json_init_array (&vam->json_tree);
13943     }
13944   node = vat_json_array_add (&vam->json_tree);
13945
13946   vat_json_init_object (node);
13947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13948   vat_json_object_add_string_copy (node, "interface_name",
13949                                    mp->interface_name);
13950   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13951                             ntohl (mp->virtio_net_hdr_sz));
13952   vat_json_object_add_uint (node, "features",
13953                             clib_net_to_host_u64 (mp->features));
13954   vat_json_object_add_uint (node, "is_server", mp->is_server);
13955   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13956   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13957   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13958 }
13959
13960 static int
13961 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13962 {
13963   vl_api_sw_interface_vhost_user_dump_t *mp;
13964   vl_api_control_ping_t *mp_ping;
13965   int ret;
13966   print (vam->ofp,
13967          "Interface name            idx hdr_sz features server regions filename");
13968
13969   /* Get list of vhost-user interfaces */
13970   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13971   S (mp);
13972
13973   /* Use a control ping for synchronization */
13974   MPING (CONTROL_PING, mp_ping);
13975   S (mp_ping);
13976
13977   W (ret);
13978   return ret;
13979 }
13980
13981 static int
13982 api_show_version (vat_main_t * vam)
13983 {
13984   vl_api_show_version_t *mp;
13985   int ret;
13986
13987   M (SHOW_VERSION, mp);
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994
13995 static int
13996 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13997 {
13998   unformat_input_t *line_input = vam->input;
13999   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14000   ip4_address_t local4, remote4;
14001   ip6_address_t local6, remote6;
14002   u8 is_add = 1;
14003   u8 ipv4_set = 0, ipv6_set = 0;
14004   u8 local_set = 0;
14005   u8 remote_set = 0;
14006   u8 grp_set = 0;
14007   u32 mcast_sw_if_index = ~0;
14008   u32 encap_vrf_id = 0;
14009   u32 decap_vrf_id = 0;
14010   u8 protocol = ~0;
14011   u32 vni;
14012   u8 vni_set = 0;
14013   int ret;
14014
14015   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14016   memset (&local4, 0, sizeof local4);
14017   memset (&remote4, 0, sizeof remote4);
14018   memset (&local6, 0, sizeof local6);
14019   memset (&remote6, 0, sizeof remote6);
14020
14021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (line_input, "del"))
14024         is_add = 0;
14025       else if (unformat (line_input, "local %U",
14026                          unformat_ip4_address, &local4))
14027         {
14028           local_set = 1;
14029           ipv4_set = 1;
14030         }
14031       else if (unformat (line_input, "remote %U",
14032                          unformat_ip4_address, &remote4))
14033         {
14034           remote_set = 1;
14035           ipv4_set = 1;
14036         }
14037       else if (unformat (line_input, "local %U",
14038                          unformat_ip6_address, &local6))
14039         {
14040           local_set = 1;
14041           ipv6_set = 1;
14042         }
14043       else if (unformat (line_input, "remote %U",
14044                          unformat_ip6_address, &remote6))
14045         {
14046           remote_set = 1;
14047           ipv6_set = 1;
14048         }
14049       else if (unformat (line_input, "group %U %U",
14050                          unformat_ip4_address, &remote4,
14051                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14052         {
14053           grp_set = remote_set = 1;
14054           ipv4_set = 1;
14055         }
14056       else if (unformat (line_input, "group %U",
14057                          unformat_ip4_address, &remote4))
14058         {
14059           grp_set = remote_set = 1;
14060           ipv4_set = 1;
14061         }
14062       else if (unformat (line_input, "group %U %U",
14063                          unformat_ip6_address, &remote6,
14064                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14065         {
14066           grp_set = remote_set = 1;
14067           ipv6_set = 1;
14068         }
14069       else if (unformat (line_input, "group %U",
14070                          unformat_ip6_address, &remote6))
14071         {
14072           grp_set = remote_set = 1;
14073           ipv6_set = 1;
14074         }
14075       else
14076         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14077         ;
14078       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14079         ;
14080       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14081         ;
14082       else if (unformat (line_input, "vni %d", &vni))
14083         vni_set = 1;
14084       else if (unformat (line_input, "next-ip4"))
14085         protocol = 1;
14086       else if (unformat (line_input, "next-ip6"))
14087         protocol = 2;
14088       else if (unformat (line_input, "next-ethernet"))
14089         protocol = 3;
14090       else if (unformat (line_input, "next-nsh"))
14091         protocol = 4;
14092       else
14093         {
14094           errmsg ("parse error '%U'", format_unformat_error, line_input);
14095           return -99;
14096         }
14097     }
14098
14099   if (local_set == 0)
14100     {
14101       errmsg ("tunnel local address not specified");
14102       return -99;
14103     }
14104   if (remote_set == 0)
14105     {
14106       errmsg ("tunnel remote address not specified");
14107       return -99;
14108     }
14109   if (grp_set && mcast_sw_if_index == ~0)
14110     {
14111       errmsg ("tunnel nonexistent multicast device");
14112       return -99;
14113     }
14114   if (ipv4_set && ipv6_set)
14115     {
14116       errmsg ("both IPv4 and IPv6 addresses specified");
14117       return -99;
14118     }
14119
14120   if (vni_set == 0)
14121     {
14122       errmsg ("vni not specified");
14123       return -99;
14124     }
14125
14126   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14127
14128
14129   if (ipv6_set)
14130     {
14131       clib_memcpy (&mp->local, &local6, sizeof (local6));
14132       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14133     }
14134   else
14135     {
14136       clib_memcpy (&mp->local, &local4, sizeof (local4));
14137       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14138     }
14139
14140   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14141   mp->encap_vrf_id = ntohl (encap_vrf_id);
14142   mp->decap_vrf_id = ntohl (decap_vrf_id);
14143   mp->protocol = protocol;
14144   mp->vni = ntohl (vni);
14145   mp->is_add = is_add;
14146   mp->is_ipv6 = ipv6_set;
14147
14148   S (mp);
14149   W (ret);
14150   return ret;
14151 }
14152
14153 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14154   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14155 {
14156   vat_main_t *vam = &vat_main;
14157   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14158   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14159
14160   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14161          ntohl (mp->sw_if_index),
14162          format_ip46_address, &local, IP46_TYPE_ANY,
14163          format_ip46_address, &remote, IP46_TYPE_ANY,
14164          ntohl (mp->vni), mp->protocol,
14165          ntohl (mp->mcast_sw_if_index),
14166          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14167 }
14168
14169
14170 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14171   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14172 {
14173   vat_main_t *vam = &vat_main;
14174   vat_json_node_t *node = NULL;
14175   struct in_addr ip4;
14176   struct in6_addr ip6;
14177
14178   if (VAT_JSON_ARRAY != vam->json_tree.type)
14179     {
14180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14181       vat_json_init_array (&vam->json_tree);
14182     }
14183   node = vat_json_array_add (&vam->json_tree);
14184
14185   vat_json_init_object (node);
14186   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14187   if (mp->is_ipv6)
14188     {
14189       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14190       vat_json_object_add_ip6 (node, "local", ip6);
14191       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14192       vat_json_object_add_ip6 (node, "remote", ip6);
14193     }
14194   else
14195     {
14196       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14197       vat_json_object_add_ip4 (node, "local", ip4);
14198       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14199       vat_json_object_add_ip4 (node, "remote", ip4);
14200     }
14201   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14202   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14203   vat_json_object_add_uint (node, "mcast_sw_if_index",
14204                             ntohl (mp->mcast_sw_if_index));
14205   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14206   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14207   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14208 }
14209
14210 static int
14211 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14215   vl_api_control_ping_t *mp_ping;
14216   u32 sw_if_index;
14217   u8 sw_if_index_set = 0;
14218   int ret;
14219
14220   /* Parse args required to build the message */
14221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (i, "sw_if_index %d", &sw_if_index))
14224         sw_if_index_set = 1;
14225       else
14226         break;
14227     }
14228
14229   if (sw_if_index_set == 0)
14230     {
14231       sw_if_index = ~0;
14232     }
14233
14234   if (!vam->json_output)
14235     {
14236       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14237              "sw_if_index", "local", "remote", "vni",
14238              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14239     }
14240
14241   /* Get list of vxlan-tunnel interfaces */
14242   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14243
14244   mp->sw_if_index = htonl (sw_if_index);
14245
14246   S (mp);
14247
14248   /* Use a control ping for synchronization */
14249   MPING (CONTROL_PING, mp_ping);
14250   S (mp_ping);
14251
14252   W (ret);
14253   return ret;
14254 }
14255
14256 static void vl_api_l2_fib_table_details_t_handler
14257   (vl_api_l2_fib_table_details_t * mp)
14258 {
14259   vat_main_t *vam = &vat_main;
14260
14261   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14262          "       %d       %d     %d",
14263          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14264          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14265          mp->bvi_mac);
14266 }
14267
14268 static void vl_api_l2_fib_table_details_t_handler_json
14269   (vl_api_l2_fib_table_details_t * mp)
14270 {
14271   vat_main_t *vam = &vat_main;
14272   vat_json_node_t *node = NULL;
14273
14274   if (VAT_JSON_ARRAY != vam->json_tree.type)
14275     {
14276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14277       vat_json_init_array (&vam->json_tree);
14278     }
14279   node = vat_json_array_add (&vam->json_tree);
14280
14281   vat_json_init_object (node);
14282   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14283   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14284   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14285   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14286   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14287   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14288 }
14289
14290 static int
14291 api_l2_fib_table_dump (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_l2_fib_table_dump_t *mp;
14295   vl_api_control_ping_t *mp_ping;
14296   u32 bd_id;
14297   u8 bd_id_set = 0;
14298   int ret;
14299
14300   /* Parse args required to build the message */
14301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14302     {
14303       if (unformat (i, "bd_id %d", &bd_id))
14304         bd_id_set = 1;
14305       else
14306         break;
14307     }
14308
14309   if (bd_id_set == 0)
14310     {
14311       errmsg ("missing bridge domain");
14312       return -99;
14313     }
14314
14315   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14316
14317   /* Get list of l2 fib entries */
14318   M (L2_FIB_TABLE_DUMP, mp);
14319
14320   mp->bd_id = ntohl (bd_id);
14321   S (mp);
14322
14323   /* Use a control ping for synchronization */
14324   MPING (CONTROL_PING, mp_ping);
14325   S (mp_ping);
14326
14327   W (ret);
14328   return ret;
14329 }
14330
14331
14332 static int
14333 api_interface_name_renumber (vat_main_t * vam)
14334 {
14335   unformat_input_t *line_input = vam->input;
14336   vl_api_interface_name_renumber_t *mp;
14337   u32 sw_if_index = ~0;
14338   u32 new_show_dev_instance = ~0;
14339   int ret;
14340
14341   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14342     {
14343       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14344                     &sw_if_index))
14345         ;
14346       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14347         ;
14348       else if (unformat (line_input, "new_show_dev_instance %d",
14349                          &new_show_dev_instance))
14350         ;
14351       else
14352         break;
14353     }
14354
14355   if (sw_if_index == ~0)
14356     {
14357       errmsg ("missing interface name or sw_if_index");
14358       return -99;
14359     }
14360
14361   if (new_show_dev_instance == ~0)
14362     {
14363       errmsg ("missing new_show_dev_instance");
14364       return -99;
14365     }
14366
14367   M (INTERFACE_NAME_RENUMBER, mp);
14368
14369   mp->sw_if_index = ntohl (sw_if_index);
14370   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14371
14372   S (mp);
14373   W (ret);
14374   return ret;
14375 }
14376
14377 static int
14378 api_ip_probe_neighbor (vat_main_t * vam)
14379 {
14380   unformat_input_t *i = vam->input;
14381   vl_api_ip_probe_neighbor_t *mp;
14382   u8 int_set = 0;
14383   u8 adr_set = 0;
14384   u8 is_ipv6 = 0;
14385   u8 dst_adr[16];
14386   u32 sw_if_index;
14387   int ret;
14388
14389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14392         int_set = 1;
14393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14394         int_set = 1;
14395       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14396         adr_set = 1;
14397       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14398         {
14399           adr_set = 1;
14400           is_ipv6 = 1;
14401         }
14402       else
14403         break;
14404     }
14405
14406   if (int_set == 0)
14407     {
14408       errmsg ("missing interface");
14409       return -99;
14410     }
14411
14412   if (adr_set == 0)
14413     {
14414       errmsg ("missing addresses");
14415       return -99;
14416     }
14417
14418   M (IP_PROBE_NEIGHBOR, mp);
14419
14420   mp->sw_if_index = ntohl (sw_if_index);
14421   mp->is_ipv6 = is_ipv6;
14422   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14423
14424   S (mp);
14425   W (ret);
14426   return ret;
14427 }
14428
14429 static int
14430 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14431 {
14432   unformat_input_t *i = vam->input;
14433   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14434   u8 mode = IP_SCAN_V46_NEIGHBORS;
14435   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14436   int ret;
14437
14438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (i, "ip4"))
14441         mode = IP_SCAN_V4_NEIGHBORS;
14442       else if (unformat (i, "ip6"))
14443         mode = IP_SCAN_V6_NEIGHBORS;
14444       if (unformat (i, "both"))
14445         mode = IP_SCAN_V46_NEIGHBORS;
14446       else if (unformat (i, "disable"))
14447         mode = IP_SCAN_DISABLED;
14448       else if (unformat (i, "interval %d", &interval))
14449         ;
14450       else if (unformat (i, "max-time %d", &time))
14451         ;
14452       else if (unformat (i, "max-update %d", &update))
14453         ;
14454       else if (unformat (i, "delay %d", &delay))
14455         ;
14456       else if (unformat (i, "stale %d", &stale))
14457         ;
14458       else
14459         break;
14460     }
14461
14462   if (interval > 255)
14463     {
14464       errmsg ("interval cannot exceed 255 minutes.");
14465       return -99;
14466     }
14467   if (time > 255)
14468     {
14469       errmsg ("max-time cannot exceed 255 usec.");
14470       return -99;
14471     }
14472   if (update > 255)
14473     {
14474       errmsg ("max-update cannot exceed 255.");
14475       return -99;
14476     }
14477   if (delay > 255)
14478     {
14479       errmsg ("delay cannot exceed 255 msec.");
14480       return -99;
14481     }
14482   if (stale > 255)
14483     {
14484       errmsg ("stale cannot exceed 255 minutes.");
14485       return -99;
14486     }
14487
14488   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14489   mp->mode = mode;
14490   mp->scan_interval = interval;
14491   mp->max_proc_time = time;
14492   mp->max_update = update;
14493   mp->scan_int_delay = delay;
14494   mp->stale_threshold = stale;
14495
14496   S (mp);
14497   W (ret);
14498   return ret;
14499 }
14500
14501 static int
14502 api_want_ip4_arp_events (vat_main_t * vam)
14503 {
14504   unformat_input_t *line_input = vam->input;
14505   vl_api_want_ip4_arp_events_t *mp;
14506   ip4_address_t address;
14507   int address_set = 0;
14508   u32 enable_disable = 1;
14509   int ret;
14510
14511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14512     {
14513       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14514         address_set = 1;
14515       else if (unformat (line_input, "del"))
14516         enable_disable = 0;
14517       else
14518         break;
14519     }
14520
14521   if (address_set == 0)
14522     {
14523       errmsg ("missing addresses");
14524       return -99;
14525     }
14526
14527   M (WANT_IP4_ARP_EVENTS, mp);
14528   mp->enable_disable = enable_disable;
14529   mp->pid = htonl (getpid ());
14530   mp->address = address.as_u32;
14531
14532   S (mp);
14533   W (ret);
14534   return ret;
14535 }
14536
14537 static int
14538 api_want_ip6_nd_events (vat_main_t * vam)
14539 {
14540   unformat_input_t *line_input = vam->input;
14541   vl_api_want_ip6_nd_events_t *mp;
14542   ip6_address_t address;
14543   int address_set = 0;
14544   u32 enable_disable = 1;
14545   int ret;
14546
14547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14548     {
14549       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14550         address_set = 1;
14551       else if (unformat (line_input, "del"))
14552         enable_disable = 0;
14553       else
14554         break;
14555     }
14556
14557   if (address_set == 0)
14558     {
14559       errmsg ("missing addresses");
14560       return -99;
14561     }
14562
14563   M (WANT_IP6_ND_EVENTS, mp);
14564   mp->enable_disable = enable_disable;
14565   mp->pid = htonl (getpid ());
14566   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14567
14568   S (mp);
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static int
14574 api_want_l2_macs_events (vat_main_t * vam)
14575 {
14576   unformat_input_t *line_input = vam->input;
14577   vl_api_want_l2_macs_events_t *mp;
14578   u8 enable_disable = 1;
14579   u32 scan_delay = 0;
14580   u32 max_macs_in_event = 0;
14581   u32 learn_limit = 0;
14582   int ret;
14583
14584   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat (line_input, "learn-limit %d", &learn_limit))
14587         ;
14588       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14589         ;
14590       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14591         ;
14592       else if (unformat (line_input, "disable"))
14593         enable_disable = 0;
14594       else
14595         break;
14596     }
14597
14598   M (WANT_L2_MACS_EVENTS, mp);
14599   mp->enable_disable = enable_disable;
14600   mp->pid = htonl (getpid ());
14601   mp->learn_limit = htonl (learn_limit);
14602   mp->scan_delay = (u8) scan_delay;
14603   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14604   S (mp);
14605   W (ret);
14606   return ret;
14607 }
14608
14609 static int
14610 api_input_acl_set_interface (vat_main_t * vam)
14611 {
14612   unformat_input_t *i = vam->input;
14613   vl_api_input_acl_set_interface_t *mp;
14614   u32 sw_if_index;
14615   int sw_if_index_set;
14616   u32 ip4_table_index = ~0;
14617   u32 ip6_table_index = ~0;
14618   u32 l2_table_index = ~0;
14619   u8 is_add = 1;
14620   int ret;
14621
14622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14625         sw_if_index_set = 1;
14626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14627         sw_if_index_set = 1;
14628       else if (unformat (i, "del"))
14629         is_add = 0;
14630       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14631         ;
14632       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14633         ;
14634       else if (unformat (i, "l2-table %d", &l2_table_index))
14635         ;
14636       else
14637         {
14638           clib_warning ("parse error '%U'", format_unformat_error, i);
14639           return -99;
14640         }
14641     }
14642
14643   if (sw_if_index_set == 0)
14644     {
14645       errmsg ("missing interface name or sw_if_index");
14646       return -99;
14647     }
14648
14649   M (INPUT_ACL_SET_INTERFACE, mp);
14650
14651   mp->sw_if_index = ntohl (sw_if_index);
14652   mp->ip4_table_index = ntohl (ip4_table_index);
14653   mp->ip6_table_index = ntohl (ip6_table_index);
14654   mp->l2_table_index = ntohl (l2_table_index);
14655   mp->is_add = is_add;
14656
14657   S (mp);
14658   W (ret);
14659   return ret;
14660 }
14661
14662 static int
14663 api_output_acl_set_interface (vat_main_t * vam)
14664 {
14665   unformat_input_t *i = vam->input;
14666   vl_api_output_acl_set_interface_t *mp;
14667   u32 sw_if_index;
14668   int sw_if_index_set;
14669   u32 ip4_table_index = ~0;
14670   u32 ip6_table_index = ~0;
14671   u32 l2_table_index = ~0;
14672   u8 is_add = 1;
14673   int ret;
14674
14675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14676     {
14677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14678         sw_if_index_set = 1;
14679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14680         sw_if_index_set = 1;
14681       else if (unformat (i, "del"))
14682         is_add = 0;
14683       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14684         ;
14685       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14686         ;
14687       else if (unformat (i, "l2-table %d", &l2_table_index))
14688         ;
14689       else
14690         {
14691           clib_warning ("parse error '%U'", format_unformat_error, i);
14692           return -99;
14693         }
14694     }
14695
14696   if (sw_if_index_set == 0)
14697     {
14698       errmsg ("missing interface name or sw_if_index");
14699       return -99;
14700     }
14701
14702   M (OUTPUT_ACL_SET_INTERFACE, mp);
14703
14704   mp->sw_if_index = ntohl (sw_if_index);
14705   mp->ip4_table_index = ntohl (ip4_table_index);
14706   mp->ip6_table_index = ntohl (ip6_table_index);
14707   mp->l2_table_index = ntohl (l2_table_index);
14708   mp->is_add = is_add;
14709
14710   S (mp);
14711   W (ret);
14712   return ret;
14713 }
14714
14715 static int
14716 api_ip_address_dump (vat_main_t * vam)
14717 {
14718   unformat_input_t *i = vam->input;
14719   vl_api_ip_address_dump_t *mp;
14720   vl_api_control_ping_t *mp_ping;
14721   u32 sw_if_index = ~0;
14722   u8 sw_if_index_set = 0;
14723   u8 ipv4_set = 0;
14724   u8 ipv6_set = 0;
14725   int ret;
14726
14727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14728     {
14729       if (unformat (i, "sw_if_index %d", &sw_if_index))
14730         sw_if_index_set = 1;
14731       else
14732         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14733         sw_if_index_set = 1;
14734       else if (unformat (i, "ipv4"))
14735         ipv4_set = 1;
14736       else if (unformat (i, "ipv6"))
14737         ipv6_set = 1;
14738       else
14739         break;
14740     }
14741
14742   if (ipv4_set && ipv6_set)
14743     {
14744       errmsg ("ipv4 and ipv6 flags cannot be both set");
14745       return -99;
14746     }
14747
14748   if ((!ipv4_set) && (!ipv6_set))
14749     {
14750       errmsg ("no ipv4 nor ipv6 flag set");
14751       return -99;
14752     }
14753
14754   if (sw_if_index_set == 0)
14755     {
14756       errmsg ("missing interface name or sw_if_index");
14757       return -99;
14758     }
14759
14760   vam->current_sw_if_index = sw_if_index;
14761   vam->is_ipv6 = ipv6_set;
14762
14763   M (IP_ADDRESS_DUMP, mp);
14764   mp->sw_if_index = ntohl (sw_if_index);
14765   mp->is_ipv6 = ipv6_set;
14766   S (mp);
14767
14768   /* Use a control ping for synchronization */
14769   MPING (CONTROL_PING, mp_ping);
14770   S (mp_ping);
14771
14772   W (ret);
14773   return ret;
14774 }
14775
14776 static int
14777 api_ip_dump (vat_main_t * vam)
14778 {
14779   vl_api_ip_dump_t *mp;
14780   vl_api_control_ping_t *mp_ping;
14781   unformat_input_t *in = vam->input;
14782   int ipv4_set = 0;
14783   int ipv6_set = 0;
14784   int is_ipv6;
14785   int i;
14786   int ret;
14787
14788   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14789     {
14790       if (unformat (in, "ipv4"))
14791         ipv4_set = 1;
14792       else if (unformat (in, "ipv6"))
14793         ipv6_set = 1;
14794       else
14795         break;
14796     }
14797
14798   if (ipv4_set && ipv6_set)
14799     {
14800       errmsg ("ipv4 and ipv6 flags cannot be both set");
14801       return -99;
14802     }
14803
14804   if ((!ipv4_set) && (!ipv6_set))
14805     {
14806       errmsg ("no ipv4 nor ipv6 flag set");
14807       return -99;
14808     }
14809
14810   is_ipv6 = ipv6_set;
14811   vam->is_ipv6 = is_ipv6;
14812
14813   /* free old data */
14814   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14815     {
14816       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14817     }
14818   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14819
14820   M (IP_DUMP, mp);
14821   mp->is_ipv6 = ipv6_set;
14822   S (mp);
14823
14824   /* Use a control ping for synchronization */
14825   MPING (CONTROL_PING, mp_ping);
14826   S (mp_ping);
14827
14828   W (ret);
14829   return ret;
14830 }
14831
14832 static int
14833 api_ipsec_spd_add_del (vat_main_t * vam)
14834 {
14835   unformat_input_t *i = vam->input;
14836   vl_api_ipsec_spd_add_del_t *mp;
14837   u32 spd_id = ~0;
14838   u8 is_add = 1;
14839   int ret;
14840
14841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (i, "spd_id %d", &spd_id))
14844         ;
14845       else if (unformat (i, "del"))
14846         is_add = 0;
14847       else
14848         {
14849           clib_warning ("parse error '%U'", format_unformat_error, i);
14850           return -99;
14851         }
14852     }
14853   if (spd_id == ~0)
14854     {
14855       errmsg ("spd_id must be set");
14856       return -99;
14857     }
14858
14859   M (IPSEC_SPD_ADD_DEL, mp);
14860
14861   mp->spd_id = ntohl (spd_id);
14862   mp->is_add = is_add;
14863
14864   S (mp);
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14871 {
14872   unformat_input_t *i = vam->input;
14873   vl_api_ipsec_interface_add_del_spd_t *mp;
14874   u32 sw_if_index;
14875   u8 sw_if_index_set = 0;
14876   u32 spd_id = (u32) ~ 0;
14877   u8 is_add = 1;
14878   int ret;
14879
14880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (i, "del"))
14883         is_add = 0;
14884       else if (unformat (i, "spd_id %d", &spd_id))
14885         ;
14886       else
14887         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14888         sw_if_index_set = 1;
14889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14890         sw_if_index_set = 1;
14891       else
14892         {
14893           clib_warning ("parse error '%U'", format_unformat_error, i);
14894           return -99;
14895         }
14896
14897     }
14898
14899   if (spd_id == (u32) ~ 0)
14900     {
14901       errmsg ("spd_id must be set");
14902       return -99;
14903     }
14904
14905   if (sw_if_index_set == 0)
14906     {
14907       errmsg ("missing interface name or sw_if_index");
14908       return -99;
14909     }
14910
14911   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14912
14913   mp->spd_id = ntohl (spd_id);
14914   mp->sw_if_index = ntohl (sw_if_index);
14915   mp->is_add = is_add;
14916
14917   S (mp);
14918   W (ret);
14919   return ret;
14920 }
14921
14922 static int
14923 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14924 {
14925   unformat_input_t *i = vam->input;
14926   vl_api_ipsec_spd_add_del_entry_t *mp;
14927   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14928   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14929   i32 priority = 0;
14930   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14931   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14932   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14933   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14934   int ret;
14935
14936   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14937   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14938   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14939   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14940   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14941   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14942
14943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14944     {
14945       if (unformat (i, "del"))
14946         is_add = 0;
14947       if (unformat (i, "outbound"))
14948         is_outbound = 1;
14949       if (unformat (i, "inbound"))
14950         is_outbound = 0;
14951       else if (unformat (i, "spd_id %d", &spd_id))
14952         ;
14953       else if (unformat (i, "sa_id %d", &sa_id))
14954         ;
14955       else if (unformat (i, "priority %d", &priority))
14956         ;
14957       else if (unformat (i, "protocol %d", &protocol))
14958         ;
14959       else if (unformat (i, "lport_start %d", &lport_start))
14960         ;
14961       else if (unformat (i, "lport_stop %d", &lport_stop))
14962         ;
14963       else if (unformat (i, "rport_start %d", &rport_start))
14964         ;
14965       else if (unformat (i, "rport_stop %d", &rport_stop))
14966         ;
14967       else
14968         if (unformat
14969             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14970         {
14971           is_ipv6 = 0;
14972           is_ip_any = 0;
14973         }
14974       else
14975         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14976         {
14977           is_ipv6 = 0;
14978           is_ip_any = 0;
14979         }
14980       else
14981         if (unformat
14982             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14983         {
14984           is_ipv6 = 0;
14985           is_ip_any = 0;
14986         }
14987       else
14988         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14989         {
14990           is_ipv6 = 0;
14991           is_ip_any = 0;
14992         }
14993       else
14994         if (unformat
14995             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14996         {
14997           is_ipv6 = 1;
14998           is_ip_any = 0;
14999         }
15000       else
15001         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15002         {
15003           is_ipv6 = 1;
15004           is_ip_any = 0;
15005         }
15006       else
15007         if (unformat
15008             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15009         {
15010           is_ipv6 = 1;
15011           is_ip_any = 0;
15012         }
15013       else
15014         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15015         {
15016           is_ipv6 = 1;
15017           is_ip_any = 0;
15018         }
15019       else
15020         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15021         {
15022           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15023             {
15024               clib_warning ("unsupported action: 'resolve'");
15025               return -99;
15026             }
15027         }
15028       else
15029         {
15030           clib_warning ("parse error '%U'", format_unformat_error, i);
15031           return -99;
15032         }
15033
15034     }
15035
15036   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15037
15038   mp->spd_id = ntohl (spd_id);
15039   mp->priority = ntohl (priority);
15040   mp->is_outbound = is_outbound;
15041
15042   mp->is_ipv6 = is_ipv6;
15043   if (is_ipv6 || is_ip_any)
15044     {
15045       clib_memcpy (mp->remote_address_start, &raddr6_start,
15046                    sizeof (ip6_address_t));
15047       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15048                    sizeof (ip6_address_t));
15049       clib_memcpy (mp->local_address_start, &laddr6_start,
15050                    sizeof (ip6_address_t));
15051       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15052                    sizeof (ip6_address_t));
15053     }
15054   else
15055     {
15056       clib_memcpy (mp->remote_address_start, &raddr4_start,
15057                    sizeof (ip4_address_t));
15058       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15059                    sizeof (ip4_address_t));
15060       clib_memcpy (mp->local_address_start, &laddr4_start,
15061                    sizeof (ip4_address_t));
15062       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15063                    sizeof (ip4_address_t));
15064     }
15065   mp->protocol = (u8) protocol;
15066   mp->local_port_start = ntohs ((u16) lport_start);
15067   mp->local_port_stop = ntohs ((u16) lport_stop);
15068   mp->remote_port_start = ntohs ((u16) rport_start);
15069   mp->remote_port_stop = ntohs ((u16) rport_stop);
15070   mp->policy = (u8) policy;
15071   mp->sa_id = ntohl (sa_id);
15072   mp->is_add = is_add;
15073   mp->is_ip_any = is_ip_any;
15074   S (mp);
15075   W (ret);
15076   return ret;
15077 }
15078
15079 static int
15080 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15081 {
15082   unformat_input_t *i = vam->input;
15083   vl_api_ipsec_sad_add_del_entry_t *mp;
15084   u32 sad_id = 0, spi = 0;
15085   u8 *ck = 0, *ik = 0;
15086   u8 is_add = 1;
15087
15088   u8 protocol = IPSEC_PROTOCOL_AH;
15089   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15090   u32 crypto_alg = 0, integ_alg = 0;
15091   ip4_address_t tun_src4;
15092   ip4_address_t tun_dst4;
15093   ip6_address_t tun_src6;
15094   ip6_address_t tun_dst6;
15095   int ret;
15096
15097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (i, "del"))
15100         is_add = 0;
15101       else if (unformat (i, "sad_id %d", &sad_id))
15102         ;
15103       else if (unformat (i, "spi %d", &spi))
15104         ;
15105       else if (unformat (i, "esp"))
15106         protocol = IPSEC_PROTOCOL_ESP;
15107       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15108         {
15109           is_tunnel = 1;
15110           is_tunnel_ipv6 = 0;
15111         }
15112       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15113         {
15114           is_tunnel = 1;
15115           is_tunnel_ipv6 = 0;
15116         }
15117       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15118         {
15119           is_tunnel = 1;
15120           is_tunnel_ipv6 = 1;
15121         }
15122       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15123         {
15124           is_tunnel = 1;
15125           is_tunnel_ipv6 = 1;
15126         }
15127       else
15128         if (unformat
15129             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15130         {
15131           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15132               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15133             {
15134               clib_warning ("unsupported crypto-alg: '%U'",
15135                             format_ipsec_crypto_alg, crypto_alg);
15136               return -99;
15137             }
15138         }
15139       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15140         ;
15141       else
15142         if (unformat
15143             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15144         {
15145           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15146               integ_alg >= IPSEC_INTEG_N_ALG)
15147             {
15148               clib_warning ("unsupported integ-alg: '%U'",
15149                             format_ipsec_integ_alg, integ_alg);
15150               return -99;
15151             }
15152         }
15153       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15154         ;
15155       else
15156         {
15157           clib_warning ("parse error '%U'", format_unformat_error, i);
15158           return -99;
15159         }
15160
15161     }
15162
15163   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15164
15165   mp->sad_id = ntohl (sad_id);
15166   mp->is_add = is_add;
15167   mp->protocol = protocol;
15168   mp->spi = ntohl (spi);
15169   mp->is_tunnel = is_tunnel;
15170   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15171   mp->crypto_algorithm = crypto_alg;
15172   mp->integrity_algorithm = integ_alg;
15173   mp->crypto_key_length = vec_len (ck);
15174   mp->integrity_key_length = vec_len (ik);
15175
15176   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15177     mp->crypto_key_length = sizeof (mp->crypto_key);
15178
15179   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15180     mp->integrity_key_length = sizeof (mp->integrity_key);
15181
15182   if (ck)
15183     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15184   if (ik)
15185     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15186
15187   if (is_tunnel)
15188     {
15189       if (is_tunnel_ipv6)
15190         {
15191           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15192                        sizeof (ip6_address_t));
15193           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15194                        sizeof (ip6_address_t));
15195         }
15196       else
15197         {
15198           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15199                        sizeof (ip4_address_t));
15200           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15201                        sizeof (ip4_address_t));
15202         }
15203     }
15204
15205   S (mp);
15206   W (ret);
15207   return ret;
15208 }
15209
15210 static int
15211 api_ipsec_sa_set_key (vat_main_t * vam)
15212 {
15213   unformat_input_t *i = vam->input;
15214   vl_api_ipsec_sa_set_key_t *mp;
15215   u32 sa_id;
15216   u8 *ck = 0, *ik = 0;
15217   int ret;
15218
15219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15220     {
15221       if (unformat (i, "sa_id %d", &sa_id))
15222         ;
15223       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15224         ;
15225       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15226         ;
15227       else
15228         {
15229           clib_warning ("parse error '%U'", format_unformat_error, i);
15230           return -99;
15231         }
15232     }
15233
15234   M (IPSEC_SA_SET_KEY, mp);
15235
15236   mp->sa_id = ntohl (sa_id);
15237   mp->crypto_key_length = vec_len (ck);
15238   mp->integrity_key_length = vec_len (ik);
15239
15240   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15241     mp->crypto_key_length = sizeof (mp->crypto_key);
15242
15243   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15244     mp->integrity_key_length = sizeof (mp->integrity_key);
15245
15246   if (ck)
15247     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15248   if (ik)
15249     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15250
15251   S (mp);
15252   W (ret);
15253   return ret;
15254 }
15255
15256 static int
15257 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15258 {
15259   unformat_input_t *i = vam->input;
15260   vl_api_ipsec_tunnel_if_add_del_t *mp;
15261   u32 local_spi = 0, remote_spi = 0;
15262   u32 crypto_alg = 0, integ_alg = 0;
15263   u8 *lck = NULL, *rck = NULL;
15264   u8 *lik = NULL, *rik = NULL;
15265   ip4_address_t local_ip = { {0} };
15266   ip4_address_t remote_ip = { {0} };
15267   u8 is_add = 1;
15268   u8 esn = 0;
15269   u8 anti_replay = 0;
15270   u8 renumber = 0;
15271   u32 instance = ~0;
15272   int ret;
15273
15274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15275     {
15276       if (unformat (i, "del"))
15277         is_add = 0;
15278       else if (unformat (i, "esn"))
15279         esn = 1;
15280       else if (unformat (i, "anti_replay"))
15281         anti_replay = 1;
15282       else if (unformat (i, "local_spi %d", &local_spi))
15283         ;
15284       else if (unformat (i, "remote_spi %d", &remote_spi))
15285         ;
15286       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15287         ;
15288       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15289         ;
15290       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15291         ;
15292       else
15293         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15294         ;
15295       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15296         ;
15297       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15298         ;
15299       else
15300         if (unformat
15301             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15302         {
15303           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15304               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15305             {
15306               errmsg ("unsupported crypto-alg: '%U'\n",
15307                       format_ipsec_crypto_alg, crypto_alg);
15308               return -99;
15309             }
15310         }
15311       else
15312         if (unformat
15313             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15314         {
15315           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15316               integ_alg >= IPSEC_INTEG_N_ALG)
15317             {
15318               errmsg ("unsupported integ-alg: '%U'\n",
15319                       format_ipsec_integ_alg, integ_alg);
15320               return -99;
15321             }
15322         }
15323       else if (unformat (i, "instance %u", &instance))
15324         renumber = 1;
15325       else
15326         {
15327           errmsg ("parse error '%U'\n", format_unformat_error, i);
15328           return -99;
15329         }
15330     }
15331
15332   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15333
15334   mp->is_add = is_add;
15335   mp->esn = esn;
15336   mp->anti_replay = anti_replay;
15337
15338   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15339   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15340
15341   mp->local_spi = htonl (local_spi);
15342   mp->remote_spi = htonl (remote_spi);
15343   mp->crypto_alg = (u8) crypto_alg;
15344
15345   mp->local_crypto_key_len = 0;
15346   if (lck)
15347     {
15348       mp->local_crypto_key_len = vec_len (lck);
15349       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15350         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15351       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15352     }
15353
15354   mp->remote_crypto_key_len = 0;
15355   if (rck)
15356     {
15357       mp->remote_crypto_key_len = vec_len (rck);
15358       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15359         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15360       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15361     }
15362
15363   mp->integ_alg = (u8) integ_alg;
15364
15365   mp->local_integ_key_len = 0;
15366   if (lik)
15367     {
15368       mp->local_integ_key_len = vec_len (lik);
15369       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15370         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15371       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15372     }
15373
15374   mp->remote_integ_key_len = 0;
15375   if (rik)
15376     {
15377       mp->remote_integ_key_len = vec_len (rik);
15378       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15379         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15380       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15381     }
15382
15383   if (renumber)
15384     {
15385       mp->renumber = renumber;
15386       mp->show_instance = ntohl (instance);
15387     }
15388
15389   S (mp);
15390   W (ret);
15391   return ret;
15392 }
15393
15394 static void
15395 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15396 {
15397   vat_main_t *vam = &vat_main;
15398
15399   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15400          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15401          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15402          "tunnel_src_addr %U tunnel_dst_addr %U "
15403          "salt %u seq_outbound %lu last_seq_inbound %lu "
15404          "replay_window %lu total_data_size %lu\n",
15405          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15406          mp->protocol,
15407          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15408          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15409          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15410          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15411          mp->tunnel_src_addr,
15412          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15413          mp->tunnel_dst_addr,
15414          ntohl (mp->salt),
15415          clib_net_to_host_u64 (mp->seq_outbound),
15416          clib_net_to_host_u64 (mp->last_seq_inbound),
15417          clib_net_to_host_u64 (mp->replay_window),
15418          clib_net_to_host_u64 (mp->total_data_size));
15419 }
15420
15421 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15422 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15423
15424 static void vl_api_ipsec_sa_details_t_handler_json
15425   (vl_api_ipsec_sa_details_t * mp)
15426 {
15427   vat_main_t *vam = &vat_main;
15428   vat_json_node_t *node = NULL;
15429   struct in_addr src_ip4, dst_ip4;
15430   struct in6_addr src_ip6, dst_ip6;
15431
15432   if (VAT_JSON_ARRAY != vam->json_tree.type)
15433     {
15434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15435       vat_json_init_array (&vam->json_tree);
15436     }
15437   node = vat_json_array_add (&vam->json_tree);
15438
15439   vat_json_init_object (node);
15440   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15441   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15442   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15443   vat_json_object_add_uint (node, "proto", mp->protocol);
15444   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15445   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15446   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15447   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15448   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15449   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15450   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15451                              mp->crypto_key_len);
15452   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15453                              mp->integ_key_len);
15454   if (mp->is_tunnel_ip6)
15455     {
15456       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15457       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15458       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15459       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15460     }
15461   else
15462     {
15463       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15464       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15465       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15466       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15467     }
15468   vat_json_object_add_uint (node, "replay_window",
15469                             clib_net_to_host_u64 (mp->replay_window));
15470   vat_json_object_add_uint (node, "total_data_size",
15471                             clib_net_to_host_u64 (mp->total_data_size));
15472
15473 }
15474
15475 static int
15476 api_ipsec_sa_dump (vat_main_t * vam)
15477 {
15478   unformat_input_t *i = vam->input;
15479   vl_api_ipsec_sa_dump_t *mp;
15480   vl_api_control_ping_t *mp_ping;
15481   u32 sa_id = ~0;
15482   int ret;
15483
15484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15485     {
15486       if (unformat (i, "sa_id %d", &sa_id))
15487         ;
15488       else
15489         {
15490           clib_warning ("parse error '%U'", format_unformat_error, i);
15491           return -99;
15492         }
15493     }
15494
15495   M (IPSEC_SA_DUMP, mp);
15496
15497   mp->sa_id = ntohl (sa_id);
15498
15499   S (mp);
15500
15501   /* Use a control ping for synchronization */
15502   M (CONTROL_PING, mp_ping);
15503   S (mp_ping);
15504
15505   W (ret);
15506   return ret;
15507 }
15508
15509 static int
15510 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15511 {
15512   unformat_input_t *i = vam->input;
15513   vl_api_ipsec_tunnel_if_set_key_t *mp;
15514   u32 sw_if_index = ~0;
15515   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15516   u8 *key = 0;
15517   u32 alg = ~0;
15518   int ret;
15519
15520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15521     {
15522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15523         ;
15524       else
15525         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15526         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15527       else
15528         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15529         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15530       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15531         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15532       else
15533         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15534         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15535       else if (unformat (i, "%U", unformat_hex_string, &key))
15536         ;
15537       else
15538         {
15539           clib_warning ("parse error '%U'", format_unformat_error, i);
15540           return -99;
15541         }
15542     }
15543
15544   if (sw_if_index == ~0)
15545     {
15546       errmsg ("interface must be specified");
15547       return -99;
15548     }
15549
15550   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15551     {
15552       errmsg ("key type must be specified");
15553       return -99;
15554     }
15555
15556   if (alg == ~0)
15557     {
15558       errmsg ("algorithm must be specified");
15559       return -99;
15560     }
15561
15562   if (vec_len (key) == 0)
15563     {
15564       errmsg ("key must be specified");
15565       return -99;
15566     }
15567
15568   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15569
15570   mp->sw_if_index = htonl (sw_if_index);
15571   mp->alg = alg;
15572   mp->key_type = key_type;
15573   mp->key_len = vec_len (key);
15574   clib_memcpy (mp->key, key, vec_len (key));
15575
15576   S (mp);
15577   W (ret);
15578
15579   return ret;
15580 }
15581
15582 static int
15583 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15584 {
15585   unformat_input_t *i = vam->input;
15586   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15587   u32 sw_if_index = ~0;
15588   u32 sa_id = ~0;
15589   u8 is_outbound = (u8) ~ 0;
15590   int ret;
15591
15592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15593     {
15594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15595         ;
15596       else if (unformat (i, "sa_id %d", &sa_id))
15597         ;
15598       else if (unformat (i, "outbound"))
15599         is_outbound = 1;
15600       else if (unformat (i, "inbound"))
15601         is_outbound = 0;
15602       else
15603         {
15604           clib_warning ("parse error '%U'", format_unformat_error, i);
15605           return -99;
15606         }
15607     }
15608
15609   if (sw_if_index == ~0)
15610     {
15611       errmsg ("interface must be specified");
15612       return -99;
15613     }
15614
15615   if (sa_id == ~0)
15616     {
15617       errmsg ("SA ID must be specified");
15618       return -99;
15619     }
15620
15621   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15622
15623   mp->sw_if_index = htonl (sw_if_index);
15624   mp->sa_id = htonl (sa_id);
15625   mp->is_outbound = is_outbound;
15626
15627   S (mp);
15628   W (ret);
15629
15630   return ret;
15631 }
15632
15633 static int
15634 api_ikev2_profile_add_del (vat_main_t * vam)
15635 {
15636   unformat_input_t *i = vam->input;
15637   vl_api_ikev2_profile_add_del_t *mp;
15638   u8 is_add = 1;
15639   u8 *name = 0;
15640   int ret;
15641
15642   const char *valid_chars = "a-zA-Z0-9_";
15643
15644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (i, "del"))
15647         is_add = 0;
15648       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15649         vec_add1 (name, 0);
15650       else
15651         {
15652           errmsg ("parse error '%U'", format_unformat_error, i);
15653           return -99;
15654         }
15655     }
15656
15657   if (!vec_len (name))
15658     {
15659       errmsg ("profile name must be specified");
15660       return -99;
15661     }
15662
15663   if (vec_len (name) > 64)
15664     {
15665       errmsg ("profile name too long");
15666       return -99;
15667     }
15668
15669   M (IKEV2_PROFILE_ADD_DEL, mp);
15670
15671   clib_memcpy (mp->name, name, vec_len (name));
15672   mp->is_add = is_add;
15673   vec_free (name);
15674
15675   S (mp);
15676   W (ret);
15677   return ret;
15678 }
15679
15680 static int
15681 api_ikev2_profile_set_auth (vat_main_t * vam)
15682 {
15683   unformat_input_t *i = vam->input;
15684   vl_api_ikev2_profile_set_auth_t *mp;
15685   u8 *name = 0;
15686   u8 *data = 0;
15687   u32 auth_method = 0;
15688   u8 is_hex = 0;
15689   int ret;
15690
15691   const char *valid_chars = "a-zA-Z0-9_";
15692
15693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15696         vec_add1 (name, 0);
15697       else if (unformat (i, "auth_method %U",
15698                          unformat_ikev2_auth_method, &auth_method))
15699         ;
15700       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15701         is_hex = 1;
15702       else if (unformat (i, "auth_data %v", &data))
15703         ;
15704       else
15705         {
15706           errmsg ("parse error '%U'", format_unformat_error, i);
15707           return -99;
15708         }
15709     }
15710
15711   if (!vec_len (name))
15712     {
15713       errmsg ("profile name must be specified");
15714       return -99;
15715     }
15716
15717   if (vec_len (name) > 64)
15718     {
15719       errmsg ("profile name too long");
15720       return -99;
15721     }
15722
15723   if (!vec_len (data))
15724     {
15725       errmsg ("auth_data must be specified");
15726       return -99;
15727     }
15728
15729   if (!auth_method)
15730     {
15731       errmsg ("auth_method must be specified");
15732       return -99;
15733     }
15734
15735   M (IKEV2_PROFILE_SET_AUTH, mp);
15736
15737   mp->is_hex = is_hex;
15738   mp->auth_method = (u8) auth_method;
15739   mp->data_len = vec_len (data);
15740   clib_memcpy (mp->name, name, vec_len (name));
15741   clib_memcpy (mp->data, data, vec_len (data));
15742   vec_free (name);
15743   vec_free (data);
15744
15745   S (mp);
15746   W (ret);
15747   return ret;
15748 }
15749
15750 static int
15751 api_ikev2_profile_set_id (vat_main_t * vam)
15752 {
15753   unformat_input_t *i = vam->input;
15754   vl_api_ikev2_profile_set_id_t *mp;
15755   u8 *name = 0;
15756   u8 *data = 0;
15757   u8 is_local = 0;
15758   u32 id_type = 0;
15759   ip4_address_t ip4;
15760   int ret;
15761
15762   const char *valid_chars = "a-zA-Z0-9_";
15763
15764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15765     {
15766       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15767         vec_add1 (name, 0);
15768       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15769         ;
15770       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15771         {
15772           data = vec_new (u8, 4);
15773           clib_memcpy (data, ip4.as_u8, 4);
15774         }
15775       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15776         ;
15777       else if (unformat (i, "id_data %v", &data))
15778         ;
15779       else if (unformat (i, "local"))
15780         is_local = 1;
15781       else if (unformat (i, "remote"))
15782         is_local = 0;
15783       else
15784         {
15785           errmsg ("parse error '%U'", format_unformat_error, i);
15786           return -99;
15787         }
15788     }
15789
15790   if (!vec_len (name))
15791     {
15792       errmsg ("profile name must be specified");
15793       return -99;
15794     }
15795
15796   if (vec_len (name) > 64)
15797     {
15798       errmsg ("profile name too long");
15799       return -99;
15800     }
15801
15802   if (!vec_len (data))
15803     {
15804       errmsg ("id_data must be specified");
15805       return -99;
15806     }
15807
15808   if (!id_type)
15809     {
15810       errmsg ("id_type must be specified");
15811       return -99;
15812     }
15813
15814   M (IKEV2_PROFILE_SET_ID, mp);
15815
15816   mp->is_local = is_local;
15817   mp->id_type = (u8) id_type;
15818   mp->data_len = vec_len (data);
15819   clib_memcpy (mp->name, name, vec_len (name));
15820   clib_memcpy (mp->data, data, vec_len (data));
15821   vec_free (name);
15822   vec_free (data);
15823
15824   S (mp);
15825   W (ret);
15826   return ret;
15827 }
15828
15829 static int
15830 api_ikev2_profile_set_ts (vat_main_t * vam)
15831 {
15832   unformat_input_t *i = vam->input;
15833   vl_api_ikev2_profile_set_ts_t *mp;
15834   u8 *name = 0;
15835   u8 is_local = 0;
15836   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15837   ip4_address_t start_addr, end_addr;
15838
15839   const char *valid_chars = "a-zA-Z0-9_";
15840   int ret;
15841
15842   start_addr.as_u32 = 0;
15843   end_addr.as_u32 = (u32) ~ 0;
15844
15845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15846     {
15847       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15848         vec_add1 (name, 0);
15849       else if (unformat (i, "protocol %d", &proto))
15850         ;
15851       else if (unformat (i, "start_port %d", &start_port))
15852         ;
15853       else if (unformat (i, "end_port %d", &end_port))
15854         ;
15855       else
15856         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15857         ;
15858       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15859         ;
15860       else if (unformat (i, "local"))
15861         is_local = 1;
15862       else if (unformat (i, "remote"))
15863         is_local = 0;
15864       else
15865         {
15866           errmsg ("parse error '%U'", format_unformat_error, i);
15867           return -99;
15868         }
15869     }
15870
15871   if (!vec_len (name))
15872     {
15873       errmsg ("profile name must be specified");
15874       return -99;
15875     }
15876
15877   if (vec_len (name) > 64)
15878     {
15879       errmsg ("profile name too long");
15880       return -99;
15881     }
15882
15883   M (IKEV2_PROFILE_SET_TS, mp);
15884
15885   mp->is_local = is_local;
15886   mp->proto = (u8) proto;
15887   mp->start_port = (u16) start_port;
15888   mp->end_port = (u16) end_port;
15889   mp->start_addr = start_addr.as_u32;
15890   mp->end_addr = end_addr.as_u32;
15891   clib_memcpy (mp->name, name, vec_len (name));
15892   vec_free (name);
15893
15894   S (mp);
15895   W (ret);
15896   return ret;
15897 }
15898
15899 static int
15900 api_ikev2_set_local_key (vat_main_t * vam)
15901 {
15902   unformat_input_t *i = vam->input;
15903   vl_api_ikev2_set_local_key_t *mp;
15904   u8 *file = 0;
15905   int ret;
15906
15907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15908     {
15909       if (unformat (i, "file %v", &file))
15910         vec_add1 (file, 0);
15911       else
15912         {
15913           errmsg ("parse error '%U'", format_unformat_error, i);
15914           return -99;
15915         }
15916     }
15917
15918   if (!vec_len (file))
15919     {
15920       errmsg ("RSA key file must be specified");
15921       return -99;
15922     }
15923
15924   if (vec_len (file) > 256)
15925     {
15926       errmsg ("file name too long");
15927       return -99;
15928     }
15929
15930   M (IKEV2_SET_LOCAL_KEY, mp);
15931
15932   clib_memcpy (mp->key_file, file, vec_len (file));
15933   vec_free (file);
15934
15935   S (mp);
15936   W (ret);
15937   return ret;
15938 }
15939
15940 static int
15941 api_ikev2_set_responder (vat_main_t * vam)
15942 {
15943   unformat_input_t *i = vam->input;
15944   vl_api_ikev2_set_responder_t *mp;
15945   int ret;
15946   u8 *name = 0;
15947   u32 sw_if_index = ~0;
15948   ip4_address_t address;
15949
15950   const char *valid_chars = "a-zA-Z0-9_";
15951
15952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15953     {
15954       if (unformat
15955           (i, "%U interface %d address %U", unformat_token, valid_chars,
15956            &name, &sw_if_index, unformat_ip4_address, &address))
15957         vec_add1 (name, 0);
15958       else
15959         {
15960           errmsg ("parse error '%U'", format_unformat_error, i);
15961           return -99;
15962         }
15963     }
15964
15965   if (!vec_len (name))
15966     {
15967       errmsg ("profile name must be specified");
15968       return -99;
15969     }
15970
15971   if (vec_len (name) > 64)
15972     {
15973       errmsg ("profile name too long");
15974       return -99;
15975     }
15976
15977   M (IKEV2_SET_RESPONDER, mp);
15978
15979   clib_memcpy (mp->name, name, vec_len (name));
15980   vec_free (name);
15981
15982   mp->sw_if_index = sw_if_index;
15983   clib_memcpy (mp->address, &address, sizeof (address));
15984
15985   S (mp);
15986   W (ret);
15987   return ret;
15988 }
15989
15990 static int
15991 api_ikev2_set_ike_transforms (vat_main_t * vam)
15992 {
15993   unformat_input_t *i = vam->input;
15994   vl_api_ikev2_set_ike_transforms_t *mp;
15995   int ret;
15996   u8 *name = 0;
15997   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15998
15999   const char *valid_chars = "a-zA-Z0-9_";
16000
16001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16002     {
16003       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16004                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16005         vec_add1 (name, 0);
16006       else
16007         {
16008           errmsg ("parse error '%U'", format_unformat_error, i);
16009           return -99;
16010         }
16011     }
16012
16013   if (!vec_len (name))
16014     {
16015       errmsg ("profile name must be specified");
16016       return -99;
16017     }
16018
16019   if (vec_len (name) > 64)
16020     {
16021       errmsg ("profile name too long");
16022       return -99;
16023     }
16024
16025   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16026
16027   clib_memcpy (mp->name, name, vec_len (name));
16028   vec_free (name);
16029   mp->crypto_alg = crypto_alg;
16030   mp->crypto_key_size = crypto_key_size;
16031   mp->integ_alg = integ_alg;
16032   mp->dh_group = dh_group;
16033
16034   S (mp);
16035   W (ret);
16036   return ret;
16037 }
16038
16039
16040 static int
16041 api_ikev2_set_esp_transforms (vat_main_t * vam)
16042 {
16043   unformat_input_t *i = vam->input;
16044   vl_api_ikev2_set_esp_transforms_t *mp;
16045   int ret;
16046   u8 *name = 0;
16047   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16048
16049   const char *valid_chars = "a-zA-Z0-9_";
16050
16051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16052     {
16053       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16054                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16055         vec_add1 (name, 0);
16056       else
16057         {
16058           errmsg ("parse error '%U'", format_unformat_error, i);
16059           return -99;
16060         }
16061     }
16062
16063   if (!vec_len (name))
16064     {
16065       errmsg ("profile name must be specified");
16066       return -99;
16067     }
16068
16069   if (vec_len (name) > 64)
16070     {
16071       errmsg ("profile name too long");
16072       return -99;
16073     }
16074
16075   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16076
16077   clib_memcpy (mp->name, name, vec_len (name));
16078   vec_free (name);
16079   mp->crypto_alg = crypto_alg;
16080   mp->crypto_key_size = crypto_key_size;
16081   mp->integ_alg = integ_alg;
16082   mp->dh_group = dh_group;
16083
16084   S (mp);
16085   W (ret);
16086   return ret;
16087 }
16088
16089 static int
16090 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16091 {
16092   unformat_input_t *i = vam->input;
16093   vl_api_ikev2_set_sa_lifetime_t *mp;
16094   int ret;
16095   u8 *name = 0;
16096   u64 lifetime, lifetime_maxdata;
16097   u32 lifetime_jitter, handover;
16098
16099   const char *valid_chars = "a-zA-Z0-9_";
16100
16101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16102     {
16103       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16104                     &lifetime, &lifetime_jitter, &handover,
16105                     &lifetime_maxdata))
16106         vec_add1 (name, 0);
16107       else
16108         {
16109           errmsg ("parse error '%U'", format_unformat_error, i);
16110           return -99;
16111         }
16112     }
16113
16114   if (!vec_len (name))
16115     {
16116       errmsg ("profile name must be specified");
16117       return -99;
16118     }
16119
16120   if (vec_len (name) > 64)
16121     {
16122       errmsg ("profile name too long");
16123       return -99;
16124     }
16125
16126   M (IKEV2_SET_SA_LIFETIME, mp);
16127
16128   clib_memcpy (mp->name, name, vec_len (name));
16129   vec_free (name);
16130   mp->lifetime = lifetime;
16131   mp->lifetime_jitter = lifetime_jitter;
16132   mp->handover = handover;
16133   mp->lifetime_maxdata = lifetime_maxdata;
16134
16135   S (mp);
16136   W (ret);
16137   return ret;
16138 }
16139
16140 static int
16141 api_ikev2_initiate_sa_init (vat_main_t * vam)
16142 {
16143   unformat_input_t *i = vam->input;
16144   vl_api_ikev2_initiate_sa_init_t *mp;
16145   int ret;
16146   u8 *name = 0;
16147
16148   const char *valid_chars = "a-zA-Z0-9_";
16149
16150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16151     {
16152       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16153         vec_add1 (name, 0);
16154       else
16155         {
16156           errmsg ("parse error '%U'", format_unformat_error, i);
16157           return -99;
16158         }
16159     }
16160
16161   if (!vec_len (name))
16162     {
16163       errmsg ("profile name must be specified");
16164       return -99;
16165     }
16166
16167   if (vec_len (name) > 64)
16168     {
16169       errmsg ("profile name too long");
16170       return -99;
16171     }
16172
16173   M (IKEV2_INITIATE_SA_INIT, mp);
16174
16175   clib_memcpy (mp->name, name, vec_len (name));
16176   vec_free (name);
16177
16178   S (mp);
16179   W (ret);
16180   return ret;
16181 }
16182
16183 static int
16184 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16185 {
16186   unformat_input_t *i = vam->input;
16187   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16188   int ret;
16189   u64 ispi;
16190
16191
16192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16193     {
16194       if (unformat (i, "%lx", &ispi))
16195         ;
16196       else
16197         {
16198           errmsg ("parse error '%U'", format_unformat_error, i);
16199           return -99;
16200         }
16201     }
16202
16203   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16204
16205   mp->ispi = ispi;
16206
16207   S (mp);
16208   W (ret);
16209   return ret;
16210 }
16211
16212 static int
16213 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16214 {
16215   unformat_input_t *i = vam->input;
16216   vl_api_ikev2_initiate_del_child_sa_t *mp;
16217   int ret;
16218   u32 ispi;
16219
16220
16221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (i, "%x", &ispi))
16224         ;
16225       else
16226         {
16227           errmsg ("parse error '%U'", format_unformat_error, i);
16228           return -99;
16229         }
16230     }
16231
16232   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16233
16234   mp->ispi = ispi;
16235
16236   S (mp);
16237   W (ret);
16238   return ret;
16239 }
16240
16241 static int
16242 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16243 {
16244   unformat_input_t *i = vam->input;
16245   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16246   int ret;
16247   u32 ispi;
16248
16249
16250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16251     {
16252       if (unformat (i, "%x", &ispi))
16253         ;
16254       else
16255         {
16256           errmsg ("parse error '%U'", format_unformat_error, i);
16257           return -99;
16258         }
16259     }
16260
16261   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16262
16263   mp->ispi = ispi;
16264
16265   S (mp);
16266   W (ret);
16267   return ret;
16268 }
16269
16270 static int
16271 api_get_first_msg_id (vat_main_t * vam)
16272 {
16273   vl_api_get_first_msg_id_t *mp;
16274   unformat_input_t *i = vam->input;
16275   u8 *name;
16276   u8 name_set = 0;
16277   int ret;
16278
16279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16280     {
16281       if (unformat (i, "client %s", &name))
16282         name_set = 1;
16283       else
16284         break;
16285     }
16286
16287   if (name_set == 0)
16288     {
16289       errmsg ("missing client name");
16290       return -99;
16291     }
16292   vec_add1 (name, 0);
16293
16294   if (vec_len (name) > 63)
16295     {
16296       errmsg ("client name too long");
16297       return -99;
16298     }
16299
16300   M (GET_FIRST_MSG_ID, mp);
16301   clib_memcpy (mp->name, name, vec_len (name));
16302   S (mp);
16303   W (ret);
16304   return ret;
16305 }
16306
16307 static int
16308 api_cop_interface_enable_disable (vat_main_t * vam)
16309 {
16310   unformat_input_t *line_input = vam->input;
16311   vl_api_cop_interface_enable_disable_t *mp;
16312   u32 sw_if_index = ~0;
16313   u8 enable_disable = 1;
16314   int ret;
16315
16316   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16317     {
16318       if (unformat (line_input, "disable"))
16319         enable_disable = 0;
16320       if (unformat (line_input, "enable"))
16321         enable_disable = 1;
16322       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16323                          vam, &sw_if_index))
16324         ;
16325       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16326         ;
16327       else
16328         break;
16329     }
16330
16331   if (sw_if_index == ~0)
16332     {
16333       errmsg ("missing interface name or sw_if_index");
16334       return -99;
16335     }
16336
16337   /* Construct the API message */
16338   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16339   mp->sw_if_index = ntohl (sw_if_index);
16340   mp->enable_disable = enable_disable;
16341
16342   /* send it... */
16343   S (mp);
16344   /* Wait for the reply */
16345   W (ret);
16346   return ret;
16347 }
16348
16349 static int
16350 api_cop_whitelist_enable_disable (vat_main_t * vam)
16351 {
16352   unformat_input_t *line_input = vam->input;
16353   vl_api_cop_whitelist_enable_disable_t *mp;
16354   u32 sw_if_index = ~0;
16355   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16356   u32 fib_id = 0;
16357   int ret;
16358
16359   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (line_input, "ip4"))
16362         ip4 = 1;
16363       else if (unformat (line_input, "ip6"))
16364         ip6 = 1;
16365       else if (unformat (line_input, "default"))
16366         default_cop = 1;
16367       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16368                          vam, &sw_if_index))
16369         ;
16370       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16371         ;
16372       else if (unformat (line_input, "fib-id %d", &fib_id))
16373         ;
16374       else
16375         break;
16376     }
16377
16378   if (sw_if_index == ~0)
16379     {
16380       errmsg ("missing interface name or sw_if_index");
16381       return -99;
16382     }
16383
16384   /* Construct the API message */
16385   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16386   mp->sw_if_index = ntohl (sw_if_index);
16387   mp->fib_id = ntohl (fib_id);
16388   mp->ip4 = ip4;
16389   mp->ip6 = ip6;
16390   mp->default_cop = default_cop;
16391
16392   /* send it... */
16393   S (mp);
16394   /* Wait for the reply */
16395   W (ret);
16396   return ret;
16397 }
16398
16399 static int
16400 api_get_node_graph (vat_main_t * vam)
16401 {
16402   vl_api_get_node_graph_t *mp;
16403   int ret;
16404
16405   M (GET_NODE_GRAPH, mp);
16406
16407   /* send it... */
16408   S (mp);
16409   /* Wait for the reply */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 /* *INDENT-OFF* */
16415 /** Used for parsing LISP eids */
16416 typedef CLIB_PACKED(struct{
16417   u8 addr[16];   /**< eid address */
16418   u32 len;       /**< prefix length if IP */
16419   u8 type;      /**< type of eid */
16420 }) lisp_eid_vat_t;
16421 /* *INDENT-ON* */
16422
16423 static uword
16424 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16425 {
16426   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16427
16428   memset (a, 0, sizeof (a[0]));
16429
16430   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16431     {
16432       a->type = 0;              /* ipv4 type */
16433     }
16434   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16435     {
16436       a->type = 1;              /* ipv6 type */
16437     }
16438   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16439     {
16440       a->type = 2;              /* mac type */
16441     }
16442   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16443     {
16444       a->type = 3;              /* NSH type */
16445       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16446       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16447     }
16448   else
16449     {
16450       return 0;
16451     }
16452
16453   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16454     {
16455       return 0;
16456     }
16457
16458   return 1;
16459 }
16460
16461 static int
16462 lisp_eid_size_vat (u8 type)
16463 {
16464   switch (type)
16465     {
16466     case 0:
16467       return 4;
16468     case 1:
16469       return 16;
16470     case 2:
16471       return 6;
16472     case 3:
16473       return 5;
16474     }
16475   return 0;
16476 }
16477
16478 static void
16479 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16480 {
16481   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16482 }
16483
16484 static int
16485 api_one_add_del_locator_set (vat_main_t * vam)
16486 {
16487   unformat_input_t *input = vam->input;
16488   vl_api_one_add_del_locator_set_t *mp;
16489   u8 is_add = 1;
16490   u8 *locator_set_name = NULL;
16491   u8 locator_set_name_set = 0;
16492   vl_api_local_locator_t locator, *locators = 0;
16493   u32 sw_if_index, priority, weight;
16494   u32 data_len = 0;
16495
16496   int ret;
16497   /* Parse args required to build the message */
16498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16499     {
16500       if (unformat (input, "del"))
16501         {
16502           is_add = 0;
16503         }
16504       else if (unformat (input, "locator-set %s", &locator_set_name))
16505         {
16506           locator_set_name_set = 1;
16507         }
16508       else if (unformat (input, "sw_if_index %u p %u w %u",
16509                          &sw_if_index, &priority, &weight))
16510         {
16511           locator.sw_if_index = htonl (sw_if_index);
16512           locator.priority = priority;
16513           locator.weight = weight;
16514           vec_add1 (locators, locator);
16515         }
16516       else
16517         if (unformat
16518             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16519              &sw_if_index, &priority, &weight))
16520         {
16521           locator.sw_if_index = htonl (sw_if_index);
16522           locator.priority = priority;
16523           locator.weight = weight;
16524           vec_add1 (locators, locator);
16525         }
16526       else
16527         break;
16528     }
16529
16530   if (locator_set_name_set == 0)
16531     {
16532       errmsg ("missing locator-set name");
16533       vec_free (locators);
16534       return -99;
16535     }
16536
16537   if (vec_len (locator_set_name) > 64)
16538     {
16539       errmsg ("locator-set name too long");
16540       vec_free (locator_set_name);
16541       vec_free (locators);
16542       return -99;
16543     }
16544   vec_add1 (locator_set_name, 0);
16545
16546   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16547
16548   /* Construct the API message */
16549   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16550
16551   mp->is_add = is_add;
16552   clib_memcpy (mp->locator_set_name, locator_set_name,
16553                vec_len (locator_set_name));
16554   vec_free (locator_set_name);
16555
16556   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16557   if (locators)
16558     clib_memcpy (mp->locators, locators, data_len);
16559   vec_free (locators);
16560
16561   /* send it... */
16562   S (mp);
16563
16564   /* Wait for a reply... */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16570
16571 static int
16572 api_one_add_del_locator (vat_main_t * vam)
16573 {
16574   unformat_input_t *input = vam->input;
16575   vl_api_one_add_del_locator_t *mp;
16576   u32 tmp_if_index = ~0;
16577   u32 sw_if_index = ~0;
16578   u8 sw_if_index_set = 0;
16579   u8 sw_if_index_if_name_set = 0;
16580   u32 priority = ~0;
16581   u8 priority_set = 0;
16582   u32 weight = ~0;
16583   u8 weight_set = 0;
16584   u8 is_add = 1;
16585   u8 *locator_set_name = NULL;
16586   u8 locator_set_name_set = 0;
16587   int ret;
16588
16589   /* Parse args required to build the message */
16590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16591     {
16592       if (unformat (input, "del"))
16593         {
16594           is_add = 0;
16595         }
16596       else if (unformat (input, "locator-set %s", &locator_set_name))
16597         {
16598           locator_set_name_set = 1;
16599         }
16600       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16601                          &tmp_if_index))
16602         {
16603           sw_if_index_if_name_set = 1;
16604           sw_if_index = tmp_if_index;
16605         }
16606       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16607         {
16608           sw_if_index_set = 1;
16609           sw_if_index = tmp_if_index;
16610         }
16611       else if (unformat (input, "p %d", &priority))
16612         {
16613           priority_set = 1;
16614         }
16615       else if (unformat (input, "w %d", &weight))
16616         {
16617           weight_set = 1;
16618         }
16619       else
16620         break;
16621     }
16622
16623   if (locator_set_name_set == 0)
16624     {
16625       errmsg ("missing locator-set name");
16626       return -99;
16627     }
16628
16629   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16630     {
16631       errmsg ("missing sw_if_index");
16632       vec_free (locator_set_name);
16633       return -99;
16634     }
16635
16636   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16637     {
16638       errmsg ("cannot use both params interface name and sw_if_index");
16639       vec_free (locator_set_name);
16640       return -99;
16641     }
16642
16643   if (priority_set == 0)
16644     {
16645       errmsg ("missing locator-set priority");
16646       vec_free (locator_set_name);
16647       return -99;
16648     }
16649
16650   if (weight_set == 0)
16651     {
16652       errmsg ("missing locator-set weight");
16653       vec_free (locator_set_name);
16654       return -99;
16655     }
16656
16657   if (vec_len (locator_set_name) > 64)
16658     {
16659       errmsg ("locator-set name too long");
16660       vec_free (locator_set_name);
16661       return -99;
16662     }
16663   vec_add1 (locator_set_name, 0);
16664
16665   /* Construct the API message */
16666   M (ONE_ADD_DEL_LOCATOR, mp);
16667
16668   mp->is_add = is_add;
16669   mp->sw_if_index = ntohl (sw_if_index);
16670   mp->priority = priority;
16671   mp->weight = weight;
16672   clib_memcpy (mp->locator_set_name, locator_set_name,
16673                vec_len (locator_set_name));
16674   vec_free (locator_set_name);
16675
16676   /* send it... */
16677   S (mp);
16678
16679   /* Wait for a reply... */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 #define api_lisp_add_del_locator api_one_add_del_locator
16685
16686 uword
16687 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16688 {
16689   u32 *key_id = va_arg (*args, u32 *);
16690   u8 *s = 0;
16691
16692   if (unformat (input, "%s", &s))
16693     {
16694       if (!strcmp ((char *) s, "sha1"))
16695         key_id[0] = HMAC_SHA_1_96;
16696       else if (!strcmp ((char *) s, "sha256"))
16697         key_id[0] = HMAC_SHA_256_128;
16698       else
16699         {
16700           clib_warning ("invalid key_id: '%s'", s);
16701           key_id[0] = HMAC_NO_KEY;
16702         }
16703     }
16704   else
16705     return 0;
16706
16707   vec_free (s);
16708   return 1;
16709 }
16710
16711 static int
16712 api_one_add_del_local_eid (vat_main_t * vam)
16713 {
16714   unformat_input_t *input = vam->input;
16715   vl_api_one_add_del_local_eid_t *mp;
16716   u8 is_add = 1;
16717   u8 eid_set = 0;
16718   lisp_eid_vat_t _eid, *eid = &_eid;
16719   u8 *locator_set_name = 0;
16720   u8 locator_set_name_set = 0;
16721   u32 vni = 0;
16722   u16 key_id = 0;
16723   u8 *key = 0;
16724   int ret;
16725
16726   /* Parse args required to build the message */
16727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (input, "del"))
16730         {
16731           is_add = 0;
16732         }
16733       else if (unformat (input, "vni %d", &vni))
16734         {
16735           ;
16736         }
16737       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16738         {
16739           eid_set = 1;
16740         }
16741       else if (unformat (input, "locator-set %s", &locator_set_name))
16742         {
16743           locator_set_name_set = 1;
16744         }
16745       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16746         ;
16747       else if (unformat (input, "secret-key %_%v%_", &key))
16748         ;
16749       else
16750         break;
16751     }
16752
16753   if (locator_set_name_set == 0)
16754     {
16755       errmsg ("missing locator-set name");
16756       return -99;
16757     }
16758
16759   if (0 == eid_set)
16760     {
16761       errmsg ("EID address not set!");
16762       vec_free (locator_set_name);
16763       return -99;
16764     }
16765
16766   if (key && (0 == key_id))
16767     {
16768       errmsg ("invalid key_id!");
16769       return -99;
16770     }
16771
16772   if (vec_len (key) > 64)
16773     {
16774       errmsg ("key too long");
16775       vec_free (key);
16776       return -99;
16777     }
16778
16779   if (vec_len (locator_set_name) > 64)
16780     {
16781       errmsg ("locator-set name too long");
16782       vec_free (locator_set_name);
16783       return -99;
16784     }
16785   vec_add1 (locator_set_name, 0);
16786
16787   /* Construct the API message */
16788   M (ONE_ADD_DEL_LOCAL_EID, mp);
16789
16790   mp->is_add = is_add;
16791   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16792   mp->eid_type = eid->type;
16793   mp->prefix_len = eid->len;
16794   mp->vni = clib_host_to_net_u32 (vni);
16795   mp->key_id = clib_host_to_net_u16 (key_id);
16796   clib_memcpy (mp->locator_set_name, locator_set_name,
16797                vec_len (locator_set_name));
16798   clib_memcpy (mp->key, key, vec_len (key));
16799
16800   vec_free (locator_set_name);
16801   vec_free (key);
16802
16803   /* send it... */
16804   S (mp);
16805
16806   /* Wait for a reply... */
16807   W (ret);
16808   return ret;
16809 }
16810
16811 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16812
16813 static int
16814 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16815 {
16816   u32 dp_table = 0, vni = 0;;
16817   unformat_input_t *input = vam->input;
16818   vl_api_gpe_add_del_fwd_entry_t *mp;
16819   u8 is_add = 1;
16820   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16821   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16822   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16823   u32 action = ~0, w;
16824   ip4_address_t rmt_rloc4, lcl_rloc4;
16825   ip6_address_t rmt_rloc6, lcl_rloc6;
16826   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16827   int ret;
16828
16829   memset (&rloc, 0, sizeof (rloc));
16830
16831   /* Parse args required to build the message */
16832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16833     {
16834       if (unformat (input, "del"))
16835         is_add = 0;
16836       else if (unformat (input, "add"))
16837         is_add = 1;
16838       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16839         {
16840           rmt_eid_set = 1;
16841         }
16842       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16843         {
16844           lcl_eid_set = 1;
16845         }
16846       else if (unformat (input, "vrf %d", &dp_table))
16847         ;
16848       else if (unformat (input, "bd %d", &dp_table))
16849         ;
16850       else if (unformat (input, "vni %d", &vni))
16851         ;
16852       else if (unformat (input, "w %d", &w))
16853         {
16854           if (!curr_rloc)
16855             {
16856               errmsg ("No RLOC configured for setting priority/weight!");
16857               return -99;
16858             }
16859           curr_rloc->weight = w;
16860         }
16861       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16862                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16863         {
16864           rloc.is_ip4 = 1;
16865
16866           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16867           rloc.weight = 0;
16868           vec_add1 (lcl_locs, rloc);
16869
16870           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16871           vec_add1 (rmt_locs, rloc);
16872           /* weight saved in rmt loc */
16873           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16874         }
16875       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16876                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16877         {
16878           rloc.is_ip4 = 0;
16879           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16880           rloc.weight = 0;
16881           vec_add1 (lcl_locs, rloc);
16882
16883           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16884           vec_add1 (rmt_locs, rloc);
16885           /* weight saved in rmt loc */
16886           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16887         }
16888       else if (unformat (input, "action %d", &action))
16889         {
16890           ;
16891         }
16892       else
16893         {
16894           clib_warning ("parse error '%U'", format_unformat_error, input);
16895           return -99;
16896         }
16897     }
16898
16899   if (!rmt_eid_set)
16900     {
16901       errmsg ("remote eid addresses not set");
16902       return -99;
16903     }
16904
16905   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16906     {
16907       errmsg ("eid types don't match");
16908       return -99;
16909     }
16910
16911   if (0 == rmt_locs && (u32) ~ 0 == action)
16912     {
16913       errmsg ("action not set for negative mapping");
16914       return -99;
16915     }
16916
16917   /* Construct the API message */
16918   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16919       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16920
16921   mp->is_add = is_add;
16922   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16923   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16924   mp->eid_type = rmt_eid->type;
16925   mp->dp_table = clib_host_to_net_u32 (dp_table);
16926   mp->vni = clib_host_to_net_u32 (vni);
16927   mp->rmt_len = rmt_eid->len;
16928   mp->lcl_len = lcl_eid->len;
16929   mp->action = action;
16930
16931   if (0 != rmt_locs && 0 != lcl_locs)
16932     {
16933       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16934       clib_memcpy (mp->locs, lcl_locs,
16935                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16936
16937       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16938       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16939                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16940     }
16941   vec_free (lcl_locs);
16942   vec_free (rmt_locs);
16943
16944   /* send it... */
16945   S (mp);
16946
16947   /* Wait for a reply... */
16948   W (ret);
16949   return ret;
16950 }
16951
16952 static int
16953 api_one_add_del_map_server (vat_main_t * vam)
16954 {
16955   unformat_input_t *input = vam->input;
16956   vl_api_one_add_del_map_server_t *mp;
16957   u8 is_add = 1;
16958   u8 ipv4_set = 0;
16959   u8 ipv6_set = 0;
16960   ip4_address_t ipv4;
16961   ip6_address_t ipv6;
16962   int ret;
16963
16964   /* Parse args required to build the message */
16965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16966     {
16967       if (unformat (input, "del"))
16968         {
16969           is_add = 0;
16970         }
16971       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16972         {
16973           ipv4_set = 1;
16974         }
16975       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16976         {
16977           ipv6_set = 1;
16978         }
16979       else
16980         break;
16981     }
16982
16983   if (ipv4_set && ipv6_set)
16984     {
16985       errmsg ("both eid v4 and v6 addresses set");
16986       return -99;
16987     }
16988
16989   if (!ipv4_set && !ipv6_set)
16990     {
16991       errmsg ("eid addresses not set");
16992       return -99;
16993     }
16994
16995   /* Construct the API message */
16996   M (ONE_ADD_DEL_MAP_SERVER, mp);
16997
16998   mp->is_add = is_add;
16999   if (ipv6_set)
17000     {
17001       mp->is_ipv6 = 1;
17002       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17003     }
17004   else
17005     {
17006       mp->is_ipv6 = 0;
17007       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17008     }
17009
17010   /* send it... */
17011   S (mp);
17012
17013   /* Wait for a reply... */
17014   W (ret);
17015   return ret;
17016 }
17017
17018 #define api_lisp_add_del_map_server api_one_add_del_map_server
17019
17020 static int
17021 api_one_add_del_map_resolver (vat_main_t * vam)
17022 {
17023   unformat_input_t *input = vam->input;
17024   vl_api_one_add_del_map_resolver_t *mp;
17025   u8 is_add = 1;
17026   u8 ipv4_set = 0;
17027   u8 ipv6_set = 0;
17028   ip4_address_t ipv4;
17029   ip6_address_t ipv6;
17030   int ret;
17031
17032   /* Parse args required to build the message */
17033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17034     {
17035       if (unformat (input, "del"))
17036         {
17037           is_add = 0;
17038         }
17039       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17040         {
17041           ipv4_set = 1;
17042         }
17043       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17044         {
17045           ipv6_set = 1;
17046         }
17047       else
17048         break;
17049     }
17050
17051   if (ipv4_set && ipv6_set)
17052     {
17053       errmsg ("both eid v4 and v6 addresses set");
17054       return -99;
17055     }
17056
17057   if (!ipv4_set && !ipv6_set)
17058     {
17059       errmsg ("eid addresses not set");
17060       return -99;
17061     }
17062
17063   /* Construct the API message */
17064   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17065
17066   mp->is_add = is_add;
17067   if (ipv6_set)
17068     {
17069       mp->is_ipv6 = 1;
17070       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17071     }
17072   else
17073     {
17074       mp->is_ipv6 = 0;
17075       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17076     }
17077
17078   /* send it... */
17079   S (mp);
17080
17081   /* Wait for a reply... */
17082   W (ret);
17083   return ret;
17084 }
17085
17086 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17087
17088 static int
17089 api_lisp_gpe_enable_disable (vat_main_t * vam)
17090 {
17091   unformat_input_t *input = vam->input;
17092   vl_api_gpe_enable_disable_t *mp;
17093   u8 is_set = 0;
17094   u8 is_en = 1;
17095   int ret;
17096
17097   /* Parse args required to build the message */
17098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17099     {
17100       if (unformat (input, "enable"))
17101         {
17102           is_set = 1;
17103           is_en = 1;
17104         }
17105       else if (unformat (input, "disable"))
17106         {
17107           is_set = 1;
17108           is_en = 0;
17109         }
17110       else
17111         break;
17112     }
17113
17114   if (is_set == 0)
17115     {
17116       errmsg ("Value not set");
17117       return -99;
17118     }
17119
17120   /* Construct the API message */
17121   M (GPE_ENABLE_DISABLE, mp);
17122
17123   mp->is_en = is_en;
17124
17125   /* send it... */
17126   S (mp);
17127
17128   /* Wait for a reply... */
17129   W (ret);
17130   return ret;
17131 }
17132
17133 static int
17134 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17135 {
17136   unformat_input_t *input = vam->input;
17137   vl_api_one_rloc_probe_enable_disable_t *mp;
17138   u8 is_set = 0;
17139   u8 is_en = 0;
17140   int ret;
17141
17142   /* Parse args required to build the message */
17143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17144     {
17145       if (unformat (input, "enable"))
17146         {
17147           is_set = 1;
17148           is_en = 1;
17149         }
17150       else if (unformat (input, "disable"))
17151         is_set = 1;
17152       else
17153         break;
17154     }
17155
17156   if (!is_set)
17157     {
17158       errmsg ("Value not set");
17159       return -99;
17160     }
17161
17162   /* Construct the API message */
17163   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17164
17165   mp->is_enabled = is_en;
17166
17167   /* send it... */
17168   S (mp);
17169
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17176
17177 static int
17178 api_one_map_register_enable_disable (vat_main_t * vam)
17179 {
17180   unformat_input_t *input = vam->input;
17181   vl_api_one_map_register_enable_disable_t *mp;
17182   u8 is_set = 0;
17183   u8 is_en = 0;
17184   int ret;
17185
17186   /* Parse args required to build the message */
17187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17188     {
17189       if (unformat (input, "enable"))
17190         {
17191           is_set = 1;
17192           is_en = 1;
17193         }
17194       else if (unformat (input, "disable"))
17195         is_set = 1;
17196       else
17197         break;
17198     }
17199
17200   if (!is_set)
17201     {
17202       errmsg ("Value not set");
17203       return -99;
17204     }
17205
17206   /* Construct the API message */
17207   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17208
17209   mp->is_enabled = is_en;
17210
17211   /* send it... */
17212   S (mp);
17213
17214   /* Wait for a reply... */
17215   W (ret);
17216   return ret;
17217 }
17218
17219 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17220
17221 static int
17222 api_one_enable_disable (vat_main_t * vam)
17223 {
17224   unformat_input_t *input = vam->input;
17225   vl_api_one_enable_disable_t *mp;
17226   u8 is_set = 0;
17227   u8 is_en = 0;
17228   int ret;
17229
17230   /* Parse args required to build the message */
17231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17232     {
17233       if (unformat (input, "enable"))
17234         {
17235           is_set = 1;
17236           is_en = 1;
17237         }
17238       else if (unformat (input, "disable"))
17239         {
17240           is_set = 1;
17241         }
17242       else
17243         break;
17244     }
17245
17246   if (!is_set)
17247     {
17248       errmsg ("Value not set");
17249       return -99;
17250     }
17251
17252   /* Construct the API message */
17253   M (ONE_ENABLE_DISABLE, mp);
17254
17255   mp->is_en = is_en;
17256
17257   /* send it... */
17258   S (mp);
17259
17260   /* Wait for a reply... */
17261   W (ret);
17262   return ret;
17263 }
17264
17265 #define api_lisp_enable_disable api_one_enable_disable
17266
17267 static int
17268 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17269 {
17270   unformat_input_t *input = vam->input;
17271   vl_api_one_enable_disable_xtr_mode_t *mp;
17272   u8 is_set = 0;
17273   u8 is_en = 0;
17274   int ret;
17275
17276   /* Parse args required to build the message */
17277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (input, "enable"))
17280         {
17281           is_set = 1;
17282           is_en = 1;
17283         }
17284       else if (unformat (input, "disable"))
17285         {
17286           is_set = 1;
17287         }
17288       else
17289         break;
17290     }
17291
17292   if (!is_set)
17293     {
17294       errmsg ("Value not set");
17295       return -99;
17296     }
17297
17298   /* Construct the API message */
17299   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17300
17301   mp->is_en = is_en;
17302
17303   /* send it... */
17304   S (mp);
17305
17306   /* Wait for a reply... */
17307   W (ret);
17308   return ret;
17309 }
17310
17311 static int
17312 api_one_show_xtr_mode (vat_main_t * vam)
17313 {
17314   vl_api_one_show_xtr_mode_t *mp;
17315   int ret;
17316
17317   /* Construct the API message */
17318   M (ONE_SHOW_XTR_MODE, mp);
17319
17320   /* send it... */
17321   S (mp);
17322
17323   /* Wait for a reply... */
17324   W (ret);
17325   return ret;
17326 }
17327
17328 static int
17329 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17330 {
17331   unformat_input_t *input = vam->input;
17332   vl_api_one_enable_disable_pitr_mode_t *mp;
17333   u8 is_set = 0;
17334   u8 is_en = 0;
17335   int ret;
17336
17337   /* Parse args required to build the message */
17338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17339     {
17340       if (unformat (input, "enable"))
17341         {
17342           is_set = 1;
17343           is_en = 1;
17344         }
17345       else if (unformat (input, "disable"))
17346         {
17347           is_set = 1;
17348         }
17349       else
17350         break;
17351     }
17352
17353   if (!is_set)
17354     {
17355       errmsg ("Value not set");
17356       return -99;
17357     }
17358
17359   /* Construct the API message */
17360   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17361
17362   mp->is_en = is_en;
17363
17364   /* send it... */
17365   S (mp);
17366
17367   /* Wait for a reply... */
17368   W (ret);
17369   return ret;
17370 }
17371
17372 static int
17373 api_one_show_pitr_mode (vat_main_t * vam)
17374 {
17375   vl_api_one_show_pitr_mode_t *mp;
17376   int ret;
17377
17378   /* Construct the API message */
17379   M (ONE_SHOW_PITR_MODE, mp);
17380
17381   /* send it... */
17382   S (mp);
17383
17384   /* Wait for a reply... */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 static int
17390 api_one_enable_disable_petr_mode (vat_main_t * vam)
17391 {
17392   unformat_input_t *input = vam->input;
17393   vl_api_one_enable_disable_petr_mode_t *mp;
17394   u8 is_set = 0;
17395   u8 is_en = 0;
17396   int ret;
17397
17398   /* Parse args required to build the message */
17399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (input, "enable"))
17402         {
17403           is_set = 1;
17404           is_en = 1;
17405         }
17406       else if (unformat (input, "disable"))
17407         {
17408           is_set = 1;
17409         }
17410       else
17411         break;
17412     }
17413
17414   if (!is_set)
17415     {
17416       errmsg ("Value not set");
17417       return -99;
17418     }
17419
17420   /* Construct the API message */
17421   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17422
17423   mp->is_en = is_en;
17424
17425   /* send it... */
17426   S (mp);
17427
17428   /* Wait for a reply... */
17429   W (ret);
17430   return ret;
17431 }
17432
17433 static int
17434 api_one_show_petr_mode (vat_main_t * vam)
17435 {
17436   vl_api_one_show_petr_mode_t *mp;
17437   int ret;
17438
17439   /* Construct the API message */
17440   M (ONE_SHOW_PETR_MODE, mp);
17441
17442   /* send it... */
17443   S (mp);
17444
17445   /* Wait for a reply... */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 static int
17451 api_show_one_map_register_state (vat_main_t * vam)
17452 {
17453   vl_api_show_one_map_register_state_t *mp;
17454   int ret;
17455
17456   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17457
17458   /* send */
17459   S (mp);
17460
17461   /* wait for reply */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 #define api_show_lisp_map_register_state api_show_one_map_register_state
17467
17468 static int
17469 api_show_one_rloc_probe_state (vat_main_t * vam)
17470 {
17471   vl_api_show_one_rloc_probe_state_t *mp;
17472   int ret;
17473
17474   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17475
17476   /* send */
17477   S (mp);
17478
17479   /* wait for reply */
17480   W (ret);
17481   return ret;
17482 }
17483
17484 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17485
17486 static int
17487 api_one_add_del_ndp_entry (vat_main_t * vam)
17488 {
17489   vl_api_one_add_del_ndp_entry_t *mp;
17490   unformat_input_t *input = vam->input;
17491   u8 is_add = 1;
17492   u8 mac_set = 0;
17493   u8 bd_set = 0;
17494   u8 ip_set = 0;
17495   u8 mac[6] = { 0, };
17496   u8 ip6[16] = { 0, };
17497   u32 bd = ~0;
17498   int ret;
17499
17500   /* Parse args required to build the message */
17501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17502     {
17503       if (unformat (input, "del"))
17504         is_add = 0;
17505       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17506         mac_set = 1;
17507       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17508         ip_set = 1;
17509       else if (unformat (input, "bd %d", &bd))
17510         bd_set = 1;
17511       else
17512         {
17513           errmsg ("parse error '%U'", format_unformat_error, input);
17514           return -99;
17515         }
17516     }
17517
17518   if (!bd_set || !ip_set || (!mac_set && is_add))
17519     {
17520       errmsg ("Missing BD, IP or MAC!");
17521       return -99;
17522     }
17523
17524   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17525   mp->is_add = is_add;
17526   clib_memcpy (mp->mac, mac, 6);
17527   mp->bd = clib_host_to_net_u32 (bd);
17528   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17529
17530   /* send */
17531   S (mp);
17532
17533   /* wait for reply */
17534   W (ret);
17535   return ret;
17536 }
17537
17538 static int
17539 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17540 {
17541   vl_api_one_add_del_l2_arp_entry_t *mp;
17542   unformat_input_t *input = vam->input;
17543   u8 is_add = 1;
17544   u8 mac_set = 0;
17545   u8 bd_set = 0;
17546   u8 ip_set = 0;
17547   u8 mac[6] = { 0, };
17548   u32 ip4 = 0, bd = ~0;
17549   int ret;
17550
17551   /* Parse args required to build the message */
17552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17553     {
17554       if (unformat (input, "del"))
17555         is_add = 0;
17556       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17557         mac_set = 1;
17558       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17559         ip_set = 1;
17560       else if (unformat (input, "bd %d", &bd))
17561         bd_set = 1;
17562       else
17563         {
17564           errmsg ("parse error '%U'", format_unformat_error, input);
17565           return -99;
17566         }
17567     }
17568
17569   if (!bd_set || !ip_set || (!mac_set && is_add))
17570     {
17571       errmsg ("Missing BD, IP or MAC!");
17572       return -99;
17573     }
17574
17575   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17576   mp->is_add = is_add;
17577   clib_memcpy (mp->mac, mac, 6);
17578   mp->bd = clib_host_to_net_u32 (bd);
17579   mp->ip4 = ip4;
17580
17581   /* send */
17582   S (mp);
17583
17584   /* wait for reply */
17585   W (ret);
17586   return ret;
17587 }
17588
17589 static int
17590 api_one_ndp_bd_get (vat_main_t * vam)
17591 {
17592   vl_api_one_ndp_bd_get_t *mp;
17593   int ret;
17594
17595   M (ONE_NDP_BD_GET, mp);
17596
17597   /* send */
17598   S (mp);
17599
17600   /* wait for reply */
17601   W (ret);
17602   return ret;
17603 }
17604
17605 static int
17606 api_one_ndp_entries_get (vat_main_t * vam)
17607 {
17608   vl_api_one_ndp_entries_get_t *mp;
17609   unformat_input_t *input = vam->input;
17610   u8 bd_set = 0;
17611   u32 bd = ~0;
17612   int ret;
17613
17614   /* Parse args required to build the message */
17615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17616     {
17617       if (unformat (input, "bd %d", &bd))
17618         bd_set = 1;
17619       else
17620         {
17621           errmsg ("parse error '%U'", format_unformat_error, input);
17622           return -99;
17623         }
17624     }
17625
17626   if (!bd_set)
17627     {
17628       errmsg ("Expected bridge domain!");
17629       return -99;
17630     }
17631
17632   M (ONE_NDP_ENTRIES_GET, mp);
17633   mp->bd = clib_host_to_net_u32 (bd);
17634
17635   /* send */
17636   S (mp);
17637
17638   /* wait for reply */
17639   W (ret);
17640   return ret;
17641 }
17642
17643 static int
17644 api_one_l2_arp_bd_get (vat_main_t * vam)
17645 {
17646   vl_api_one_l2_arp_bd_get_t *mp;
17647   int ret;
17648
17649   M (ONE_L2_ARP_BD_GET, mp);
17650
17651   /* send */
17652   S (mp);
17653
17654   /* wait for reply */
17655   W (ret);
17656   return ret;
17657 }
17658
17659 static int
17660 api_one_l2_arp_entries_get (vat_main_t * vam)
17661 {
17662   vl_api_one_l2_arp_entries_get_t *mp;
17663   unformat_input_t *input = vam->input;
17664   u8 bd_set = 0;
17665   u32 bd = ~0;
17666   int ret;
17667
17668   /* Parse args required to build the message */
17669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17670     {
17671       if (unformat (input, "bd %d", &bd))
17672         bd_set = 1;
17673       else
17674         {
17675           errmsg ("parse error '%U'", format_unformat_error, input);
17676           return -99;
17677         }
17678     }
17679
17680   if (!bd_set)
17681     {
17682       errmsg ("Expected bridge domain!");
17683       return -99;
17684     }
17685
17686   M (ONE_L2_ARP_ENTRIES_GET, mp);
17687   mp->bd = clib_host_to_net_u32 (bd);
17688
17689   /* send */
17690   S (mp);
17691
17692   /* wait for reply */
17693   W (ret);
17694   return ret;
17695 }
17696
17697 static int
17698 api_one_stats_enable_disable (vat_main_t * vam)
17699 {
17700   vl_api_one_stats_enable_disable_t *mp;
17701   unformat_input_t *input = vam->input;
17702   u8 is_set = 0;
17703   u8 is_en = 0;
17704   int ret;
17705
17706   /* Parse args required to build the message */
17707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17708     {
17709       if (unformat (input, "enable"))
17710         {
17711           is_set = 1;
17712           is_en = 1;
17713         }
17714       else if (unformat (input, "disable"))
17715         {
17716           is_set = 1;
17717         }
17718       else
17719         break;
17720     }
17721
17722   if (!is_set)
17723     {
17724       errmsg ("Value not set");
17725       return -99;
17726     }
17727
17728   M (ONE_STATS_ENABLE_DISABLE, mp);
17729   mp->is_en = is_en;
17730
17731   /* send */
17732   S (mp);
17733
17734   /* wait for reply */
17735   W (ret);
17736   return ret;
17737 }
17738
17739 static int
17740 api_show_one_stats_enable_disable (vat_main_t * vam)
17741 {
17742   vl_api_show_one_stats_enable_disable_t *mp;
17743   int ret;
17744
17745   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17746
17747   /* send */
17748   S (mp);
17749
17750   /* wait for reply */
17751   W (ret);
17752   return ret;
17753 }
17754
17755 static int
17756 api_show_one_map_request_mode (vat_main_t * vam)
17757 {
17758   vl_api_show_one_map_request_mode_t *mp;
17759   int ret;
17760
17761   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17762
17763   /* send */
17764   S (mp);
17765
17766   /* wait for reply */
17767   W (ret);
17768   return ret;
17769 }
17770
17771 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17772
17773 static int
17774 api_one_map_request_mode (vat_main_t * vam)
17775 {
17776   unformat_input_t *input = vam->input;
17777   vl_api_one_map_request_mode_t *mp;
17778   u8 mode = 0;
17779   int ret;
17780
17781   /* Parse args required to build the message */
17782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17783     {
17784       if (unformat (input, "dst-only"))
17785         mode = 0;
17786       else if (unformat (input, "src-dst"))
17787         mode = 1;
17788       else
17789         {
17790           errmsg ("parse error '%U'", format_unformat_error, input);
17791           return -99;
17792         }
17793     }
17794
17795   M (ONE_MAP_REQUEST_MODE, mp);
17796
17797   mp->mode = mode;
17798
17799   /* send */
17800   S (mp);
17801
17802   /* wait for reply */
17803   W (ret);
17804   return ret;
17805 }
17806
17807 #define api_lisp_map_request_mode api_one_map_request_mode
17808
17809 /**
17810  * Enable/disable ONE proxy ITR.
17811  *
17812  * @param vam vpp API test context
17813  * @return return code
17814  */
17815 static int
17816 api_one_pitr_set_locator_set (vat_main_t * vam)
17817 {
17818   u8 ls_name_set = 0;
17819   unformat_input_t *input = vam->input;
17820   vl_api_one_pitr_set_locator_set_t *mp;
17821   u8 is_add = 1;
17822   u8 *ls_name = 0;
17823   int ret;
17824
17825   /* Parse args required to build the message */
17826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17827     {
17828       if (unformat (input, "del"))
17829         is_add = 0;
17830       else if (unformat (input, "locator-set %s", &ls_name))
17831         ls_name_set = 1;
17832       else
17833         {
17834           errmsg ("parse error '%U'", format_unformat_error, input);
17835           return -99;
17836         }
17837     }
17838
17839   if (!ls_name_set)
17840     {
17841       errmsg ("locator-set name not set!");
17842       return -99;
17843     }
17844
17845   M (ONE_PITR_SET_LOCATOR_SET, mp);
17846
17847   mp->is_add = is_add;
17848   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17849   vec_free (ls_name);
17850
17851   /* send */
17852   S (mp);
17853
17854   /* wait for reply */
17855   W (ret);
17856   return ret;
17857 }
17858
17859 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17860
17861 static int
17862 api_one_nsh_set_locator_set (vat_main_t * vam)
17863 {
17864   u8 ls_name_set = 0;
17865   unformat_input_t *input = vam->input;
17866   vl_api_one_nsh_set_locator_set_t *mp;
17867   u8 is_add = 1;
17868   u8 *ls_name = 0;
17869   int ret;
17870
17871   /* Parse args required to build the message */
17872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17873     {
17874       if (unformat (input, "del"))
17875         is_add = 0;
17876       else if (unformat (input, "ls %s", &ls_name))
17877         ls_name_set = 1;
17878       else
17879         {
17880           errmsg ("parse error '%U'", format_unformat_error, input);
17881           return -99;
17882         }
17883     }
17884
17885   if (!ls_name_set && is_add)
17886     {
17887       errmsg ("locator-set name not set!");
17888       return -99;
17889     }
17890
17891   M (ONE_NSH_SET_LOCATOR_SET, mp);
17892
17893   mp->is_add = is_add;
17894   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17895   vec_free (ls_name);
17896
17897   /* send */
17898   S (mp);
17899
17900   /* wait for reply */
17901   W (ret);
17902   return ret;
17903 }
17904
17905 static int
17906 api_show_one_pitr (vat_main_t * vam)
17907 {
17908   vl_api_show_one_pitr_t *mp;
17909   int ret;
17910
17911   if (!vam->json_output)
17912     {
17913       print (vam->ofp, "%=20s", "lisp status:");
17914     }
17915
17916   M (SHOW_ONE_PITR, mp);
17917   /* send it... */
17918   S (mp);
17919
17920   /* Wait for a reply... */
17921   W (ret);
17922   return ret;
17923 }
17924
17925 #define api_show_lisp_pitr api_show_one_pitr
17926
17927 static int
17928 api_one_use_petr (vat_main_t * vam)
17929 {
17930   unformat_input_t *input = vam->input;
17931   vl_api_one_use_petr_t *mp;
17932   u8 is_add = 0;
17933   ip_address_t ip;
17934   int ret;
17935
17936   memset (&ip, 0, sizeof (ip));
17937
17938   /* Parse args required to build the message */
17939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17940     {
17941       if (unformat (input, "disable"))
17942         is_add = 0;
17943       else
17944         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17945         {
17946           is_add = 1;
17947           ip_addr_version (&ip) = IP4;
17948         }
17949       else
17950         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17951         {
17952           is_add = 1;
17953           ip_addr_version (&ip) = IP6;
17954         }
17955       else
17956         {
17957           errmsg ("parse error '%U'", format_unformat_error, input);
17958           return -99;
17959         }
17960     }
17961
17962   M (ONE_USE_PETR, mp);
17963
17964   mp->is_add = is_add;
17965   if (is_add)
17966     {
17967       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17968       if (mp->is_ip4)
17969         clib_memcpy (mp->address, &ip, 4);
17970       else
17971         clib_memcpy (mp->address, &ip, 16);
17972     }
17973
17974   /* send */
17975   S (mp);
17976
17977   /* wait for reply */
17978   W (ret);
17979   return ret;
17980 }
17981
17982 #define api_lisp_use_petr api_one_use_petr
17983
17984 static int
17985 api_show_one_nsh_mapping (vat_main_t * vam)
17986 {
17987   vl_api_show_one_use_petr_t *mp;
17988   int ret;
17989
17990   if (!vam->json_output)
17991     {
17992       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17993     }
17994
17995   M (SHOW_ONE_NSH_MAPPING, mp);
17996   /* send it... */
17997   S (mp);
17998
17999   /* Wait for a reply... */
18000   W (ret);
18001   return ret;
18002 }
18003
18004 static int
18005 api_show_one_use_petr (vat_main_t * vam)
18006 {
18007   vl_api_show_one_use_petr_t *mp;
18008   int ret;
18009
18010   if (!vam->json_output)
18011     {
18012       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18013     }
18014
18015   M (SHOW_ONE_USE_PETR, mp);
18016   /* send it... */
18017   S (mp);
18018
18019   /* Wait for a reply... */
18020   W (ret);
18021   return ret;
18022 }
18023
18024 #define api_show_lisp_use_petr api_show_one_use_petr
18025
18026 /**
18027  * Add/delete mapping between vni and vrf
18028  */
18029 static int
18030 api_one_eid_table_add_del_map (vat_main_t * vam)
18031 {
18032   unformat_input_t *input = vam->input;
18033   vl_api_one_eid_table_add_del_map_t *mp;
18034   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18035   u32 vni, vrf, bd_index;
18036   int ret;
18037
18038   /* Parse args required to build the message */
18039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18040     {
18041       if (unformat (input, "del"))
18042         is_add = 0;
18043       else if (unformat (input, "vrf %d", &vrf))
18044         vrf_set = 1;
18045       else if (unformat (input, "bd_index %d", &bd_index))
18046         bd_index_set = 1;
18047       else if (unformat (input, "vni %d", &vni))
18048         vni_set = 1;
18049       else
18050         break;
18051     }
18052
18053   if (!vni_set || (!vrf_set && !bd_index_set))
18054     {
18055       errmsg ("missing arguments!");
18056       return -99;
18057     }
18058
18059   if (vrf_set && bd_index_set)
18060     {
18061       errmsg ("error: both vrf and bd entered!");
18062       return -99;
18063     }
18064
18065   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18066
18067   mp->is_add = is_add;
18068   mp->vni = htonl (vni);
18069   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18070   mp->is_l2 = bd_index_set;
18071
18072   /* send */
18073   S (mp);
18074
18075   /* wait for reply */
18076   W (ret);
18077   return ret;
18078 }
18079
18080 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18081
18082 uword
18083 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18084 {
18085   u32 *action = va_arg (*args, u32 *);
18086   u8 *s = 0;
18087
18088   if (unformat (input, "%s", &s))
18089     {
18090       if (!strcmp ((char *) s, "no-action"))
18091         action[0] = 0;
18092       else if (!strcmp ((char *) s, "natively-forward"))
18093         action[0] = 1;
18094       else if (!strcmp ((char *) s, "send-map-request"))
18095         action[0] = 2;
18096       else if (!strcmp ((char *) s, "drop"))
18097         action[0] = 3;
18098       else
18099         {
18100           clib_warning ("invalid action: '%s'", s);
18101           action[0] = 3;
18102         }
18103     }
18104   else
18105     return 0;
18106
18107   vec_free (s);
18108   return 1;
18109 }
18110
18111 /**
18112  * Add/del remote mapping to/from ONE control plane
18113  *
18114  * @param vam vpp API test context
18115  * @return return code
18116  */
18117 static int
18118 api_one_add_del_remote_mapping (vat_main_t * vam)
18119 {
18120   unformat_input_t *input = vam->input;
18121   vl_api_one_add_del_remote_mapping_t *mp;
18122   u32 vni = 0;
18123   lisp_eid_vat_t _eid, *eid = &_eid;
18124   lisp_eid_vat_t _seid, *seid = &_seid;
18125   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18126   u32 action = ~0, p, w, data_len;
18127   ip4_address_t rloc4;
18128   ip6_address_t rloc6;
18129   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18130   int ret;
18131
18132   memset (&rloc, 0, sizeof (rloc));
18133
18134   /* Parse args required to build the message */
18135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18136     {
18137       if (unformat (input, "del-all"))
18138         {
18139           del_all = 1;
18140         }
18141       else if (unformat (input, "del"))
18142         {
18143           is_add = 0;
18144         }
18145       else if (unformat (input, "add"))
18146         {
18147           is_add = 1;
18148         }
18149       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18150         {
18151           eid_set = 1;
18152         }
18153       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18154         {
18155           seid_set = 1;
18156         }
18157       else if (unformat (input, "vni %d", &vni))
18158         {
18159           ;
18160         }
18161       else if (unformat (input, "p %d w %d", &p, &w))
18162         {
18163           if (!curr_rloc)
18164             {
18165               errmsg ("No RLOC configured for setting priority/weight!");
18166               return -99;
18167             }
18168           curr_rloc->priority = p;
18169           curr_rloc->weight = w;
18170         }
18171       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18172         {
18173           rloc.is_ip4 = 1;
18174           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18175           vec_add1 (rlocs, rloc);
18176           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18177         }
18178       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18179         {
18180           rloc.is_ip4 = 0;
18181           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18182           vec_add1 (rlocs, rloc);
18183           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18184         }
18185       else if (unformat (input, "action %U",
18186                          unformat_negative_mapping_action, &action))
18187         {
18188           ;
18189         }
18190       else
18191         {
18192           clib_warning ("parse error '%U'", format_unformat_error, input);
18193           return -99;
18194         }
18195     }
18196
18197   if (0 == eid_set)
18198     {
18199       errmsg ("missing params!");
18200       return -99;
18201     }
18202
18203   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18204     {
18205       errmsg ("no action set for negative map-reply!");
18206       return -99;
18207     }
18208
18209   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18210
18211   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18212   mp->is_add = is_add;
18213   mp->vni = htonl (vni);
18214   mp->action = (u8) action;
18215   mp->is_src_dst = seid_set;
18216   mp->eid_len = eid->len;
18217   mp->seid_len = seid->len;
18218   mp->del_all = del_all;
18219   mp->eid_type = eid->type;
18220   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18221   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18222
18223   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18224   clib_memcpy (mp->rlocs, rlocs, data_len);
18225   vec_free (rlocs);
18226
18227   /* send it... */
18228   S (mp);
18229
18230   /* Wait for a reply... */
18231   W (ret);
18232   return ret;
18233 }
18234
18235 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18236
18237 /**
18238  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18239  * forwarding entries in data-plane accordingly.
18240  *
18241  * @param vam vpp API test context
18242  * @return return code
18243  */
18244 static int
18245 api_one_add_del_adjacency (vat_main_t * vam)
18246 {
18247   unformat_input_t *input = vam->input;
18248   vl_api_one_add_del_adjacency_t *mp;
18249   u32 vni = 0;
18250   ip4_address_t leid4, reid4;
18251   ip6_address_t leid6, reid6;
18252   u8 reid_mac[6] = { 0 };
18253   u8 leid_mac[6] = { 0 };
18254   u8 reid_type, leid_type;
18255   u32 leid_len = 0, reid_len = 0, len;
18256   u8 is_add = 1;
18257   int ret;
18258
18259   leid_type = reid_type = (u8) ~ 0;
18260
18261   /* Parse args required to build the message */
18262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18263     {
18264       if (unformat (input, "del"))
18265         {
18266           is_add = 0;
18267         }
18268       else if (unformat (input, "add"))
18269         {
18270           is_add = 1;
18271         }
18272       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18273                          &reid4, &len))
18274         {
18275           reid_type = 0;        /* ipv4 */
18276           reid_len = len;
18277         }
18278       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18279                          &reid6, &len))
18280         {
18281           reid_type = 1;        /* ipv6 */
18282           reid_len = len;
18283         }
18284       else if (unformat (input, "reid %U", unformat_ethernet_address,
18285                          reid_mac))
18286         {
18287           reid_type = 2;        /* mac */
18288         }
18289       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18290                          &leid4, &len))
18291         {
18292           leid_type = 0;        /* ipv4 */
18293           leid_len = len;
18294         }
18295       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18296                          &leid6, &len))
18297         {
18298           leid_type = 1;        /* ipv6 */
18299           leid_len = len;
18300         }
18301       else if (unformat (input, "leid %U", unformat_ethernet_address,
18302                          leid_mac))
18303         {
18304           leid_type = 2;        /* mac */
18305         }
18306       else if (unformat (input, "vni %d", &vni))
18307         {
18308           ;
18309         }
18310       else
18311         {
18312           errmsg ("parse error '%U'", format_unformat_error, input);
18313           return -99;
18314         }
18315     }
18316
18317   if ((u8) ~ 0 == reid_type)
18318     {
18319       errmsg ("missing params!");
18320       return -99;
18321     }
18322
18323   if (leid_type != reid_type)
18324     {
18325       errmsg ("remote and local EIDs are of different types!");
18326       return -99;
18327     }
18328
18329   M (ONE_ADD_DEL_ADJACENCY, mp);
18330   mp->is_add = is_add;
18331   mp->vni = htonl (vni);
18332   mp->leid_len = leid_len;
18333   mp->reid_len = reid_len;
18334   mp->eid_type = reid_type;
18335
18336   switch (mp->eid_type)
18337     {
18338     case 0:
18339       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18340       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18341       break;
18342     case 1:
18343       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18344       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18345       break;
18346     case 2:
18347       clib_memcpy (mp->leid, leid_mac, 6);
18348       clib_memcpy (mp->reid, reid_mac, 6);
18349       break;
18350     default:
18351       errmsg ("unknown EID type %d!", mp->eid_type);
18352       return 0;
18353     }
18354
18355   /* send it... */
18356   S (mp);
18357
18358   /* Wait for a reply... */
18359   W (ret);
18360   return ret;
18361 }
18362
18363 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18364
18365 uword
18366 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18367 {
18368   u32 *mode = va_arg (*args, u32 *);
18369
18370   if (unformat (input, "lisp"))
18371     *mode = 0;
18372   else if (unformat (input, "vxlan"))
18373     *mode = 1;
18374   else
18375     return 0;
18376
18377   return 1;
18378 }
18379
18380 static int
18381 api_gpe_get_encap_mode (vat_main_t * vam)
18382 {
18383   vl_api_gpe_get_encap_mode_t *mp;
18384   int ret;
18385
18386   /* Construct the API message */
18387   M (GPE_GET_ENCAP_MODE, mp);
18388
18389   /* send it... */
18390   S (mp);
18391
18392   /* Wait for a reply... */
18393   W (ret);
18394   return ret;
18395 }
18396
18397 static int
18398 api_gpe_set_encap_mode (vat_main_t * vam)
18399 {
18400   unformat_input_t *input = vam->input;
18401   vl_api_gpe_set_encap_mode_t *mp;
18402   int ret;
18403   u32 mode = 0;
18404
18405   /* Parse args required to build the message */
18406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18407     {
18408       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18409         ;
18410       else
18411         break;
18412     }
18413
18414   /* Construct the API message */
18415   M (GPE_SET_ENCAP_MODE, mp);
18416
18417   mp->mode = mode;
18418
18419   /* send it... */
18420   S (mp);
18421
18422   /* Wait for a reply... */
18423   W (ret);
18424   return ret;
18425 }
18426
18427 static int
18428 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18429 {
18430   unformat_input_t *input = vam->input;
18431   vl_api_gpe_add_del_iface_t *mp;
18432   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18433   u32 dp_table = 0, vni = 0;
18434   int ret;
18435
18436   /* Parse args required to build the message */
18437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18438     {
18439       if (unformat (input, "up"))
18440         {
18441           action_set = 1;
18442           is_add = 1;
18443         }
18444       else if (unformat (input, "down"))
18445         {
18446           action_set = 1;
18447           is_add = 0;
18448         }
18449       else if (unformat (input, "table_id %d", &dp_table))
18450         {
18451           dp_table_set = 1;
18452         }
18453       else if (unformat (input, "bd_id %d", &dp_table))
18454         {
18455           dp_table_set = 1;
18456           is_l2 = 1;
18457         }
18458       else if (unformat (input, "vni %d", &vni))
18459         {
18460           vni_set = 1;
18461         }
18462       else
18463         break;
18464     }
18465
18466   if (action_set == 0)
18467     {
18468       errmsg ("Action not set");
18469       return -99;
18470     }
18471   if (dp_table_set == 0 || vni_set == 0)
18472     {
18473       errmsg ("vni and dp_table must be set");
18474       return -99;
18475     }
18476
18477   /* Construct the API message */
18478   M (GPE_ADD_DEL_IFACE, mp);
18479
18480   mp->is_add = is_add;
18481   mp->dp_table = clib_host_to_net_u32 (dp_table);
18482   mp->is_l2 = is_l2;
18483   mp->vni = clib_host_to_net_u32 (vni);
18484
18485   /* send it... */
18486   S (mp);
18487
18488   /* Wait for a reply... */
18489   W (ret);
18490   return ret;
18491 }
18492
18493 static int
18494 api_one_map_register_fallback_threshold (vat_main_t * vam)
18495 {
18496   unformat_input_t *input = vam->input;
18497   vl_api_one_map_register_fallback_threshold_t *mp;
18498   u32 value = 0;
18499   u8 is_set = 0;
18500   int ret;
18501
18502   /* Parse args required to build the message */
18503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18504     {
18505       if (unformat (input, "%u", &value))
18506         is_set = 1;
18507       else
18508         {
18509           clib_warning ("parse error '%U'", format_unformat_error, input);
18510           return -99;
18511         }
18512     }
18513
18514   if (!is_set)
18515     {
18516       errmsg ("fallback threshold value is missing!");
18517       return -99;
18518     }
18519
18520   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18521   mp->value = clib_host_to_net_u32 (value);
18522
18523   /* send it... */
18524   S (mp);
18525
18526   /* Wait for a reply... */
18527   W (ret);
18528   return ret;
18529 }
18530
18531 static int
18532 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18533 {
18534   vl_api_show_one_map_register_fallback_threshold_t *mp;
18535   int ret;
18536
18537   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18538
18539   /* send it... */
18540   S (mp);
18541
18542   /* Wait for a reply... */
18543   W (ret);
18544   return ret;
18545 }
18546
18547 uword
18548 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18549 {
18550   u32 *proto = va_arg (*args, u32 *);
18551
18552   if (unformat (input, "udp"))
18553     *proto = 1;
18554   else if (unformat (input, "api"))
18555     *proto = 2;
18556   else
18557     return 0;
18558
18559   return 1;
18560 }
18561
18562 static int
18563 api_one_set_transport_protocol (vat_main_t * vam)
18564 {
18565   unformat_input_t *input = vam->input;
18566   vl_api_one_set_transport_protocol_t *mp;
18567   u8 is_set = 0;
18568   u32 protocol = 0;
18569   int ret;
18570
18571   /* Parse args required to build the message */
18572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18573     {
18574       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18575         is_set = 1;
18576       else
18577         {
18578           clib_warning ("parse error '%U'", format_unformat_error, input);
18579           return -99;
18580         }
18581     }
18582
18583   if (!is_set)
18584     {
18585       errmsg ("Transport protocol missing!");
18586       return -99;
18587     }
18588
18589   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18590   mp->protocol = (u8) protocol;
18591
18592   /* send it... */
18593   S (mp);
18594
18595   /* Wait for a reply... */
18596   W (ret);
18597   return ret;
18598 }
18599
18600 static int
18601 api_one_get_transport_protocol (vat_main_t * vam)
18602 {
18603   vl_api_one_get_transport_protocol_t *mp;
18604   int ret;
18605
18606   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18607
18608   /* send it... */
18609   S (mp);
18610
18611   /* Wait for a reply... */
18612   W (ret);
18613   return ret;
18614 }
18615
18616 static int
18617 api_one_map_register_set_ttl (vat_main_t * vam)
18618 {
18619   unformat_input_t *input = vam->input;
18620   vl_api_one_map_register_set_ttl_t *mp;
18621   u32 ttl = 0;
18622   u8 is_set = 0;
18623   int ret;
18624
18625   /* Parse args required to build the message */
18626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (input, "%u", &ttl))
18629         is_set = 1;
18630       else
18631         {
18632           clib_warning ("parse error '%U'", format_unformat_error, input);
18633           return -99;
18634         }
18635     }
18636
18637   if (!is_set)
18638     {
18639       errmsg ("TTL value missing!");
18640       return -99;
18641     }
18642
18643   M (ONE_MAP_REGISTER_SET_TTL, mp);
18644   mp->ttl = clib_host_to_net_u32 (ttl);
18645
18646   /* send it... */
18647   S (mp);
18648
18649   /* Wait for a reply... */
18650   W (ret);
18651   return ret;
18652 }
18653
18654 static int
18655 api_show_one_map_register_ttl (vat_main_t * vam)
18656 {
18657   vl_api_show_one_map_register_ttl_t *mp;
18658   int ret;
18659
18660   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18661
18662   /* send it... */
18663   S (mp);
18664
18665   /* Wait for a reply... */
18666   W (ret);
18667   return ret;
18668 }
18669
18670 /**
18671  * Add/del map request itr rlocs from ONE control plane and updates
18672  *
18673  * @param vam vpp API test context
18674  * @return return code
18675  */
18676 static int
18677 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18678 {
18679   unformat_input_t *input = vam->input;
18680   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18681   u8 *locator_set_name = 0;
18682   u8 locator_set_name_set = 0;
18683   u8 is_add = 1;
18684   int ret;
18685
18686   /* Parse args required to build the message */
18687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18688     {
18689       if (unformat (input, "del"))
18690         {
18691           is_add = 0;
18692         }
18693       else if (unformat (input, "%_%v%_", &locator_set_name))
18694         {
18695           locator_set_name_set = 1;
18696         }
18697       else
18698         {
18699           clib_warning ("parse error '%U'", format_unformat_error, input);
18700           return -99;
18701         }
18702     }
18703
18704   if (is_add && !locator_set_name_set)
18705     {
18706       errmsg ("itr-rloc is not set!");
18707       return -99;
18708     }
18709
18710   if (is_add && vec_len (locator_set_name) > 64)
18711     {
18712       errmsg ("itr-rloc locator-set name too long");
18713       vec_free (locator_set_name);
18714       return -99;
18715     }
18716
18717   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18718   mp->is_add = is_add;
18719   if (is_add)
18720     {
18721       clib_memcpy (mp->locator_set_name, locator_set_name,
18722                    vec_len (locator_set_name));
18723     }
18724   else
18725     {
18726       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18727     }
18728   vec_free (locator_set_name);
18729
18730   /* send it... */
18731   S (mp);
18732
18733   /* Wait for a reply... */
18734   W (ret);
18735   return ret;
18736 }
18737
18738 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18739
18740 static int
18741 api_one_locator_dump (vat_main_t * vam)
18742 {
18743   unformat_input_t *input = vam->input;
18744   vl_api_one_locator_dump_t *mp;
18745   vl_api_control_ping_t *mp_ping;
18746   u8 is_index_set = 0, is_name_set = 0;
18747   u8 *ls_name = 0;
18748   u32 ls_index = ~0;
18749   int ret;
18750
18751   /* Parse args required to build the message */
18752   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18753     {
18754       if (unformat (input, "ls_name %_%v%_", &ls_name))
18755         {
18756           is_name_set = 1;
18757         }
18758       else if (unformat (input, "ls_index %d", &ls_index))
18759         {
18760           is_index_set = 1;
18761         }
18762       else
18763         {
18764           errmsg ("parse error '%U'", format_unformat_error, input);
18765           return -99;
18766         }
18767     }
18768
18769   if (!is_index_set && !is_name_set)
18770     {
18771       errmsg ("error: expected one of index or name!");
18772       return -99;
18773     }
18774
18775   if (is_index_set && is_name_set)
18776     {
18777       errmsg ("error: only one param expected!");
18778       return -99;
18779     }
18780
18781   if (vec_len (ls_name) > 62)
18782     {
18783       errmsg ("error: locator set name too long!");
18784       return -99;
18785     }
18786
18787   if (!vam->json_output)
18788     {
18789       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18790     }
18791
18792   M (ONE_LOCATOR_DUMP, mp);
18793   mp->is_index_set = is_index_set;
18794
18795   if (is_index_set)
18796     mp->ls_index = clib_host_to_net_u32 (ls_index);
18797   else
18798     {
18799       vec_add1 (ls_name, 0);
18800       strncpy ((char *) mp->ls_name, (char *) ls_name,
18801                sizeof (mp->ls_name) - 1);
18802     }
18803
18804   /* send it... */
18805   S (mp);
18806
18807   /* Use a control ping for synchronization */
18808   MPING (CONTROL_PING, mp_ping);
18809   S (mp_ping);
18810
18811   /* Wait for a reply... */
18812   W (ret);
18813   return ret;
18814 }
18815
18816 #define api_lisp_locator_dump api_one_locator_dump
18817
18818 static int
18819 api_one_locator_set_dump (vat_main_t * vam)
18820 {
18821   vl_api_one_locator_set_dump_t *mp;
18822   vl_api_control_ping_t *mp_ping;
18823   unformat_input_t *input = vam->input;
18824   u8 filter = 0;
18825   int ret;
18826
18827   /* Parse args required to build the message */
18828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18829     {
18830       if (unformat (input, "local"))
18831         {
18832           filter = 1;
18833         }
18834       else if (unformat (input, "remote"))
18835         {
18836           filter = 2;
18837         }
18838       else
18839         {
18840           errmsg ("parse error '%U'", format_unformat_error, input);
18841           return -99;
18842         }
18843     }
18844
18845   if (!vam->json_output)
18846     {
18847       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18848     }
18849
18850   M (ONE_LOCATOR_SET_DUMP, mp);
18851
18852   mp->filter = filter;
18853
18854   /* send it... */
18855   S (mp);
18856
18857   /* Use a control ping for synchronization */
18858   MPING (CONTROL_PING, mp_ping);
18859   S (mp_ping);
18860
18861   /* Wait for a reply... */
18862   W (ret);
18863   return ret;
18864 }
18865
18866 #define api_lisp_locator_set_dump api_one_locator_set_dump
18867
18868 static int
18869 api_one_eid_table_map_dump (vat_main_t * vam)
18870 {
18871   u8 is_l2 = 0;
18872   u8 mode_set = 0;
18873   unformat_input_t *input = vam->input;
18874   vl_api_one_eid_table_map_dump_t *mp;
18875   vl_api_control_ping_t *mp_ping;
18876   int ret;
18877
18878   /* Parse args required to build the message */
18879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18880     {
18881       if (unformat (input, "l2"))
18882         {
18883           is_l2 = 1;
18884           mode_set = 1;
18885         }
18886       else if (unformat (input, "l3"))
18887         {
18888           is_l2 = 0;
18889           mode_set = 1;
18890         }
18891       else
18892         {
18893           errmsg ("parse error '%U'", format_unformat_error, input);
18894           return -99;
18895         }
18896     }
18897
18898   if (!mode_set)
18899     {
18900       errmsg ("expected one of 'l2' or 'l3' parameter!");
18901       return -99;
18902     }
18903
18904   if (!vam->json_output)
18905     {
18906       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18907     }
18908
18909   M (ONE_EID_TABLE_MAP_DUMP, mp);
18910   mp->is_l2 = is_l2;
18911
18912   /* send it... */
18913   S (mp);
18914
18915   /* Use a control ping for synchronization */
18916   MPING (CONTROL_PING, mp_ping);
18917   S (mp_ping);
18918
18919   /* Wait for a reply... */
18920   W (ret);
18921   return ret;
18922 }
18923
18924 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18925
18926 static int
18927 api_one_eid_table_vni_dump (vat_main_t * vam)
18928 {
18929   vl_api_one_eid_table_vni_dump_t *mp;
18930   vl_api_control_ping_t *mp_ping;
18931   int ret;
18932
18933   if (!vam->json_output)
18934     {
18935       print (vam->ofp, "VNI");
18936     }
18937
18938   M (ONE_EID_TABLE_VNI_DUMP, mp);
18939
18940   /* send it... */
18941   S (mp);
18942
18943   /* Use a control ping for synchronization */
18944   MPING (CONTROL_PING, mp_ping);
18945   S (mp_ping);
18946
18947   /* Wait for a reply... */
18948   W (ret);
18949   return ret;
18950 }
18951
18952 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18953
18954 static int
18955 api_one_eid_table_dump (vat_main_t * vam)
18956 {
18957   unformat_input_t *i = vam->input;
18958   vl_api_one_eid_table_dump_t *mp;
18959   vl_api_control_ping_t *mp_ping;
18960   struct in_addr ip4;
18961   struct in6_addr ip6;
18962   u8 mac[6];
18963   u8 eid_type = ~0, eid_set = 0;
18964   u32 prefix_length = ~0, t, vni = 0;
18965   u8 filter = 0;
18966   int ret;
18967   lisp_nsh_api_t nsh;
18968
18969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18970     {
18971       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18972         {
18973           eid_set = 1;
18974           eid_type = 0;
18975           prefix_length = t;
18976         }
18977       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18978         {
18979           eid_set = 1;
18980           eid_type = 1;
18981           prefix_length = t;
18982         }
18983       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18984         {
18985           eid_set = 1;
18986           eid_type = 2;
18987         }
18988       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18989         {
18990           eid_set = 1;
18991           eid_type = 3;
18992         }
18993       else if (unformat (i, "vni %d", &t))
18994         {
18995           vni = t;
18996         }
18997       else if (unformat (i, "local"))
18998         {
18999           filter = 1;
19000         }
19001       else if (unformat (i, "remote"))
19002         {
19003           filter = 2;
19004         }
19005       else
19006         {
19007           errmsg ("parse error '%U'", format_unformat_error, i);
19008           return -99;
19009         }
19010     }
19011
19012   if (!vam->json_output)
19013     {
19014       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19015              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19016     }
19017
19018   M (ONE_EID_TABLE_DUMP, mp);
19019
19020   mp->filter = filter;
19021   if (eid_set)
19022     {
19023       mp->eid_set = 1;
19024       mp->vni = htonl (vni);
19025       mp->eid_type = eid_type;
19026       switch (eid_type)
19027         {
19028         case 0:
19029           mp->prefix_length = prefix_length;
19030           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19031           break;
19032         case 1:
19033           mp->prefix_length = prefix_length;
19034           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19035           break;
19036         case 2:
19037           clib_memcpy (mp->eid, mac, sizeof (mac));
19038           break;
19039         case 3:
19040           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19041           break;
19042         default:
19043           errmsg ("unknown EID type %d!", eid_type);
19044           return -99;
19045         }
19046     }
19047
19048   /* send it... */
19049   S (mp);
19050
19051   /* Use a control ping for synchronization */
19052   MPING (CONTROL_PING, mp_ping);
19053   S (mp_ping);
19054
19055   /* Wait for a reply... */
19056   W (ret);
19057   return ret;
19058 }
19059
19060 #define api_lisp_eid_table_dump api_one_eid_table_dump
19061
19062 static int
19063 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19064 {
19065   unformat_input_t *i = vam->input;
19066   vl_api_gpe_fwd_entries_get_t *mp;
19067   u8 vni_set = 0;
19068   u32 vni = ~0;
19069   int ret;
19070
19071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19072     {
19073       if (unformat (i, "vni %d", &vni))
19074         {
19075           vni_set = 1;
19076         }
19077       else
19078         {
19079           errmsg ("parse error '%U'", format_unformat_error, i);
19080           return -99;
19081         }
19082     }
19083
19084   if (!vni_set)
19085     {
19086       errmsg ("vni not set!");
19087       return -99;
19088     }
19089
19090   if (!vam->json_output)
19091     {
19092       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19093              "leid", "reid");
19094     }
19095
19096   M (GPE_FWD_ENTRIES_GET, mp);
19097   mp->vni = clib_host_to_net_u32 (vni);
19098
19099   /* send it... */
19100   S (mp);
19101
19102   /* Wait for a reply... */
19103   W (ret);
19104   return ret;
19105 }
19106
19107 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19108 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19109 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19110 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19111 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19112 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19113 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19114 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19115
19116 static int
19117 api_one_adjacencies_get (vat_main_t * vam)
19118 {
19119   unformat_input_t *i = vam->input;
19120   vl_api_one_adjacencies_get_t *mp;
19121   u8 vni_set = 0;
19122   u32 vni = ~0;
19123   int ret;
19124
19125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19126     {
19127       if (unformat (i, "vni %d", &vni))
19128         {
19129           vni_set = 1;
19130         }
19131       else
19132         {
19133           errmsg ("parse error '%U'", format_unformat_error, i);
19134           return -99;
19135         }
19136     }
19137
19138   if (!vni_set)
19139     {
19140       errmsg ("vni not set!");
19141       return -99;
19142     }
19143
19144   if (!vam->json_output)
19145     {
19146       print (vam->ofp, "%s %40s", "leid", "reid");
19147     }
19148
19149   M (ONE_ADJACENCIES_GET, mp);
19150   mp->vni = clib_host_to_net_u32 (vni);
19151
19152   /* send it... */
19153   S (mp);
19154
19155   /* Wait for a reply... */
19156   W (ret);
19157   return ret;
19158 }
19159
19160 #define api_lisp_adjacencies_get api_one_adjacencies_get
19161
19162 static int
19163 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19164 {
19165   unformat_input_t *i = vam->input;
19166   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19167   int ret;
19168   u8 ip_family_set = 0, is_ip4 = 1;
19169
19170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19171     {
19172       if (unformat (i, "ip4"))
19173         {
19174           ip_family_set = 1;
19175           is_ip4 = 1;
19176         }
19177       else if (unformat (i, "ip6"))
19178         {
19179           ip_family_set = 1;
19180           is_ip4 = 0;
19181         }
19182       else
19183         {
19184           errmsg ("parse error '%U'", format_unformat_error, i);
19185           return -99;
19186         }
19187     }
19188
19189   if (!ip_family_set)
19190     {
19191       errmsg ("ip family not set!");
19192       return -99;
19193     }
19194
19195   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19196   mp->is_ip4 = is_ip4;
19197
19198   /* send it... */
19199   S (mp);
19200
19201   /* Wait for a reply... */
19202   W (ret);
19203   return ret;
19204 }
19205
19206 static int
19207 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19208 {
19209   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19210   int ret;
19211
19212   if (!vam->json_output)
19213     {
19214       print (vam->ofp, "VNIs");
19215     }
19216
19217   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19218
19219   /* send it... */
19220   S (mp);
19221
19222   /* Wait for a reply... */
19223   W (ret);
19224   return ret;
19225 }
19226
19227 static int
19228 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19229 {
19230   unformat_input_t *i = vam->input;
19231   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19232   int ret = 0;
19233   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19234   struct in_addr ip4;
19235   struct in6_addr ip6;
19236   u32 table_id = 0, nh_sw_if_index = ~0;
19237
19238   memset (&ip4, 0, sizeof (ip4));
19239   memset (&ip6, 0, sizeof (ip6));
19240
19241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19242     {
19243       if (unformat (i, "del"))
19244         is_add = 0;
19245       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19246                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19247         {
19248           ip_set = 1;
19249           is_ip4 = 1;
19250         }
19251       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19252                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19253         {
19254           ip_set = 1;
19255           is_ip4 = 0;
19256         }
19257       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19258         {
19259           ip_set = 1;
19260           is_ip4 = 1;
19261           nh_sw_if_index = ~0;
19262         }
19263       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19264         {
19265           ip_set = 1;
19266           is_ip4 = 0;
19267           nh_sw_if_index = ~0;
19268         }
19269       else if (unformat (i, "table %d", &table_id))
19270         ;
19271       else
19272         {
19273           errmsg ("parse error '%U'", format_unformat_error, i);
19274           return -99;
19275         }
19276     }
19277
19278   if (!ip_set)
19279     {
19280       errmsg ("nh addr not set!");
19281       return -99;
19282     }
19283
19284   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19285   mp->is_add = is_add;
19286   mp->table_id = clib_host_to_net_u32 (table_id);
19287   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19288   mp->is_ip4 = is_ip4;
19289   if (is_ip4)
19290     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19291   else
19292     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19293
19294   /* send it... */
19295   S (mp);
19296
19297   /* Wait for a reply... */
19298   W (ret);
19299   return ret;
19300 }
19301
19302 static int
19303 api_one_map_server_dump (vat_main_t * vam)
19304 {
19305   vl_api_one_map_server_dump_t *mp;
19306   vl_api_control_ping_t *mp_ping;
19307   int ret;
19308
19309   if (!vam->json_output)
19310     {
19311       print (vam->ofp, "%=20s", "Map server");
19312     }
19313
19314   M (ONE_MAP_SERVER_DUMP, mp);
19315   /* send it... */
19316   S (mp);
19317
19318   /* Use a control ping for synchronization */
19319   MPING (CONTROL_PING, mp_ping);
19320   S (mp_ping);
19321
19322   /* Wait for a reply... */
19323   W (ret);
19324   return ret;
19325 }
19326
19327 #define api_lisp_map_server_dump api_one_map_server_dump
19328
19329 static int
19330 api_one_map_resolver_dump (vat_main_t * vam)
19331 {
19332   vl_api_one_map_resolver_dump_t *mp;
19333   vl_api_control_ping_t *mp_ping;
19334   int ret;
19335
19336   if (!vam->json_output)
19337     {
19338       print (vam->ofp, "%=20s", "Map resolver");
19339     }
19340
19341   M (ONE_MAP_RESOLVER_DUMP, mp);
19342   /* send it... */
19343   S (mp);
19344
19345   /* Use a control ping for synchronization */
19346   MPING (CONTROL_PING, mp_ping);
19347   S (mp_ping);
19348
19349   /* Wait for a reply... */
19350   W (ret);
19351   return ret;
19352 }
19353
19354 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19355
19356 static int
19357 api_one_stats_flush (vat_main_t * vam)
19358 {
19359   vl_api_one_stats_flush_t *mp;
19360   int ret = 0;
19361
19362   M (ONE_STATS_FLUSH, mp);
19363   S (mp);
19364   W (ret);
19365   return ret;
19366 }
19367
19368 static int
19369 api_one_stats_dump (vat_main_t * vam)
19370 {
19371   vl_api_one_stats_dump_t *mp;
19372   vl_api_control_ping_t *mp_ping;
19373   int ret;
19374
19375   M (ONE_STATS_DUMP, mp);
19376   /* send it... */
19377   S (mp);
19378
19379   /* Use a control ping for synchronization */
19380   MPING (CONTROL_PING, mp_ping);
19381   S (mp_ping);
19382
19383   /* Wait for a reply... */
19384   W (ret);
19385   return ret;
19386 }
19387
19388 static int
19389 api_show_one_status (vat_main_t * vam)
19390 {
19391   vl_api_show_one_status_t *mp;
19392   int ret;
19393
19394   if (!vam->json_output)
19395     {
19396       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19397     }
19398
19399   M (SHOW_ONE_STATUS, mp);
19400   /* send it... */
19401   S (mp);
19402   /* Wait for a reply... */
19403   W (ret);
19404   return ret;
19405 }
19406
19407 #define api_show_lisp_status api_show_one_status
19408
19409 static int
19410 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19411 {
19412   vl_api_gpe_fwd_entry_path_dump_t *mp;
19413   vl_api_control_ping_t *mp_ping;
19414   unformat_input_t *i = vam->input;
19415   u32 fwd_entry_index = ~0;
19416   int ret;
19417
19418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19419     {
19420       if (unformat (i, "index %d", &fwd_entry_index))
19421         ;
19422       else
19423         break;
19424     }
19425
19426   if (~0 == fwd_entry_index)
19427     {
19428       errmsg ("no index specified!");
19429       return -99;
19430     }
19431
19432   if (!vam->json_output)
19433     {
19434       print (vam->ofp, "first line");
19435     }
19436
19437   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19438
19439   /* send it... */
19440   S (mp);
19441   /* Use a control ping for synchronization */
19442   MPING (CONTROL_PING, mp_ping);
19443   S (mp_ping);
19444
19445   /* Wait for a reply... */
19446   W (ret);
19447   return ret;
19448 }
19449
19450 static int
19451 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19452 {
19453   vl_api_one_get_map_request_itr_rlocs_t *mp;
19454   int ret;
19455
19456   if (!vam->json_output)
19457     {
19458       print (vam->ofp, "%=20s", "itr-rlocs:");
19459     }
19460
19461   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19462   /* send it... */
19463   S (mp);
19464   /* Wait for a reply... */
19465   W (ret);
19466   return ret;
19467 }
19468
19469 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19470
19471 static int
19472 api_af_packet_create (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_af_packet_create_t *mp;
19476   u8 *host_if_name = 0;
19477   u8 hw_addr[6];
19478   u8 random_hw_addr = 1;
19479   int ret;
19480
19481   memset (hw_addr, 0, sizeof (hw_addr));
19482
19483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19484     {
19485       if (unformat (i, "name %s", &host_if_name))
19486         vec_add1 (host_if_name, 0);
19487       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19488         random_hw_addr = 0;
19489       else
19490         break;
19491     }
19492
19493   if (!vec_len (host_if_name))
19494     {
19495       errmsg ("host-interface name must be specified");
19496       return -99;
19497     }
19498
19499   if (vec_len (host_if_name) > 64)
19500     {
19501       errmsg ("host-interface name too long");
19502       return -99;
19503     }
19504
19505   M (AF_PACKET_CREATE, mp);
19506
19507   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19508   clib_memcpy (mp->hw_addr, hw_addr, 6);
19509   mp->use_random_hw_addr = random_hw_addr;
19510   vec_free (host_if_name);
19511
19512   S (mp);
19513
19514   /* *INDENT-OFF* */
19515   W2 (ret,
19516       ({
19517         if (ret == 0)
19518           fprintf (vam->ofp ? vam->ofp : stderr,
19519                    " new sw_if_index = %d\n", vam->sw_if_index);
19520       }));
19521   /* *INDENT-ON* */
19522   return ret;
19523 }
19524
19525 static int
19526 api_af_packet_delete (vat_main_t * vam)
19527 {
19528   unformat_input_t *i = vam->input;
19529   vl_api_af_packet_delete_t *mp;
19530   u8 *host_if_name = 0;
19531   int ret;
19532
19533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19534     {
19535       if (unformat (i, "name %s", &host_if_name))
19536         vec_add1 (host_if_name, 0);
19537       else
19538         break;
19539     }
19540
19541   if (!vec_len (host_if_name))
19542     {
19543       errmsg ("host-interface name must be specified");
19544       return -99;
19545     }
19546
19547   if (vec_len (host_if_name) > 64)
19548     {
19549       errmsg ("host-interface name too long");
19550       return -99;
19551     }
19552
19553   M (AF_PACKET_DELETE, mp);
19554
19555   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19556   vec_free (host_if_name);
19557
19558   S (mp);
19559   W (ret);
19560   return ret;
19561 }
19562
19563 static void vl_api_af_packet_details_t_handler
19564   (vl_api_af_packet_details_t * mp)
19565 {
19566   vat_main_t *vam = &vat_main;
19567
19568   print (vam->ofp, "%-16s %d",
19569          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19570 }
19571
19572 static void vl_api_af_packet_details_t_handler_json
19573   (vl_api_af_packet_details_t * mp)
19574 {
19575   vat_main_t *vam = &vat_main;
19576   vat_json_node_t *node = NULL;
19577
19578   if (VAT_JSON_ARRAY != vam->json_tree.type)
19579     {
19580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19581       vat_json_init_array (&vam->json_tree);
19582     }
19583   node = vat_json_array_add (&vam->json_tree);
19584
19585   vat_json_init_object (node);
19586   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19587   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19588 }
19589
19590 static int
19591 api_af_packet_dump (vat_main_t * vam)
19592 {
19593   vl_api_af_packet_dump_t *mp;
19594   vl_api_control_ping_t *mp_ping;
19595   int ret;
19596
19597   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19598   /* Get list of tap interfaces */
19599   M (AF_PACKET_DUMP, mp);
19600   S (mp);
19601
19602   /* Use a control ping for synchronization */
19603   MPING (CONTROL_PING, mp_ping);
19604   S (mp_ping);
19605
19606   W (ret);
19607   return ret;
19608 }
19609
19610 static int
19611 api_policer_add_del (vat_main_t * vam)
19612 {
19613   unformat_input_t *i = vam->input;
19614   vl_api_policer_add_del_t *mp;
19615   u8 is_add = 1;
19616   u8 *name = 0;
19617   u32 cir = 0;
19618   u32 eir = 0;
19619   u64 cb = 0;
19620   u64 eb = 0;
19621   u8 rate_type = 0;
19622   u8 round_type = 0;
19623   u8 type = 0;
19624   u8 color_aware = 0;
19625   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19626   int ret;
19627
19628   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19629   conform_action.dscp = 0;
19630   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19631   exceed_action.dscp = 0;
19632   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19633   violate_action.dscp = 0;
19634
19635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19636     {
19637       if (unformat (i, "del"))
19638         is_add = 0;
19639       else if (unformat (i, "name %s", &name))
19640         vec_add1 (name, 0);
19641       else if (unformat (i, "cir %u", &cir))
19642         ;
19643       else if (unformat (i, "eir %u", &eir))
19644         ;
19645       else if (unformat (i, "cb %u", &cb))
19646         ;
19647       else if (unformat (i, "eb %u", &eb))
19648         ;
19649       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19650                          &rate_type))
19651         ;
19652       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19653                          &round_type))
19654         ;
19655       else if (unformat (i, "type %U", unformat_policer_type, &type))
19656         ;
19657       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19658                          &conform_action))
19659         ;
19660       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19661                          &exceed_action))
19662         ;
19663       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19664                          &violate_action))
19665         ;
19666       else if (unformat (i, "color-aware"))
19667         color_aware = 1;
19668       else
19669         break;
19670     }
19671
19672   if (!vec_len (name))
19673     {
19674       errmsg ("policer name must be specified");
19675       return -99;
19676     }
19677
19678   if (vec_len (name) > 64)
19679     {
19680       errmsg ("policer name too long");
19681       return -99;
19682     }
19683
19684   M (POLICER_ADD_DEL, mp);
19685
19686   clib_memcpy (mp->name, name, vec_len (name));
19687   vec_free (name);
19688   mp->is_add = is_add;
19689   mp->cir = ntohl (cir);
19690   mp->eir = ntohl (eir);
19691   mp->cb = clib_net_to_host_u64 (cb);
19692   mp->eb = clib_net_to_host_u64 (eb);
19693   mp->rate_type = rate_type;
19694   mp->round_type = round_type;
19695   mp->type = type;
19696   mp->conform_action_type = conform_action.action_type;
19697   mp->conform_dscp = conform_action.dscp;
19698   mp->exceed_action_type = exceed_action.action_type;
19699   mp->exceed_dscp = exceed_action.dscp;
19700   mp->violate_action_type = violate_action.action_type;
19701   mp->violate_dscp = violate_action.dscp;
19702   mp->color_aware = color_aware;
19703
19704   S (mp);
19705   W (ret);
19706   return ret;
19707 }
19708
19709 static int
19710 api_policer_dump (vat_main_t * vam)
19711 {
19712   unformat_input_t *i = vam->input;
19713   vl_api_policer_dump_t *mp;
19714   vl_api_control_ping_t *mp_ping;
19715   u8 *match_name = 0;
19716   u8 match_name_valid = 0;
19717   int ret;
19718
19719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (i, "name %s", &match_name))
19722         {
19723           vec_add1 (match_name, 0);
19724           match_name_valid = 1;
19725         }
19726       else
19727         break;
19728     }
19729
19730   M (POLICER_DUMP, mp);
19731   mp->match_name_valid = match_name_valid;
19732   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19733   vec_free (match_name);
19734   /* send it... */
19735   S (mp);
19736
19737   /* Use a control ping for synchronization */
19738   MPING (CONTROL_PING, mp_ping);
19739   S (mp_ping);
19740
19741   /* Wait for a reply... */
19742   W (ret);
19743   return ret;
19744 }
19745
19746 static int
19747 api_policer_classify_set_interface (vat_main_t * vam)
19748 {
19749   unformat_input_t *i = vam->input;
19750   vl_api_policer_classify_set_interface_t *mp;
19751   u32 sw_if_index;
19752   int sw_if_index_set;
19753   u32 ip4_table_index = ~0;
19754   u32 ip6_table_index = ~0;
19755   u32 l2_table_index = ~0;
19756   u8 is_add = 1;
19757   int ret;
19758
19759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19760     {
19761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19762         sw_if_index_set = 1;
19763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19764         sw_if_index_set = 1;
19765       else if (unformat (i, "del"))
19766         is_add = 0;
19767       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19768         ;
19769       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19770         ;
19771       else if (unformat (i, "l2-table %d", &l2_table_index))
19772         ;
19773       else
19774         {
19775           clib_warning ("parse error '%U'", format_unformat_error, i);
19776           return -99;
19777         }
19778     }
19779
19780   if (sw_if_index_set == 0)
19781     {
19782       errmsg ("missing interface name or sw_if_index");
19783       return -99;
19784     }
19785
19786   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19787
19788   mp->sw_if_index = ntohl (sw_if_index);
19789   mp->ip4_table_index = ntohl (ip4_table_index);
19790   mp->ip6_table_index = ntohl (ip6_table_index);
19791   mp->l2_table_index = ntohl (l2_table_index);
19792   mp->is_add = is_add;
19793
19794   S (mp);
19795   W (ret);
19796   return ret;
19797 }
19798
19799 static int
19800 api_policer_classify_dump (vat_main_t * vam)
19801 {
19802   unformat_input_t *i = vam->input;
19803   vl_api_policer_classify_dump_t *mp;
19804   vl_api_control_ping_t *mp_ping;
19805   u8 type = POLICER_CLASSIFY_N_TABLES;
19806   int ret;
19807
19808   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19809     ;
19810   else
19811     {
19812       errmsg ("classify table type must be specified");
19813       return -99;
19814     }
19815
19816   if (!vam->json_output)
19817     {
19818       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19819     }
19820
19821   M (POLICER_CLASSIFY_DUMP, mp);
19822   mp->type = type;
19823   /* send it... */
19824   S (mp);
19825
19826   /* Use a control ping for synchronization */
19827   MPING (CONTROL_PING, mp_ping);
19828   S (mp_ping);
19829
19830   /* Wait for a reply... */
19831   W (ret);
19832   return ret;
19833 }
19834
19835 static int
19836 api_netmap_create (vat_main_t * vam)
19837 {
19838   unformat_input_t *i = vam->input;
19839   vl_api_netmap_create_t *mp;
19840   u8 *if_name = 0;
19841   u8 hw_addr[6];
19842   u8 random_hw_addr = 1;
19843   u8 is_pipe = 0;
19844   u8 is_master = 0;
19845   int ret;
19846
19847   memset (hw_addr, 0, sizeof (hw_addr));
19848
19849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19850     {
19851       if (unformat (i, "name %s", &if_name))
19852         vec_add1 (if_name, 0);
19853       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19854         random_hw_addr = 0;
19855       else if (unformat (i, "pipe"))
19856         is_pipe = 1;
19857       else if (unformat (i, "master"))
19858         is_master = 1;
19859       else if (unformat (i, "slave"))
19860         is_master = 0;
19861       else
19862         break;
19863     }
19864
19865   if (!vec_len (if_name))
19866     {
19867       errmsg ("interface name must be specified");
19868       return -99;
19869     }
19870
19871   if (vec_len (if_name) > 64)
19872     {
19873       errmsg ("interface name too long");
19874       return -99;
19875     }
19876
19877   M (NETMAP_CREATE, mp);
19878
19879   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19880   clib_memcpy (mp->hw_addr, hw_addr, 6);
19881   mp->use_random_hw_addr = random_hw_addr;
19882   mp->is_pipe = is_pipe;
19883   mp->is_master = is_master;
19884   vec_free (if_name);
19885
19886   S (mp);
19887   W (ret);
19888   return ret;
19889 }
19890
19891 static int
19892 api_netmap_delete (vat_main_t * vam)
19893 {
19894   unformat_input_t *i = vam->input;
19895   vl_api_netmap_delete_t *mp;
19896   u8 *if_name = 0;
19897   int ret;
19898
19899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19900     {
19901       if (unformat (i, "name %s", &if_name))
19902         vec_add1 (if_name, 0);
19903       else
19904         break;
19905     }
19906
19907   if (!vec_len (if_name))
19908     {
19909       errmsg ("interface name must be specified");
19910       return -99;
19911     }
19912
19913   if (vec_len (if_name) > 64)
19914     {
19915       errmsg ("interface name too long");
19916       return -99;
19917     }
19918
19919   M (NETMAP_DELETE, mp);
19920
19921   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19922   vec_free (if_name);
19923
19924   S (mp);
19925   W (ret);
19926   return ret;
19927 }
19928
19929 static void
19930 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19931 {
19932   if (fp->afi == IP46_TYPE_IP6)
19933     print (vam->ofp,
19934            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19935            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19936            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19937            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19938            format_ip6_address, fp->next_hop);
19939   else if (fp->afi == IP46_TYPE_IP4)
19940     print (vam->ofp,
19941            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19942            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19943            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19944            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19945            format_ip4_address, fp->next_hop);
19946 }
19947
19948 static void
19949 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19950                                  vl_api_fib_path_t * fp)
19951 {
19952   struct in_addr ip4;
19953   struct in6_addr ip6;
19954
19955   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19956   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19957   vat_json_object_add_uint (node, "is_local", fp->is_local);
19958   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19959   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19960   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19961   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19962   if (fp->afi == IP46_TYPE_IP4)
19963     {
19964       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19965       vat_json_object_add_ip4 (node, "next_hop", ip4);
19966     }
19967   else if (fp->afi == IP46_TYPE_IP6)
19968     {
19969       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19970       vat_json_object_add_ip6 (node, "next_hop", ip6);
19971     }
19972 }
19973
19974 static void
19975 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19976 {
19977   vat_main_t *vam = &vat_main;
19978   int count = ntohl (mp->mt_count);
19979   vl_api_fib_path_t *fp;
19980   i32 i;
19981
19982   print (vam->ofp, "[%d]: sw_if_index %d via:",
19983          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19984   fp = mp->mt_paths;
19985   for (i = 0; i < count; i++)
19986     {
19987       vl_api_mpls_fib_path_print (vam, fp);
19988       fp++;
19989     }
19990
19991   print (vam->ofp, "");
19992 }
19993
19994 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19995 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19996
19997 static void
19998 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19999 {
20000   vat_main_t *vam = &vat_main;
20001   vat_json_node_t *node = NULL;
20002   int count = ntohl (mp->mt_count);
20003   vl_api_fib_path_t *fp;
20004   i32 i;
20005
20006   if (VAT_JSON_ARRAY != vam->json_tree.type)
20007     {
20008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20009       vat_json_init_array (&vam->json_tree);
20010     }
20011   node = vat_json_array_add (&vam->json_tree);
20012
20013   vat_json_init_object (node);
20014   vat_json_object_add_uint (node, "tunnel_index",
20015                             ntohl (mp->mt_tunnel_index));
20016   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20017
20018   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20019
20020   fp = mp->mt_paths;
20021   for (i = 0; i < count; i++)
20022     {
20023       vl_api_mpls_fib_path_json_print (node, fp);
20024       fp++;
20025     }
20026 }
20027
20028 static int
20029 api_mpls_tunnel_dump (vat_main_t * vam)
20030 {
20031   vl_api_mpls_tunnel_dump_t *mp;
20032   vl_api_control_ping_t *mp_ping;
20033   i32 index = -1;
20034   int ret;
20035
20036   /* Parse args required to build the message */
20037   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20038     {
20039       if (!unformat (vam->input, "tunnel_index %d", &index))
20040         {
20041           index = -1;
20042           break;
20043         }
20044     }
20045
20046   print (vam->ofp, "  tunnel_index %d", index);
20047
20048   M (MPLS_TUNNEL_DUMP, mp);
20049   mp->tunnel_index = htonl (index);
20050   S (mp);
20051
20052   /* Use a control ping for synchronization */
20053   MPING (CONTROL_PING, mp_ping);
20054   S (mp_ping);
20055
20056   W (ret);
20057   return ret;
20058 }
20059
20060 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20061 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20062
20063
20064 static void
20065 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20066 {
20067   vat_main_t *vam = &vat_main;
20068   int count = ntohl (mp->count);
20069   vl_api_fib_path_t *fp;
20070   int i;
20071
20072   print (vam->ofp,
20073          "table-id %d, label %u, ess_bit %u",
20074          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20075   fp = mp->path;
20076   for (i = 0; i < count; i++)
20077     {
20078       vl_api_mpls_fib_path_print (vam, fp);
20079       fp++;
20080     }
20081 }
20082
20083 static void vl_api_mpls_fib_details_t_handler_json
20084   (vl_api_mpls_fib_details_t * mp)
20085 {
20086   vat_main_t *vam = &vat_main;
20087   int count = ntohl (mp->count);
20088   vat_json_node_t *node = NULL;
20089   vl_api_fib_path_t *fp;
20090   int i;
20091
20092   if (VAT_JSON_ARRAY != vam->json_tree.type)
20093     {
20094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20095       vat_json_init_array (&vam->json_tree);
20096     }
20097   node = vat_json_array_add (&vam->json_tree);
20098
20099   vat_json_init_object (node);
20100   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20101   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20102   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20103   vat_json_object_add_uint (node, "path_count", count);
20104   fp = mp->path;
20105   for (i = 0; i < count; i++)
20106     {
20107       vl_api_mpls_fib_path_json_print (node, fp);
20108       fp++;
20109     }
20110 }
20111
20112 static int
20113 api_mpls_fib_dump (vat_main_t * vam)
20114 {
20115   vl_api_mpls_fib_dump_t *mp;
20116   vl_api_control_ping_t *mp_ping;
20117   int ret;
20118
20119   M (MPLS_FIB_DUMP, mp);
20120   S (mp);
20121
20122   /* Use a control ping for synchronization */
20123   MPING (CONTROL_PING, mp_ping);
20124   S (mp_ping);
20125
20126   W (ret);
20127   return ret;
20128 }
20129
20130 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20131 #define vl_api_ip_fib_details_t_print vl_noop_handler
20132
20133 static void
20134 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20135 {
20136   vat_main_t *vam = &vat_main;
20137   int count = ntohl (mp->count);
20138   vl_api_fib_path_t *fp;
20139   int i;
20140
20141   print (vam->ofp,
20142          "table-id %d, prefix %U/%d",
20143          ntohl (mp->table_id), format_ip4_address, mp->address,
20144          mp->address_length);
20145   fp = mp->path;
20146   for (i = 0; i < count; i++)
20147     {
20148       if (fp->afi == IP46_TYPE_IP6)
20149         print (vam->ofp,
20150                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20151                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20152                "next_hop_table %d",
20153                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20154                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20155                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20156       else if (fp->afi == IP46_TYPE_IP4)
20157         print (vam->ofp,
20158                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20159                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20160                "next_hop_table %d",
20161                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20162                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20163                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20164       fp++;
20165     }
20166 }
20167
20168 static void vl_api_ip_fib_details_t_handler_json
20169   (vl_api_ip_fib_details_t * mp)
20170 {
20171   vat_main_t *vam = &vat_main;
20172   int count = ntohl (mp->count);
20173   vat_json_node_t *node = NULL;
20174   struct in_addr ip4;
20175   struct in6_addr ip6;
20176   vl_api_fib_path_t *fp;
20177   int i;
20178
20179   if (VAT_JSON_ARRAY != vam->json_tree.type)
20180     {
20181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20182       vat_json_init_array (&vam->json_tree);
20183     }
20184   node = vat_json_array_add (&vam->json_tree);
20185
20186   vat_json_init_object (node);
20187   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20188   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20189   vat_json_object_add_ip4 (node, "prefix", ip4);
20190   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20191   vat_json_object_add_uint (node, "path_count", count);
20192   fp = mp->path;
20193   for (i = 0; i < count; i++)
20194     {
20195       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20196       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20197       vat_json_object_add_uint (node, "is_local", fp->is_local);
20198       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20199       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20200       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20201       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20202       if (fp->afi == IP46_TYPE_IP4)
20203         {
20204           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20205           vat_json_object_add_ip4 (node, "next_hop", ip4);
20206         }
20207       else if (fp->afi == IP46_TYPE_IP6)
20208         {
20209           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20210           vat_json_object_add_ip6 (node, "next_hop", ip6);
20211         }
20212     }
20213 }
20214
20215 static int
20216 api_ip_fib_dump (vat_main_t * vam)
20217 {
20218   vl_api_ip_fib_dump_t *mp;
20219   vl_api_control_ping_t *mp_ping;
20220   int ret;
20221
20222   M (IP_FIB_DUMP, mp);
20223   S (mp);
20224
20225   /* Use a control ping for synchronization */
20226   MPING (CONTROL_PING, mp_ping);
20227   S (mp_ping);
20228
20229   W (ret);
20230   return ret;
20231 }
20232
20233 static int
20234 api_ip_mfib_dump (vat_main_t * vam)
20235 {
20236   vl_api_ip_mfib_dump_t *mp;
20237   vl_api_control_ping_t *mp_ping;
20238   int ret;
20239
20240   M (IP_MFIB_DUMP, mp);
20241   S (mp);
20242
20243   /* Use a control ping for synchronization */
20244   MPING (CONTROL_PING, mp_ping);
20245   S (mp_ping);
20246
20247   W (ret);
20248   return ret;
20249 }
20250
20251 static void vl_api_ip_neighbor_details_t_handler
20252   (vl_api_ip_neighbor_details_t * mp)
20253 {
20254   vat_main_t *vam = &vat_main;
20255
20256   print (vam->ofp, "%c %U %U",
20257          (mp->is_static) ? 'S' : 'D',
20258          format_ethernet_address, &mp->mac_address,
20259          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20260          &mp->ip_address);
20261 }
20262
20263 static void vl_api_ip_neighbor_details_t_handler_json
20264   (vl_api_ip_neighbor_details_t * mp)
20265 {
20266
20267   vat_main_t *vam = &vat_main;
20268   vat_json_node_t *node;
20269   struct in_addr ip4;
20270   struct in6_addr ip6;
20271
20272   if (VAT_JSON_ARRAY != vam->json_tree.type)
20273     {
20274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20275       vat_json_init_array (&vam->json_tree);
20276     }
20277   node = vat_json_array_add (&vam->json_tree);
20278
20279   vat_json_init_object (node);
20280   vat_json_object_add_string_copy (node, "flag",
20281                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20282                                    "dynamic");
20283
20284   vat_json_object_add_string_copy (node, "link_layer",
20285                                    format (0, "%U", format_ethernet_address,
20286                                            &mp->mac_address));
20287
20288   if (mp->is_ipv6)
20289     {
20290       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20291       vat_json_object_add_ip6 (node, "ip_address", ip6);
20292     }
20293   else
20294     {
20295       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20296       vat_json_object_add_ip4 (node, "ip_address", ip4);
20297     }
20298 }
20299
20300 static int
20301 api_ip_neighbor_dump (vat_main_t * vam)
20302 {
20303   unformat_input_t *i = vam->input;
20304   vl_api_ip_neighbor_dump_t *mp;
20305   vl_api_control_ping_t *mp_ping;
20306   u8 is_ipv6 = 0;
20307   u32 sw_if_index = ~0;
20308   int ret;
20309
20310   /* Parse args required to build the message */
20311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20312     {
20313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20314         ;
20315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20316         ;
20317       else if (unformat (i, "ip6"))
20318         is_ipv6 = 1;
20319       else
20320         break;
20321     }
20322
20323   if (sw_if_index == ~0)
20324     {
20325       errmsg ("missing interface name or sw_if_index");
20326       return -99;
20327     }
20328
20329   M (IP_NEIGHBOR_DUMP, mp);
20330   mp->is_ipv6 = (u8) is_ipv6;
20331   mp->sw_if_index = ntohl (sw_if_index);
20332   S (mp);
20333
20334   /* Use a control ping for synchronization */
20335   MPING (CONTROL_PING, mp_ping);
20336   S (mp_ping);
20337
20338   W (ret);
20339   return ret;
20340 }
20341
20342 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20343 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20344
20345 static void
20346 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20347 {
20348   vat_main_t *vam = &vat_main;
20349   int count = ntohl (mp->count);
20350   vl_api_fib_path_t *fp;
20351   int i;
20352
20353   print (vam->ofp,
20354          "table-id %d, prefix %U/%d",
20355          ntohl (mp->table_id), format_ip6_address, mp->address,
20356          mp->address_length);
20357   fp = mp->path;
20358   for (i = 0; i < count; i++)
20359     {
20360       if (fp->afi == IP46_TYPE_IP6)
20361         print (vam->ofp,
20362                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20363                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20364                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20365                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20366                format_ip6_address, fp->next_hop);
20367       else if (fp->afi == IP46_TYPE_IP4)
20368         print (vam->ofp,
20369                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20370                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20371                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20372                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20373                format_ip4_address, fp->next_hop);
20374       fp++;
20375     }
20376 }
20377
20378 static void vl_api_ip6_fib_details_t_handler_json
20379   (vl_api_ip6_fib_details_t * mp)
20380 {
20381   vat_main_t *vam = &vat_main;
20382   int count = ntohl (mp->count);
20383   vat_json_node_t *node = NULL;
20384   struct in_addr ip4;
20385   struct in6_addr ip6;
20386   vl_api_fib_path_t *fp;
20387   int i;
20388
20389   if (VAT_JSON_ARRAY != vam->json_tree.type)
20390     {
20391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20392       vat_json_init_array (&vam->json_tree);
20393     }
20394   node = vat_json_array_add (&vam->json_tree);
20395
20396   vat_json_init_object (node);
20397   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20398   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20399   vat_json_object_add_ip6 (node, "prefix", ip6);
20400   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20401   vat_json_object_add_uint (node, "path_count", count);
20402   fp = mp->path;
20403   for (i = 0; i < count; i++)
20404     {
20405       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20406       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20407       vat_json_object_add_uint (node, "is_local", fp->is_local);
20408       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20409       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20410       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20411       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20412       if (fp->afi == IP46_TYPE_IP4)
20413         {
20414           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20415           vat_json_object_add_ip4 (node, "next_hop", ip4);
20416         }
20417       else if (fp->afi == IP46_TYPE_IP6)
20418         {
20419           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20420           vat_json_object_add_ip6 (node, "next_hop", ip6);
20421         }
20422     }
20423 }
20424
20425 static int
20426 api_ip6_fib_dump (vat_main_t * vam)
20427 {
20428   vl_api_ip6_fib_dump_t *mp;
20429   vl_api_control_ping_t *mp_ping;
20430   int ret;
20431
20432   M (IP6_FIB_DUMP, mp);
20433   S (mp);
20434
20435   /* Use a control ping for synchronization */
20436   MPING (CONTROL_PING, mp_ping);
20437   S (mp_ping);
20438
20439   W (ret);
20440   return ret;
20441 }
20442
20443 static int
20444 api_ip6_mfib_dump (vat_main_t * vam)
20445 {
20446   vl_api_ip6_mfib_dump_t *mp;
20447   vl_api_control_ping_t *mp_ping;
20448   int ret;
20449
20450   M (IP6_MFIB_DUMP, mp);
20451   S (mp);
20452
20453   /* Use a control ping for synchronization */
20454   MPING (CONTROL_PING, mp_ping);
20455   S (mp_ping);
20456
20457   W (ret);
20458   return ret;
20459 }
20460
20461 int
20462 api_classify_table_ids (vat_main_t * vam)
20463 {
20464   vl_api_classify_table_ids_t *mp;
20465   int ret;
20466
20467   /* Construct the API message */
20468   M (CLASSIFY_TABLE_IDS, mp);
20469   mp->context = 0;
20470
20471   S (mp);
20472   W (ret);
20473   return ret;
20474 }
20475
20476 int
20477 api_classify_table_by_interface (vat_main_t * vam)
20478 {
20479   unformat_input_t *input = vam->input;
20480   vl_api_classify_table_by_interface_t *mp;
20481
20482   u32 sw_if_index = ~0;
20483   int ret;
20484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20485     {
20486       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20487         ;
20488       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20489         ;
20490       else
20491         break;
20492     }
20493   if (sw_if_index == ~0)
20494     {
20495       errmsg ("missing interface name or sw_if_index");
20496       return -99;
20497     }
20498
20499   /* Construct the API message */
20500   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20501   mp->context = 0;
20502   mp->sw_if_index = ntohl (sw_if_index);
20503
20504   S (mp);
20505   W (ret);
20506   return ret;
20507 }
20508
20509 int
20510 api_classify_table_info (vat_main_t * vam)
20511 {
20512   unformat_input_t *input = vam->input;
20513   vl_api_classify_table_info_t *mp;
20514
20515   u32 table_id = ~0;
20516   int ret;
20517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (input, "table_id %d", &table_id))
20520         ;
20521       else
20522         break;
20523     }
20524   if (table_id == ~0)
20525     {
20526       errmsg ("missing table id");
20527       return -99;
20528     }
20529
20530   /* Construct the API message */
20531   M (CLASSIFY_TABLE_INFO, mp);
20532   mp->context = 0;
20533   mp->table_id = ntohl (table_id);
20534
20535   S (mp);
20536   W (ret);
20537   return ret;
20538 }
20539
20540 int
20541 api_classify_session_dump (vat_main_t * vam)
20542 {
20543   unformat_input_t *input = vam->input;
20544   vl_api_classify_session_dump_t *mp;
20545   vl_api_control_ping_t *mp_ping;
20546
20547   u32 table_id = ~0;
20548   int ret;
20549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20550     {
20551       if (unformat (input, "table_id %d", &table_id))
20552         ;
20553       else
20554         break;
20555     }
20556   if (table_id == ~0)
20557     {
20558       errmsg ("missing table id");
20559       return -99;
20560     }
20561
20562   /* Construct the API message */
20563   M (CLASSIFY_SESSION_DUMP, mp);
20564   mp->context = 0;
20565   mp->table_id = ntohl (table_id);
20566   S (mp);
20567
20568   /* Use a control ping for synchronization */
20569   MPING (CONTROL_PING, mp_ping);
20570   S (mp_ping);
20571
20572   W (ret);
20573   return ret;
20574 }
20575
20576 static void
20577 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20578 {
20579   vat_main_t *vam = &vat_main;
20580
20581   print (vam->ofp, "collector_address %U, collector_port %d, "
20582          "src_address %U, vrf_id %d, path_mtu %u, "
20583          "template_interval %u, udp_checksum %d",
20584          format_ip4_address, mp->collector_address,
20585          ntohs (mp->collector_port),
20586          format_ip4_address, mp->src_address,
20587          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20588          ntohl (mp->template_interval), mp->udp_checksum);
20589
20590   vam->retval = 0;
20591   vam->result_ready = 1;
20592 }
20593
20594 static void
20595   vl_api_ipfix_exporter_details_t_handler_json
20596   (vl_api_ipfix_exporter_details_t * mp)
20597 {
20598   vat_main_t *vam = &vat_main;
20599   vat_json_node_t node;
20600   struct in_addr collector_address;
20601   struct in_addr src_address;
20602
20603   vat_json_init_object (&node);
20604   clib_memcpy (&collector_address, &mp->collector_address,
20605                sizeof (collector_address));
20606   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20607   vat_json_object_add_uint (&node, "collector_port",
20608                             ntohs (mp->collector_port));
20609   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20610   vat_json_object_add_ip4 (&node, "src_address", src_address);
20611   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20612   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20613   vat_json_object_add_uint (&node, "template_interval",
20614                             ntohl (mp->template_interval));
20615   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20616
20617   vat_json_print (vam->ofp, &node);
20618   vat_json_free (&node);
20619   vam->retval = 0;
20620   vam->result_ready = 1;
20621 }
20622
20623 int
20624 api_ipfix_exporter_dump (vat_main_t * vam)
20625 {
20626   vl_api_ipfix_exporter_dump_t *mp;
20627   int ret;
20628
20629   /* Construct the API message */
20630   M (IPFIX_EXPORTER_DUMP, mp);
20631   mp->context = 0;
20632
20633   S (mp);
20634   W (ret);
20635   return ret;
20636 }
20637
20638 static int
20639 api_ipfix_classify_stream_dump (vat_main_t * vam)
20640 {
20641   vl_api_ipfix_classify_stream_dump_t *mp;
20642   int ret;
20643
20644   /* Construct the API message */
20645   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20646   mp->context = 0;
20647
20648   S (mp);
20649   W (ret);
20650   return ret;
20651   /* NOTREACHED */
20652   return 0;
20653 }
20654
20655 static void
20656   vl_api_ipfix_classify_stream_details_t_handler
20657   (vl_api_ipfix_classify_stream_details_t * mp)
20658 {
20659   vat_main_t *vam = &vat_main;
20660   print (vam->ofp, "domain_id %d, src_port %d",
20661          ntohl (mp->domain_id), ntohs (mp->src_port));
20662   vam->retval = 0;
20663   vam->result_ready = 1;
20664 }
20665
20666 static void
20667   vl_api_ipfix_classify_stream_details_t_handler_json
20668   (vl_api_ipfix_classify_stream_details_t * mp)
20669 {
20670   vat_main_t *vam = &vat_main;
20671   vat_json_node_t node;
20672
20673   vat_json_init_object (&node);
20674   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20675   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20676
20677   vat_json_print (vam->ofp, &node);
20678   vat_json_free (&node);
20679   vam->retval = 0;
20680   vam->result_ready = 1;
20681 }
20682
20683 static int
20684 api_ipfix_classify_table_dump (vat_main_t * vam)
20685 {
20686   vl_api_ipfix_classify_table_dump_t *mp;
20687   vl_api_control_ping_t *mp_ping;
20688   int ret;
20689
20690   if (!vam->json_output)
20691     {
20692       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20693              "transport_protocol");
20694     }
20695
20696   /* Construct the API message */
20697   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20698
20699   /* send it... */
20700   S (mp);
20701
20702   /* Use a control ping for synchronization */
20703   MPING (CONTROL_PING, mp_ping);
20704   S (mp_ping);
20705
20706   W (ret);
20707   return ret;
20708 }
20709
20710 static void
20711   vl_api_ipfix_classify_table_details_t_handler
20712   (vl_api_ipfix_classify_table_details_t * mp)
20713 {
20714   vat_main_t *vam = &vat_main;
20715   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20716          mp->transport_protocol);
20717 }
20718
20719 static void
20720   vl_api_ipfix_classify_table_details_t_handler_json
20721   (vl_api_ipfix_classify_table_details_t * mp)
20722 {
20723   vat_json_node_t *node = NULL;
20724   vat_main_t *vam = &vat_main;
20725
20726   if (VAT_JSON_ARRAY != vam->json_tree.type)
20727     {
20728       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20729       vat_json_init_array (&vam->json_tree);
20730     }
20731
20732   node = vat_json_array_add (&vam->json_tree);
20733   vat_json_init_object (node);
20734
20735   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20736   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20737   vat_json_object_add_uint (node, "transport_protocol",
20738                             mp->transport_protocol);
20739 }
20740
20741 static int
20742 api_sw_interface_span_enable_disable (vat_main_t * vam)
20743 {
20744   unformat_input_t *i = vam->input;
20745   vl_api_sw_interface_span_enable_disable_t *mp;
20746   u32 src_sw_if_index = ~0;
20747   u32 dst_sw_if_index = ~0;
20748   u8 state = 3;
20749   int ret;
20750   u8 is_l2 = 0;
20751
20752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20753     {
20754       if (unformat
20755           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20756         ;
20757       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20758         ;
20759       else
20760         if (unformat
20761             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20762         ;
20763       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20764         ;
20765       else if (unformat (i, "disable"))
20766         state = 0;
20767       else if (unformat (i, "rx"))
20768         state = 1;
20769       else if (unformat (i, "tx"))
20770         state = 2;
20771       else if (unformat (i, "both"))
20772         state = 3;
20773       else if (unformat (i, "l2"))
20774         is_l2 = 1;
20775       else
20776         break;
20777     }
20778
20779   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20780
20781   mp->sw_if_index_from = htonl (src_sw_if_index);
20782   mp->sw_if_index_to = htonl (dst_sw_if_index);
20783   mp->state = state;
20784   mp->is_l2 = is_l2;
20785
20786   S (mp);
20787   W (ret);
20788   return ret;
20789 }
20790
20791 static void
20792 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20793                                             * mp)
20794 {
20795   vat_main_t *vam = &vat_main;
20796   u8 *sw_if_from_name = 0;
20797   u8 *sw_if_to_name = 0;
20798   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20799   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20800   char *states[] = { "none", "rx", "tx", "both" };
20801   hash_pair_t *p;
20802
20803   /* *INDENT-OFF* */
20804   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20805   ({
20806     if ((u32) p->value[0] == sw_if_index_from)
20807       {
20808         sw_if_from_name = (u8 *)(p->key);
20809         if (sw_if_to_name)
20810           break;
20811       }
20812     if ((u32) p->value[0] == sw_if_index_to)
20813       {
20814         sw_if_to_name = (u8 *)(p->key);
20815         if (sw_if_from_name)
20816           break;
20817       }
20818   }));
20819   /* *INDENT-ON* */
20820   print (vam->ofp, "%20s => %20s (%s) %s",
20821          sw_if_from_name, sw_if_to_name, states[mp->state],
20822          mp->is_l2 ? "l2" : "device");
20823 }
20824
20825 static void
20826   vl_api_sw_interface_span_details_t_handler_json
20827   (vl_api_sw_interface_span_details_t * mp)
20828 {
20829   vat_main_t *vam = &vat_main;
20830   vat_json_node_t *node = NULL;
20831   u8 *sw_if_from_name = 0;
20832   u8 *sw_if_to_name = 0;
20833   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20834   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20835   hash_pair_t *p;
20836
20837   /* *INDENT-OFF* */
20838   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20839   ({
20840     if ((u32) p->value[0] == sw_if_index_from)
20841       {
20842         sw_if_from_name = (u8 *)(p->key);
20843         if (sw_if_to_name)
20844           break;
20845       }
20846     if ((u32) p->value[0] == sw_if_index_to)
20847       {
20848         sw_if_to_name = (u8 *)(p->key);
20849         if (sw_if_from_name)
20850           break;
20851       }
20852   }));
20853   /* *INDENT-ON* */
20854
20855   if (VAT_JSON_ARRAY != vam->json_tree.type)
20856     {
20857       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20858       vat_json_init_array (&vam->json_tree);
20859     }
20860   node = vat_json_array_add (&vam->json_tree);
20861
20862   vat_json_init_object (node);
20863   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20864   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20865   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20866   if (0 != sw_if_to_name)
20867     {
20868       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20869     }
20870   vat_json_object_add_uint (node, "state", mp->state);
20871   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20872 }
20873
20874 static int
20875 api_sw_interface_span_dump (vat_main_t * vam)
20876 {
20877   unformat_input_t *input = vam->input;
20878   vl_api_sw_interface_span_dump_t *mp;
20879   vl_api_control_ping_t *mp_ping;
20880   u8 is_l2 = 0;
20881   int ret;
20882
20883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20884     {
20885       if (unformat (input, "l2"))
20886         is_l2 = 1;
20887       else
20888         break;
20889     }
20890
20891   M (SW_INTERFACE_SPAN_DUMP, mp);
20892   mp->is_l2 = is_l2;
20893   S (mp);
20894
20895   /* Use a control ping for synchronization */
20896   MPING (CONTROL_PING, mp_ping);
20897   S (mp_ping);
20898
20899   W (ret);
20900   return ret;
20901 }
20902
20903 int
20904 api_pg_create_interface (vat_main_t * vam)
20905 {
20906   unformat_input_t *input = vam->input;
20907   vl_api_pg_create_interface_t *mp;
20908
20909   u32 if_id = ~0;
20910   int ret;
20911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20912     {
20913       if (unformat (input, "if_id %d", &if_id))
20914         ;
20915       else
20916         break;
20917     }
20918   if (if_id == ~0)
20919     {
20920       errmsg ("missing pg interface index");
20921       return -99;
20922     }
20923
20924   /* Construct the API message */
20925   M (PG_CREATE_INTERFACE, mp);
20926   mp->context = 0;
20927   mp->interface_id = ntohl (if_id);
20928
20929   S (mp);
20930   W (ret);
20931   return ret;
20932 }
20933
20934 int
20935 api_pg_capture (vat_main_t * vam)
20936 {
20937   unformat_input_t *input = vam->input;
20938   vl_api_pg_capture_t *mp;
20939
20940   u32 if_id = ~0;
20941   u8 enable = 1;
20942   u32 count = 1;
20943   u8 pcap_file_set = 0;
20944   u8 *pcap_file = 0;
20945   int ret;
20946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20947     {
20948       if (unformat (input, "if_id %d", &if_id))
20949         ;
20950       else if (unformat (input, "pcap %s", &pcap_file))
20951         pcap_file_set = 1;
20952       else if (unformat (input, "count %d", &count))
20953         ;
20954       else if (unformat (input, "disable"))
20955         enable = 0;
20956       else
20957         break;
20958     }
20959   if (if_id == ~0)
20960     {
20961       errmsg ("missing pg interface index");
20962       return -99;
20963     }
20964   if (pcap_file_set > 0)
20965     {
20966       if (vec_len (pcap_file) > 255)
20967         {
20968           errmsg ("pcap file name is too long");
20969           return -99;
20970         }
20971     }
20972
20973   u32 name_len = vec_len (pcap_file);
20974   /* Construct the API message */
20975   M (PG_CAPTURE, mp);
20976   mp->context = 0;
20977   mp->interface_id = ntohl (if_id);
20978   mp->is_enabled = enable;
20979   mp->count = ntohl (count);
20980   mp->pcap_name_length = ntohl (name_len);
20981   if (pcap_file_set != 0)
20982     {
20983       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20984     }
20985   vec_free (pcap_file);
20986
20987   S (mp);
20988   W (ret);
20989   return ret;
20990 }
20991
20992 int
20993 api_pg_enable_disable (vat_main_t * vam)
20994 {
20995   unformat_input_t *input = vam->input;
20996   vl_api_pg_enable_disable_t *mp;
20997
20998   u8 enable = 1;
20999   u8 stream_name_set = 0;
21000   u8 *stream_name = 0;
21001   int ret;
21002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21003     {
21004       if (unformat (input, "stream %s", &stream_name))
21005         stream_name_set = 1;
21006       else if (unformat (input, "disable"))
21007         enable = 0;
21008       else
21009         break;
21010     }
21011
21012   if (stream_name_set > 0)
21013     {
21014       if (vec_len (stream_name) > 255)
21015         {
21016           errmsg ("stream name too long");
21017           return -99;
21018         }
21019     }
21020
21021   u32 name_len = vec_len (stream_name);
21022   /* Construct the API message */
21023   M (PG_ENABLE_DISABLE, mp);
21024   mp->context = 0;
21025   mp->is_enabled = enable;
21026   if (stream_name_set != 0)
21027     {
21028       mp->stream_name_length = ntohl (name_len);
21029       clib_memcpy (mp->stream_name, stream_name, name_len);
21030     }
21031   vec_free (stream_name);
21032
21033   S (mp);
21034   W (ret);
21035   return ret;
21036 }
21037
21038 int
21039 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21040 {
21041   unformat_input_t *input = vam->input;
21042   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21043
21044   u16 *low_ports = 0;
21045   u16 *high_ports = 0;
21046   u16 this_low;
21047   u16 this_hi;
21048   ip4_address_t ip4_addr;
21049   ip6_address_t ip6_addr;
21050   u32 length;
21051   u32 tmp, tmp2;
21052   u8 prefix_set = 0;
21053   u32 vrf_id = ~0;
21054   u8 is_add = 1;
21055   u8 is_ipv6 = 0;
21056   int ret;
21057
21058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21059     {
21060       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21061         {
21062           prefix_set = 1;
21063         }
21064       else
21065         if (unformat
21066             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21067         {
21068           prefix_set = 1;
21069           is_ipv6 = 1;
21070         }
21071       else if (unformat (input, "vrf %d", &vrf_id))
21072         ;
21073       else if (unformat (input, "del"))
21074         is_add = 0;
21075       else if (unformat (input, "port %d", &tmp))
21076         {
21077           if (tmp == 0 || tmp > 65535)
21078             {
21079               errmsg ("port %d out of range", tmp);
21080               return -99;
21081             }
21082           this_low = tmp;
21083           this_hi = this_low + 1;
21084           vec_add1 (low_ports, this_low);
21085           vec_add1 (high_ports, this_hi);
21086         }
21087       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21088         {
21089           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21090             {
21091               errmsg ("incorrect range parameters");
21092               return -99;
21093             }
21094           this_low = tmp;
21095           /* Note: in debug CLI +1 is added to high before
21096              passing to real fn that does "the work"
21097              (ip_source_and_port_range_check_add_del).
21098              This fn is a wrapper around the binary API fn a
21099              control plane will call, which expects this increment
21100              to have occurred. Hence letting the binary API control
21101              plane fn do the increment for consistency between VAT
21102              and other control planes.
21103            */
21104           this_hi = tmp2;
21105           vec_add1 (low_ports, this_low);
21106           vec_add1 (high_ports, this_hi);
21107         }
21108       else
21109         break;
21110     }
21111
21112   if (prefix_set == 0)
21113     {
21114       errmsg ("<address>/<mask> not specified");
21115       return -99;
21116     }
21117
21118   if (vrf_id == ~0)
21119     {
21120       errmsg ("VRF ID required, not specified");
21121       return -99;
21122     }
21123
21124   if (vrf_id == 0)
21125     {
21126       errmsg
21127         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21128       return -99;
21129     }
21130
21131   if (vec_len (low_ports) == 0)
21132     {
21133       errmsg ("At least one port or port range required");
21134       return -99;
21135     }
21136
21137   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21138
21139   mp->is_add = is_add;
21140
21141   if (is_ipv6)
21142     {
21143       mp->is_ipv6 = 1;
21144       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21145     }
21146   else
21147     {
21148       mp->is_ipv6 = 0;
21149       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21150     }
21151
21152   mp->mask_length = length;
21153   mp->number_of_ranges = vec_len (low_ports);
21154
21155   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21156   vec_free (low_ports);
21157
21158   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21159   vec_free (high_ports);
21160
21161   mp->vrf_id = ntohl (vrf_id);
21162
21163   S (mp);
21164   W (ret);
21165   return ret;
21166 }
21167
21168 int
21169 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21170 {
21171   unformat_input_t *input = vam->input;
21172   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21173   u32 sw_if_index = ~0;
21174   int vrf_set = 0;
21175   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21176   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21177   u8 is_add = 1;
21178   int ret;
21179
21180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21181     {
21182       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21183         ;
21184       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21185         ;
21186       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21187         vrf_set = 1;
21188       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21189         vrf_set = 1;
21190       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21191         vrf_set = 1;
21192       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21193         vrf_set = 1;
21194       else if (unformat (input, "del"))
21195         is_add = 0;
21196       else
21197         break;
21198     }
21199
21200   if (sw_if_index == ~0)
21201     {
21202       errmsg ("Interface required but not specified");
21203       return -99;
21204     }
21205
21206   if (vrf_set == 0)
21207     {
21208       errmsg ("VRF ID required but not specified");
21209       return -99;
21210     }
21211
21212   if (tcp_out_vrf_id == 0
21213       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21214     {
21215       errmsg
21216         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21217       return -99;
21218     }
21219
21220   /* Construct the API message */
21221   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21222
21223   mp->sw_if_index = ntohl (sw_if_index);
21224   mp->is_add = is_add;
21225   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21226   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21227   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21228   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21229
21230   /* send it... */
21231   S (mp);
21232
21233   /* Wait for a reply... */
21234   W (ret);
21235   return ret;
21236 }
21237
21238 static int
21239 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21240 {
21241   unformat_input_t *i = vam->input;
21242   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21243   u32 local_sa_id = 0;
21244   u32 remote_sa_id = 0;
21245   ip4_address_t src_address;
21246   ip4_address_t dst_address;
21247   u8 is_add = 1;
21248   int ret;
21249
21250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21251     {
21252       if (unformat (i, "local_sa %d", &local_sa_id))
21253         ;
21254       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21255         ;
21256       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21257         ;
21258       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21259         ;
21260       else if (unformat (i, "del"))
21261         is_add = 0;
21262       else
21263         {
21264           clib_warning ("parse error '%U'", format_unformat_error, i);
21265           return -99;
21266         }
21267     }
21268
21269   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21270
21271   mp->local_sa_id = ntohl (local_sa_id);
21272   mp->remote_sa_id = ntohl (remote_sa_id);
21273   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21274   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21275   mp->is_add = is_add;
21276
21277   S (mp);
21278   W (ret);
21279   return ret;
21280 }
21281
21282 static int
21283 api_punt (vat_main_t * vam)
21284 {
21285   unformat_input_t *i = vam->input;
21286   vl_api_punt_t *mp;
21287   u32 ipv = ~0;
21288   u32 protocol = ~0;
21289   u32 port = ~0;
21290   int is_add = 1;
21291   int ret;
21292
21293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21294     {
21295       if (unformat (i, "ip %d", &ipv))
21296         ;
21297       else if (unformat (i, "protocol %d", &protocol))
21298         ;
21299       else if (unformat (i, "port %d", &port))
21300         ;
21301       else if (unformat (i, "del"))
21302         is_add = 0;
21303       else
21304         {
21305           clib_warning ("parse error '%U'", format_unformat_error, i);
21306           return -99;
21307         }
21308     }
21309
21310   M (PUNT, mp);
21311
21312   mp->is_add = (u8) is_add;
21313   mp->ipv = (u8) ipv;
21314   mp->l4_protocol = (u8) protocol;
21315   mp->l4_port = htons ((u16) port);
21316
21317   S (mp);
21318   W (ret);
21319   return ret;
21320 }
21321
21322 static void vl_api_ipsec_gre_tunnel_details_t_handler
21323   (vl_api_ipsec_gre_tunnel_details_t * mp)
21324 {
21325   vat_main_t *vam = &vat_main;
21326
21327   print (vam->ofp, "%11d%15U%15U%14d%14d",
21328          ntohl (mp->sw_if_index),
21329          format_ip4_address, &mp->src_address,
21330          format_ip4_address, &mp->dst_address,
21331          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21332 }
21333
21334 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21335   (vl_api_ipsec_gre_tunnel_details_t * mp)
21336 {
21337   vat_main_t *vam = &vat_main;
21338   vat_json_node_t *node = NULL;
21339   struct in_addr ip4;
21340
21341   if (VAT_JSON_ARRAY != vam->json_tree.type)
21342     {
21343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21344       vat_json_init_array (&vam->json_tree);
21345     }
21346   node = vat_json_array_add (&vam->json_tree);
21347
21348   vat_json_init_object (node);
21349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21350   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21351   vat_json_object_add_ip4 (node, "src_address", ip4);
21352   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21353   vat_json_object_add_ip4 (node, "dst_address", ip4);
21354   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21355   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21356 }
21357
21358 static int
21359 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21360 {
21361   unformat_input_t *i = vam->input;
21362   vl_api_ipsec_gre_tunnel_dump_t *mp;
21363   vl_api_control_ping_t *mp_ping;
21364   u32 sw_if_index;
21365   u8 sw_if_index_set = 0;
21366   int ret;
21367
21368   /* Parse args required to build the message */
21369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21370     {
21371       if (unformat (i, "sw_if_index %d", &sw_if_index))
21372         sw_if_index_set = 1;
21373       else
21374         break;
21375     }
21376
21377   if (sw_if_index_set == 0)
21378     {
21379       sw_if_index = ~0;
21380     }
21381
21382   if (!vam->json_output)
21383     {
21384       print (vam->ofp, "%11s%15s%15s%14s%14s",
21385              "sw_if_index", "src_address", "dst_address",
21386              "local_sa_id", "remote_sa_id");
21387     }
21388
21389   /* Get list of gre-tunnel interfaces */
21390   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21391
21392   mp->sw_if_index = htonl (sw_if_index);
21393
21394   S (mp);
21395
21396   /* Use a control ping for synchronization */
21397   MPING (CONTROL_PING, mp_ping);
21398   S (mp_ping);
21399
21400   W (ret);
21401   return ret;
21402 }
21403
21404 static int
21405 api_delete_subif (vat_main_t * vam)
21406 {
21407   unformat_input_t *i = vam->input;
21408   vl_api_delete_subif_t *mp;
21409   u32 sw_if_index = ~0;
21410   int ret;
21411
21412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21413     {
21414       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21415         ;
21416       if (unformat (i, "sw_if_index %d", &sw_if_index))
21417         ;
21418       else
21419         break;
21420     }
21421
21422   if (sw_if_index == ~0)
21423     {
21424       errmsg ("missing sw_if_index");
21425       return -99;
21426     }
21427
21428   /* Construct the API message */
21429   M (DELETE_SUBIF, mp);
21430   mp->sw_if_index = ntohl (sw_if_index);
21431
21432   S (mp);
21433   W (ret);
21434   return ret;
21435 }
21436
21437 #define foreach_pbb_vtr_op      \
21438 _("disable",  L2_VTR_DISABLED)  \
21439 _("pop",  L2_VTR_POP_2)         \
21440 _("push",  L2_VTR_PUSH_2)
21441
21442 static int
21443 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21444 {
21445   unformat_input_t *i = vam->input;
21446   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21447   u32 sw_if_index = ~0, vtr_op = ~0;
21448   u16 outer_tag = ~0;
21449   u8 dmac[6], smac[6];
21450   u8 dmac_set = 0, smac_set = 0;
21451   u16 vlanid = 0;
21452   u32 sid = ~0;
21453   u32 tmp;
21454   int ret;
21455
21456   /* Shut up coverity */
21457   memset (dmac, 0, sizeof (dmac));
21458   memset (smac, 0, sizeof (smac));
21459
21460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21461     {
21462       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21463         ;
21464       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21465         ;
21466       else if (unformat (i, "vtr_op %d", &vtr_op))
21467         ;
21468 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21469       foreach_pbb_vtr_op
21470 #undef _
21471         else if (unformat (i, "translate_pbb_stag"))
21472         {
21473           if (unformat (i, "%d", &tmp))
21474             {
21475               vtr_op = L2_VTR_TRANSLATE_2_1;
21476               outer_tag = tmp;
21477             }
21478           else
21479             {
21480               errmsg
21481                 ("translate_pbb_stag operation requires outer tag definition");
21482               return -99;
21483             }
21484         }
21485       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21486         dmac_set++;
21487       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21488         smac_set++;
21489       else if (unformat (i, "sid %d", &sid))
21490         ;
21491       else if (unformat (i, "vlanid %d", &tmp))
21492         vlanid = tmp;
21493       else
21494         {
21495           clib_warning ("parse error '%U'", format_unformat_error, i);
21496           return -99;
21497         }
21498     }
21499
21500   if ((sw_if_index == ~0) || (vtr_op == ~0))
21501     {
21502       errmsg ("missing sw_if_index or vtr operation");
21503       return -99;
21504     }
21505   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21506       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21507     {
21508       errmsg
21509         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21510       return -99;
21511     }
21512
21513   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21514   mp->sw_if_index = ntohl (sw_if_index);
21515   mp->vtr_op = ntohl (vtr_op);
21516   mp->outer_tag = ntohs (outer_tag);
21517   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21518   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21519   mp->b_vlanid = ntohs (vlanid);
21520   mp->i_sid = ntohl (sid);
21521
21522   S (mp);
21523   W (ret);
21524   return ret;
21525 }
21526
21527 static int
21528 api_flow_classify_set_interface (vat_main_t * vam)
21529 {
21530   unformat_input_t *i = vam->input;
21531   vl_api_flow_classify_set_interface_t *mp;
21532   u32 sw_if_index;
21533   int sw_if_index_set;
21534   u32 ip4_table_index = ~0;
21535   u32 ip6_table_index = ~0;
21536   u8 is_add = 1;
21537   int ret;
21538
21539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21540     {
21541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21542         sw_if_index_set = 1;
21543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21544         sw_if_index_set = 1;
21545       else if (unformat (i, "del"))
21546         is_add = 0;
21547       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21548         ;
21549       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21550         ;
21551       else
21552         {
21553           clib_warning ("parse error '%U'", format_unformat_error, i);
21554           return -99;
21555         }
21556     }
21557
21558   if (sw_if_index_set == 0)
21559     {
21560       errmsg ("missing interface name or sw_if_index");
21561       return -99;
21562     }
21563
21564   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21565
21566   mp->sw_if_index = ntohl (sw_if_index);
21567   mp->ip4_table_index = ntohl (ip4_table_index);
21568   mp->ip6_table_index = ntohl (ip6_table_index);
21569   mp->is_add = is_add;
21570
21571   S (mp);
21572   W (ret);
21573   return ret;
21574 }
21575
21576 static int
21577 api_flow_classify_dump (vat_main_t * vam)
21578 {
21579   unformat_input_t *i = vam->input;
21580   vl_api_flow_classify_dump_t *mp;
21581   vl_api_control_ping_t *mp_ping;
21582   u8 type = FLOW_CLASSIFY_N_TABLES;
21583   int ret;
21584
21585   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21586     ;
21587   else
21588     {
21589       errmsg ("classify table type must be specified");
21590       return -99;
21591     }
21592
21593   if (!vam->json_output)
21594     {
21595       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21596     }
21597
21598   M (FLOW_CLASSIFY_DUMP, mp);
21599   mp->type = type;
21600   /* send it... */
21601   S (mp);
21602
21603   /* Use a control ping for synchronization */
21604   MPING (CONTROL_PING, mp_ping);
21605   S (mp_ping);
21606
21607   /* Wait for a reply... */
21608   W (ret);
21609   return ret;
21610 }
21611
21612 static int
21613 api_feature_enable_disable (vat_main_t * vam)
21614 {
21615   unformat_input_t *i = vam->input;
21616   vl_api_feature_enable_disable_t *mp;
21617   u8 *arc_name = 0;
21618   u8 *feature_name = 0;
21619   u32 sw_if_index = ~0;
21620   u8 enable = 1;
21621   int ret;
21622
21623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21624     {
21625       if (unformat (i, "arc_name %s", &arc_name))
21626         ;
21627       else if (unformat (i, "feature_name %s", &feature_name))
21628         ;
21629       else
21630         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21631         ;
21632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21633         ;
21634       else if (unformat (i, "disable"))
21635         enable = 0;
21636       else
21637         break;
21638     }
21639
21640   if (arc_name == 0)
21641     {
21642       errmsg ("missing arc name");
21643       return -99;
21644     }
21645   if (vec_len (arc_name) > 63)
21646     {
21647       errmsg ("arc name too long");
21648     }
21649
21650   if (feature_name == 0)
21651     {
21652       errmsg ("missing feature name");
21653       return -99;
21654     }
21655   if (vec_len (feature_name) > 63)
21656     {
21657       errmsg ("feature name too long");
21658     }
21659
21660   if (sw_if_index == ~0)
21661     {
21662       errmsg ("missing interface name or sw_if_index");
21663       return -99;
21664     }
21665
21666   /* Construct the API message */
21667   M (FEATURE_ENABLE_DISABLE, mp);
21668   mp->sw_if_index = ntohl (sw_if_index);
21669   mp->enable = enable;
21670   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21671   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21672   vec_free (arc_name);
21673   vec_free (feature_name);
21674
21675   S (mp);
21676   W (ret);
21677   return ret;
21678 }
21679
21680 static int
21681 api_sw_interface_tag_add_del (vat_main_t * vam)
21682 {
21683   unformat_input_t *i = vam->input;
21684   vl_api_sw_interface_tag_add_del_t *mp;
21685   u32 sw_if_index = ~0;
21686   u8 *tag = 0;
21687   u8 enable = 1;
21688   int ret;
21689
21690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21691     {
21692       if (unformat (i, "tag %s", &tag))
21693         ;
21694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21695         ;
21696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21697         ;
21698       else if (unformat (i, "del"))
21699         enable = 0;
21700       else
21701         break;
21702     }
21703
21704   if (sw_if_index == ~0)
21705     {
21706       errmsg ("missing interface name or sw_if_index");
21707       return -99;
21708     }
21709
21710   if (enable && (tag == 0))
21711     {
21712       errmsg ("no tag specified");
21713       return -99;
21714     }
21715
21716   /* Construct the API message */
21717   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21718   mp->sw_if_index = ntohl (sw_if_index);
21719   mp->is_add = enable;
21720   if (enable)
21721     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21722   vec_free (tag);
21723
21724   S (mp);
21725   W (ret);
21726   return ret;
21727 }
21728
21729 static void vl_api_l2_xconnect_details_t_handler
21730   (vl_api_l2_xconnect_details_t * mp)
21731 {
21732   vat_main_t *vam = &vat_main;
21733
21734   print (vam->ofp, "%15d%15d",
21735          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21736 }
21737
21738 static void vl_api_l2_xconnect_details_t_handler_json
21739   (vl_api_l2_xconnect_details_t * mp)
21740 {
21741   vat_main_t *vam = &vat_main;
21742   vat_json_node_t *node = NULL;
21743
21744   if (VAT_JSON_ARRAY != vam->json_tree.type)
21745     {
21746       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21747       vat_json_init_array (&vam->json_tree);
21748     }
21749   node = vat_json_array_add (&vam->json_tree);
21750
21751   vat_json_init_object (node);
21752   vat_json_object_add_uint (node, "rx_sw_if_index",
21753                             ntohl (mp->rx_sw_if_index));
21754   vat_json_object_add_uint (node, "tx_sw_if_index",
21755                             ntohl (mp->tx_sw_if_index));
21756 }
21757
21758 static int
21759 api_l2_xconnect_dump (vat_main_t * vam)
21760 {
21761   vl_api_l2_xconnect_dump_t *mp;
21762   vl_api_control_ping_t *mp_ping;
21763   int ret;
21764
21765   if (!vam->json_output)
21766     {
21767       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21768     }
21769
21770   M (L2_XCONNECT_DUMP, mp);
21771
21772   S (mp);
21773
21774   /* Use a control ping for synchronization */
21775   MPING (CONTROL_PING, mp_ping);
21776   S (mp_ping);
21777
21778   W (ret);
21779   return ret;
21780 }
21781
21782 static int
21783 api_hw_interface_set_mtu (vat_main_t * vam)
21784 {
21785   unformat_input_t *i = vam->input;
21786   vl_api_hw_interface_set_mtu_t *mp;
21787   u32 sw_if_index = ~0;
21788   u32 mtu = 0;
21789   int ret;
21790
21791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21792     {
21793       if (unformat (i, "mtu %d", &mtu))
21794         ;
21795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21796         ;
21797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21798         ;
21799       else
21800         break;
21801     }
21802
21803   if (sw_if_index == ~0)
21804     {
21805       errmsg ("missing interface name or sw_if_index");
21806       return -99;
21807     }
21808
21809   if (mtu == 0)
21810     {
21811       errmsg ("no mtu specified");
21812       return -99;
21813     }
21814
21815   /* Construct the API message */
21816   M (HW_INTERFACE_SET_MTU, mp);
21817   mp->sw_if_index = ntohl (sw_if_index);
21818   mp->mtu = ntohs ((u16) mtu);
21819
21820   S (mp);
21821   W (ret);
21822   return ret;
21823 }
21824
21825 static int
21826 api_p2p_ethernet_add (vat_main_t * vam)
21827 {
21828   unformat_input_t *i = vam->input;
21829   vl_api_p2p_ethernet_add_t *mp;
21830   u32 parent_if_index = ~0;
21831   u32 sub_id = ~0;
21832   u8 remote_mac[6];
21833   u8 mac_set = 0;
21834   int ret;
21835
21836   memset (remote_mac, 0, sizeof (remote_mac));
21837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21838     {
21839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21840         ;
21841       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21842         ;
21843       else
21844         if (unformat
21845             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21846         mac_set++;
21847       else if (unformat (i, "sub_id %d", &sub_id))
21848         ;
21849       else
21850         {
21851           clib_warning ("parse error '%U'", format_unformat_error, i);
21852           return -99;
21853         }
21854     }
21855
21856   if (parent_if_index == ~0)
21857     {
21858       errmsg ("missing interface name or sw_if_index");
21859       return -99;
21860     }
21861   if (mac_set == 0)
21862     {
21863       errmsg ("missing remote mac address");
21864       return -99;
21865     }
21866   if (sub_id == ~0)
21867     {
21868       errmsg ("missing sub-interface id");
21869       return -99;
21870     }
21871
21872   M (P2P_ETHERNET_ADD, mp);
21873   mp->parent_if_index = ntohl (parent_if_index);
21874   mp->subif_id = ntohl (sub_id);
21875   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21876
21877   S (mp);
21878   W (ret);
21879   return ret;
21880 }
21881
21882 static int
21883 api_p2p_ethernet_del (vat_main_t * vam)
21884 {
21885   unformat_input_t *i = vam->input;
21886   vl_api_p2p_ethernet_del_t *mp;
21887   u32 parent_if_index = ~0;
21888   u8 remote_mac[6];
21889   u8 mac_set = 0;
21890   int ret;
21891
21892   memset (remote_mac, 0, sizeof (remote_mac));
21893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21894     {
21895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21896         ;
21897       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21898         ;
21899       else
21900         if (unformat
21901             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21902         mac_set++;
21903       else
21904         {
21905           clib_warning ("parse error '%U'", format_unformat_error, i);
21906           return -99;
21907         }
21908     }
21909
21910   if (parent_if_index == ~0)
21911     {
21912       errmsg ("missing interface name or sw_if_index");
21913       return -99;
21914     }
21915   if (mac_set == 0)
21916     {
21917       errmsg ("missing remote mac address");
21918       return -99;
21919     }
21920
21921   M (P2P_ETHERNET_DEL, mp);
21922   mp->parent_if_index = ntohl (parent_if_index);
21923   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21924
21925   S (mp);
21926   W (ret);
21927   return ret;
21928 }
21929
21930 static int
21931 api_lldp_config (vat_main_t * vam)
21932 {
21933   unformat_input_t *i = vam->input;
21934   vl_api_lldp_config_t *mp;
21935   int tx_hold = 0;
21936   int tx_interval = 0;
21937   u8 *sys_name = NULL;
21938   int ret;
21939
21940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21941     {
21942       if (unformat (i, "system-name %s", &sys_name))
21943         ;
21944       else if (unformat (i, "tx-hold %d", &tx_hold))
21945         ;
21946       else if (unformat (i, "tx-interval %d", &tx_interval))
21947         ;
21948       else
21949         {
21950           clib_warning ("parse error '%U'", format_unformat_error, i);
21951           return -99;
21952         }
21953     }
21954
21955   vec_add1 (sys_name, 0);
21956
21957   M (LLDP_CONFIG, mp);
21958   mp->tx_hold = htonl (tx_hold);
21959   mp->tx_interval = htonl (tx_interval);
21960   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21961   vec_free (sys_name);
21962
21963   S (mp);
21964   W (ret);
21965   return ret;
21966 }
21967
21968 static int
21969 api_sw_interface_set_lldp (vat_main_t * vam)
21970 {
21971   unformat_input_t *i = vam->input;
21972   vl_api_sw_interface_set_lldp_t *mp;
21973   u32 sw_if_index = ~0;
21974   u32 enable = 1;
21975   u8 *port_desc = NULL, *mgmt_oid = NULL;
21976   ip4_address_t ip4_addr;
21977   ip6_address_t ip6_addr;
21978   int ret;
21979
21980   memset (&ip4_addr, 0, sizeof (ip4_addr));
21981   memset (&ip6_addr, 0, sizeof (ip6_addr));
21982
21983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21984     {
21985       if (unformat (i, "disable"))
21986         enable = 0;
21987       else
21988         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21989         ;
21990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21991         ;
21992       else if (unformat (i, "port-desc %s", &port_desc))
21993         ;
21994       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21995         ;
21996       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21997         ;
21998       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21999         ;
22000       else
22001         break;
22002     }
22003
22004   if (sw_if_index == ~0)
22005     {
22006       errmsg ("missing interface name or sw_if_index");
22007       return -99;
22008     }
22009
22010   /* Construct the API message */
22011   vec_add1 (port_desc, 0);
22012   vec_add1 (mgmt_oid, 0);
22013   M (SW_INTERFACE_SET_LLDP, mp);
22014   mp->sw_if_index = ntohl (sw_if_index);
22015   mp->enable = enable;
22016   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22017   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22018   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22019   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22020   vec_free (port_desc);
22021   vec_free (mgmt_oid);
22022
22023   S (mp);
22024   W (ret);
22025   return ret;
22026 }
22027
22028 static int
22029 api_tcp_configure_src_addresses (vat_main_t * vam)
22030 {
22031   vl_api_tcp_configure_src_addresses_t *mp;
22032   unformat_input_t *i = vam->input;
22033   ip4_address_t v4first, v4last;
22034   ip6_address_t v6first, v6last;
22035   u8 range_set = 0;
22036   u32 vrf_id = 0;
22037   int ret;
22038
22039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22040     {
22041       if (unformat (i, "%U - %U",
22042                     unformat_ip4_address, &v4first,
22043                     unformat_ip4_address, &v4last))
22044         {
22045           if (range_set)
22046             {
22047               errmsg ("one range per message (range already set)");
22048               return -99;
22049             }
22050           range_set = 1;
22051         }
22052       else if (unformat (i, "%U - %U",
22053                          unformat_ip6_address, &v6first,
22054                          unformat_ip6_address, &v6last))
22055         {
22056           if (range_set)
22057             {
22058               errmsg ("one range per message (range already set)");
22059               return -99;
22060             }
22061           range_set = 2;
22062         }
22063       else if (unformat (i, "vrf %d", &vrf_id))
22064         ;
22065       else
22066         break;
22067     }
22068
22069   if (range_set == 0)
22070     {
22071       errmsg ("address range not set");
22072       return -99;
22073     }
22074
22075   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22076   mp->vrf_id = ntohl (vrf_id);
22077   /* ipv6? */
22078   if (range_set == 2)
22079     {
22080       mp->is_ipv6 = 1;
22081       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22082       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22083     }
22084   else
22085     {
22086       mp->is_ipv6 = 0;
22087       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22088       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22089     }
22090   S (mp);
22091   W (ret);
22092   return ret;
22093 }
22094
22095 static void vl_api_app_namespace_add_del_reply_t_handler
22096   (vl_api_app_namespace_add_del_reply_t * mp)
22097 {
22098   vat_main_t *vam = &vat_main;
22099   i32 retval = ntohl (mp->retval);
22100   if (vam->async_mode)
22101     {
22102       vam->async_errors += (retval < 0);
22103     }
22104   else
22105     {
22106       vam->retval = retval;
22107       if (retval == 0)
22108         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22109       vam->result_ready = 1;
22110     }
22111 }
22112
22113 static void vl_api_app_namespace_add_del_reply_t_handler_json
22114   (vl_api_app_namespace_add_del_reply_t * mp)
22115 {
22116   vat_main_t *vam = &vat_main;
22117   vat_json_node_t node;
22118
22119   vat_json_init_object (&node);
22120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22121   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22122
22123   vat_json_print (vam->ofp, &node);
22124   vat_json_free (&node);
22125
22126   vam->retval = ntohl (mp->retval);
22127   vam->result_ready = 1;
22128 }
22129
22130 static int
22131 api_app_namespace_add_del (vat_main_t * vam)
22132 {
22133   vl_api_app_namespace_add_del_t *mp;
22134   unformat_input_t *i = vam->input;
22135   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22136   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22137   u64 secret;
22138   int ret;
22139
22140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22141     {
22142       if (unformat (i, "id %_%v%_", &ns_id))
22143         ;
22144       else if (unformat (i, "secret %lu", &secret))
22145         secret_set = 1;
22146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22147         sw_if_index_set = 1;
22148       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22149         ;
22150       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22151         ;
22152       else
22153         break;
22154     }
22155   if (!ns_id || !secret_set || !sw_if_index_set)
22156     {
22157       errmsg ("namespace id, secret and sw_if_index must be set");
22158       return -99;
22159     }
22160   if (vec_len (ns_id) > 64)
22161     {
22162       errmsg ("namespace id too long");
22163       return -99;
22164     }
22165   M (APP_NAMESPACE_ADD_DEL, mp);
22166
22167   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22168   mp->namespace_id_len = vec_len (ns_id);
22169   mp->secret = clib_host_to_net_u64 (secret);
22170   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22171   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22172   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22173   vec_free (ns_id);
22174   S (mp);
22175   W (ret);
22176   return ret;
22177 }
22178
22179 static int
22180 api_sock_init_shm (vat_main_t * vam)
22181 {
22182 #if VPP_API_TEST_BUILTIN == 0
22183   unformat_input_t *i = vam->input;
22184   vl_api_shm_elem_config_t *config = 0;
22185   u64 size = 64 << 20;
22186   int rv;
22187
22188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22189     {
22190       if (unformat (i, "size %U", unformat_memory_size, &size))
22191         ;
22192       else
22193         break;
22194     }
22195
22196   /*
22197    * Canned custom ring allocator config.
22198    * Should probably parse all of this
22199    */
22200   vec_validate (config, 6);
22201   config[0].type = VL_API_VLIB_RING;
22202   config[0].size = 256;
22203   config[0].count = 32;
22204
22205   config[1].type = VL_API_VLIB_RING;
22206   config[1].size = 1024;
22207   config[1].count = 16;
22208
22209   config[2].type = VL_API_VLIB_RING;
22210   config[2].size = 4096;
22211   config[2].count = 2;
22212
22213   config[3].type = VL_API_CLIENT_RING;
22214   config[3].size = 256;
22215   config[3].count = 32;
22216
22217   config[4].type = VL_API_CLIENT_RING;
22218   config[4].size = 1024;
22219   config[4].count = 16;
22220
22221   config[5].type = VL_API_CLIENT_RING;
22222   config[5].size = 4096;
22223   config[5].count = 2;
22224
22225   config[6].type = VL_API_QUEUE;
22226   config[6].count = 128;
22227   config[6].size = sizeof (uword);
22228
22229   rv = vl_socket_client_init_shm (config);
22230   if (!rv)
22231     vam->client_index_invalid = 1;
22232   return rv;
22233 #else
22234   return -99;
22235 #endif
22236 }
22237
22238 static int
22239 api_dns_enable_disable (vat_main_t * vam)
22240 {
22241   unformat_input_t *line_input = vam->input;
22242   vl_api_dns_enable_disable_t *mp;
22243   u8 enable_disable = 1;
22244   int ret;
22245
22246   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22247     {
22248       if (unformat (line_input, "disable"))
22249         enable_disable = 0;
22250       if (unformat (line_input, "enable"))
22251         enable_disable = 1;
22252       else
22253         break;
22254     }
22255
22256   /* Construct the API message */
22257   M (DNS_ENABLE_DISABLE, mp);
22258   mp->enable = enable_disable;
22259
22260   /* send it... */
22261   S (mp);
22262   /* Wait for the reply */
22263   W (ret);
22264   return ret;
22265 }
22266
22267 static int
22268 api_dns_resolve_name (vat_main_t * vam)
22269 {
22270   unformat_input_t *line_input = vam->input;
22271   vl_api_dns_resolve_name_t *mp;
22272   u8 *name = 0;
22273   int ret;
22274
22275   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22276     {
22277       if (unformat (line_input, "%s", &name))
22278         ;
22279       else
22280         break;
22281     }
22282
22283   if (vec_len (name) > 127)
22284     {
22285       errmsg ("name too long");
22286       return -99;
22287     }
22288
22289   /* Construct the API message */
22290   M (DNS_RESOLVE_NAME, mp);
22291   memcpy (mp->name, name, vec_len (name));
22292   vec_free (name);
22293
22294   /* send it... */
22295   S (mp);
22296   /* Wait for the reply */
22297   W (ret);
22298   return ret;
22299 }
22300
22301 static int
22302 api_dns_resolve_ip (vat_main_t * vam)
22303 {
22304   unformat_input_t *line_input = vam->input;
22305   vl_api_dns_resolve_ip_t *mp;
22306   int is_ip6 = -1;
22307   ip4_address_t addr4;
22308   ip6_address_t addr6;
22309   int ret;
22310
22311   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22312     {
22313       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22314         is_ip6 = 1;
22315       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22316         is_ip6 = 0;
22317       else
22318         break;
22319     }
22320
22321   if (is_ip6 == -1)
22322     {
22323       errmsg ("missing address");
22324       return -99;
22325     }
22326
22327   /* Construct the API message */
22328   M (DNS_RESOLVE_IP, mp);
22329   mp->is_ip6 = is_ip6;
22330   if (is_ip6)
22331     memcpy (mp->address, &addr6, sizeof (addr6));
22332   else
22333     memcpy (mp->address, &addr4, sizeof (addr4));
22334
22335   /* send it... */
22336   S (mp);
22337   /* Wait for the reply */
22338   W (ret);
22339   return ret;
22340 }
22341
22342 static int
22343 api_dns_name_server_add_del (vat_main_t * vam)
22344 {
22345   unformat_input_t *i = vam->input;
22346   vl_api_dns_name_server_add_del_t *mp;
22347   u8 is_add = 1;
22348   ip6_address_t ip6_server;
22349   ip4_address_t ip4_server;
22350   int ip6_set = 0;
22351   int ip4_set = 0;
22352   int ret = 0;
22353
22354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22355     {
22356       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22357         ip6_set = 1;
22358       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22359         ip4_set = 1;
22360       else if (unformat (i, "del"))
22361         is_add = 0;
22362       else
22363         {
22364           clib_warning ("parse error '%U'", format_unformat_error, i);
22365           return -99;
22366         }
22367     }
22368
22369   if (ip4_set && ip6_set)
22370     {
22371       errmsg ("Only one server address allowed per message");
22372       return -99;
22373     }
22374   if ((ip4_set + ip6_set) == 0)
22375     {
22376       errmsg ("Server address required");
22377       return -99;
22378     }
22379
22380   /* Construct the API message */
22381   M (DNS_NAME_SERVER_ADD_DEL, mp);
22382
22383   if (ip6_set)
22384     {
22385       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22386       mp->is_ip6 = 1;
22387     }
22388   else
22389     {
22390       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22391       mp->is_ip6 = 0;
22392     }
22393
22394   mp->is_add = is_add;
22395
22396   /* send it... */
22397   S (mp);
22398
22399   /* Wait for a reply, return good/bad news  */
22400   W (ret);
22401   return ret;
22402 }
22403
22404 static void
22405 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22406 {
22407   vat_main_t *vam = &vat_main;
22408
22409   if (mp->is_ip4)
22410     {
22411       print (vam->ofp,
22412              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22413              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22414              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22415              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22416              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22417              clib_net_to_host_u32 (mp->action_index), mp->tag);
22418     }
22419   else
22420     {
22421       print (vam->ofp,
22422              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22423              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22424              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22425              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22426              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22427              clib_net_to_host_u32 (mp->action_index), mp->tag);
22428     }
22429 }
22430
22431 static void
22432 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22433                                              mp)
22434 {
22435   vat_main_t *vam = &vat_main;
22436   vat_json_node_t *node = NULL;
22437   struct in6_addr ip6;
22438   struct in_addr ip4;
22439
22440   if (VAT_JSON_ARRAY != vam->json_tree.type)
22441     {
22442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22443       vat_json_init_array (&vam->json_tree);
22444     }
22445   node = vat_json_array_add (&vam->json_tree);
22446   vat_json_init_object (node);
22447
22448   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22449   vat_json_object_add_uint (node, "appns_index",
22450                             clib_net_to_host_u32 (mp->appns_index));
22451   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22452   vat_json_object_add_uint (node, "scope", mp->scope);
22453   vat_json_object_add_uint (node, "action_index",
22454                             clib_net_to_host_u32 (mp->action_index));
22455   vat_json_object_add_uint (node, "lcl_port",
22456                             clib_net_to_host_u16 (mp->lcl_port));
22457   vat_json_object_add_uint (node, "rmt_port",
22458                             clib_net_to_host_u16 (mp->rmt_port));
22459   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22460   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22461   vat_json_object_add_string_copy (node, "tag", mp->tag);
22462   if (mp->is_ip4)
22463     {
22464       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22465       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22466       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22467       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22468     }
22469   else
22470     {
22471       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22472       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22473       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22474       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22475     }
22476 }
22477
22478 static int
22479 api_session_rule_add_del (vat_main_t * vam)
22480 {
22481   vl_api_session_rule_add_del_t *mp;
22482   unformat_input_t *i = vam->input;
22483   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22484   u32 appns_index = 0, scope = 0;
22485   ip4_address_t lcl_ip4, rmt_ip4;
22486   ip6_address_t lcl_ip6, rmt_ip6;
22487   u8 is_ip4 = 1, conn_set = 0;
22488   u8 is_add = 1, *tag = 0;
22489   int ret;
22490
22491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22492     {
22493       if (unformat (i, "del"))
22494         is_add = 0;
22495       else if (unformat (i, "add"))
22496         ;
22497       else if (unformat (i, "proto tcp"))
22498         proto = 0;
22499       else if (unformat (i, "proto udp"))
22500         proto = 1;
22501       else if (unformat (i, "appns %d", &appns_index))
22502         ;
22503       else if (unformat (i, "scope %d", &scope))
22504         ;
22505       else if (unformat (i, "tag %_%v%_", &tag))
22506         ;
22507       else
22508         if (unformat
22509             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22510              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22511              &rmt_port))
22512         {
22513           is_ip4 = 1;
22514           conn_set = 1;
22515         }
22516       else
22517         if (unformat
22518             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22519              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22520              &rmt_port))
22521         {
22522           is_ip4 = 0;
22523           conn_set = 1;
22524         }
22525       else if (unformat (i, "action %d", &action))
22526         ;
22527       else
22528         break;
22529     }
22530   if (proto == ~0 || !conn_set || action == ~0)
22531     {
22532       errmsg ("transport proto, connection and action must be set");
22533       return -99;
22534     }
22535
22536   if (scope > 3)
22537     {
22538       errmsg ("scope should be 0-3");
22539       return -99;
22540     }
22541
22542   M (SESSION_RULE_ADD_DEL, mp);
22543
22544   mp->is_ip4 = is_ip4;
22545   mp->transport_proto = proto;
22546   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22547   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22548   mp->lcl_plen = lcl_plen;
22549   mp->rmt_plen = rmt_plen;
22550   mp->action_index = clib_host_to_net_u32 (action);
22551   mp->appns_index = clib_host_to_net_u32 (appns_index);
22552   mp->scope = scope;
22553   mp->is_add = is_add;
22554   if (is_ip4)
22555     {
22556       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22557       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22558     }
22559   else
22560     {
22561       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22562       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22563     }
22564   if (tag)
22565     {
22566       clib_memcpy (mp->tag, tag, vec_len (tag));
22567       vec_free (tag);
22568     }
22569
22570   S (mp);
22571   W (ret);
22572   return ret;
22573 }
22574
22575 static int
22576 api_session_rules_dump (vat_main_t * vam)
22577 {
22578   vl_api_session_rules_dump_t *mp;
22579   vl_api_control_ping_t *mp_ping;
22580   int ret;
22581
22582   if (!vam->json_output)
22583     {
22584       print (vam->ofp, "%=20s", "Session Rules");
22585     }
22586
22587   M (SESSION_RULES_DUMP, mp);
22588   /* send it... */
22589   S (mp);
22590
22591   /* Use a control ping for synchronization */
22592   MPING (CONTROL_PING, mp_ping);
22593   S (mp_ping);
22594
22595   /* Wait for a reply... */
22596   W (ret);
22597   return ret;
22598 }
22599
22600 static int
22601 api_ip_container_proxy_add_del (vat_main_t * vam)
22602 {
22603   vl_api_ip_container_proxy_add_del_t *mp;
22604   unformat_input_t *i = vam->input;
22605   u32 plen = ~0, sw_if_index = ~0;
22606   ip4_address_t ip4;
22607   ip6_address_t ip6;
22608   u8 is_ip4 = 1;
22609   u8 is_add = 1;
22610   int ret;
22611
22612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22613     {
22614       if (unformat (i, "del"))
22615         is_add = 0;
22616       else if (unformat (i, "add"))
22617         ;
22618       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22619         {
22620           is_ip4 = 1;
22621           plen = 32;
22622         }
22623       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22624         {
22625           is_ip4 = 0;
22626           plen = 128;
22627         }
22628       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22629         ;
22630       else
22631         break;
22632     }
22633   if (sw_if_index == ~0 || plen == ~0)
22634     {
22635       errmsg ("address and sw_if_index must be set");
22636       return -99;
22637     }
22638
22639   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22640
22641   mp->is_ip4 = is_ip4;
22642   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22643   mp->plen = plen;
22644   mp->is_add = is_add;
22645   if (is_ip4)
22646     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22647   else
22648     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22649
22650   S (mp);
22651   W (ret);
22652   return ret;
22653 }
22654
22655 static int
22656 api_qos_record_enable_disable (vat_main_t * vam)
22657 {
22658   unformat_input_t *i = vam->input;
22659   vl_api_qos_record_enable_disable_t *mp;
22660   u32 sw_if_index, qs = 0xff;
22661   u8 sw_if_index_set = 0;
22662   u8 enable = 1;
22663   int ret;
22664
22665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22666     {
22667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22668         sw_if_index_set = 1;
22669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22670         sw_if_index_set = 1;
22671       else if (unformat (i, "%U", unformat_qos_source, &qs))
22672         ;
22673       else if (unformat (i, "disable"))
22674         enable = 0;
22675       else
22676         {
22677           clib_warning ("parse error '%U'", format_unformat_error, i);
22678           return -99;
22679         }
22680     }
22681
22682   if (sw_if_index_set == 0)
22683     {
22684       errmsg ("missing interface name or sw_if_index");
22685       return -99;
22686     }
22687   if (qs == 0xff)
22688     {
22689       errmsg ("input location must be specified");
22690       return -99;
22691     }
22692
22693   M (QOS_RECORD_ENABLE_DISABLE, mp);
22694
22695   mp->sw_if_index = ntohl (sw_if_index);
22696   mp->input_source = qs;
22697   mp->enable = enable;
22698
22699   S (mp);
22700   W (ret);
22701   return ret;
22702 }
22703
22704
22705 static int
22706 q_or_quit (vat_main_t * vam)
22707 {
22708 #if VPP_API_TEST_BUILTIN == 0
22709   longjmp (vam->jump_buf, 1);
22710 #endif
22711   return 0;                     /* not so much */
22712 }
22713
22714 static int
22715 q (vat_main_t * vam)
22716 {
22717   return q_or_quit (vam);
22718 }
22719
22720 static int
22721 quit (vat_main_t * vam)
22722 {
22723   return q_or_quit (vam);
22724 }
22725
22726 static int
22727 comment (vat_main_t * vam)
22728 {
22729   return 0;
22730 }
22731
22732 static int
22733 statseg (vat_main_t * vam)
22734 {
22735   ssvm_private_t *ssvmp = &vam->stat_segment;
22736   ssvm_shared_header_t *shared_header = ssvmp->sh;
22737   vlib_counter_t **counters;
22738   u64 thread0_index1_packets;
22739   u64 thread0_index1_bytes;
22740   f64 vector_rate, input_rate;
22741   uword *p;
22742
22743   uword *counter_vector_by_name;
22744   if (vam->stat_segment_lockp == 0)
22745     {
22746       errmsg ("Stat segment not mapped...");
22747       return -99;
22748     }
22749
22750   /* look up "/if/rx for sw_if_index 1 as a test */
22751
22752   clib_spinlock_lock (vam->stat_segment_lockp);
22753
22754   counter_vector_by_name = (uword *) shared_header->opaque[1];
22755
22756   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22757   if (p == 0)
22758     {
22759       clib_spinlock_unlock (vam->stat_segment_lockp);
22760       errmsg ("/if/tx not found?");
22761       return -99;
22762     }
22763
22764   /* Fish per-thread vector of combined counters from shared memory */
22765   counters = (vlib_counter_t **) p[0];
22766
22767   if (vec_len (counters[0]) < 2)
22768     {
22769       clib_spinlock_unlock (vam->stat_segment_lockp);
22770       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22771       return -99;
22772     }
22773
22774   /* Read thread 0 sw_if_index 1 counter */
22775   thread0_index1_packets = counters[0][1].packets;
22776   thread0_index1_bytes = counters[0][1].bytes;
22777
22778   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22779   if (p == 0)
22780     {
22781       clib_spinlock_unlock (vam->stat_segment_lockp);
22782       errmsg ("vector_rate not found?");
22783       return -99;
22784     }
22785
22786   vector_rate = *(f64 *) (p[0]);
22787   p = hash_get_mem (counter_vector_by_name, "input_rate");
22788   if (p == 0)
22789     {
22790       clib_spinlock_unlock (vam->stat_segment_lockp);
22791       errmsg ("input_rate not found?");
22792       return -99;
22793     }
22794   input_rate = *(f64 *) (p[0]);
22795
22796   clib_spinlock_unlock (vam->stat_segment_lockp);
22797
22798   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22799          vector_rate, input_rate);
22800   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22801          thread0_index1_packets, thread0_index1_bytes);
22802
22803   return 0;
22804 }
22805
22806 static int
22807 cmd_cmp (void *a1, void *a2)
22808 {
22809   u8 **c1 = a1;
22810   u8 **c2 = a2;
22811
22812   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22813 }
22814
22815 static int
22816 help (vat_main_t * vam)
22817 {
22818   u8 **cmds = 0;
22819   u8 *name = 0;
22820   hash_pair_t *p;
22821   unformat_input_t *i = vam->input;
22822   int j;
22823
22824   if (unformat (i, "%s", &name))
22825     {
22826       uword *hs;
22827
22828       vec_add1 (name, 0);
22829
22830       hs = hash_get_mem (vam->help_by_name, name);
22831       if (hs)
22832         print (vam->ofp, "usage: %s %s", name, hs[0]);
22833       else
22834         print (vam->ofp, "No such msg / command '%s'", name);
22835       vec_free (name);
22836       return 0;
22837     }
22838
22839   print (vam->ofp, "Help is available for the following:");
22840
22841     /* *INDENT-OFF* */
22842     hash_foreach_pair (p, vam->function_by_name,
22843     ({
22844       vec_add1 (cmds, (u8 *)(p->key));
22845     }));
22846     /* *INDENT-ON* */
22847
22848   vec_sort_with_function (cmds, cmd_cmp);
22849
22850   for (j = 0; j < vec_len (cmds); j++)
22851     print (vam->ofp, "%s", cmds[j]);
22852
22853   vec_free (cmds);
22854   return 0;
22855 }
22856
22857 static int
22858 set (vat_main_t * vam)
22859 {
22860   u8 *name = 0, *value = 0;
22861   unformat_input_t *i = vam->input;
22862
22863   if (unformat (i, "%s", &name))
22864     {
22865       /* The input buffer is a vector, not a string. */
22866       value = vec_dup (i->buffer);
22867       vec_delete (value, i->index, 0);
22868       /* Almost certainly has a trailing newline */
22869       if (value[vec_len (value) - 1] == '\n')
22870         value[vec_len (value) - 1] = 0;
22871       /* Make sure it's a proper string, one way or the other */
22872       vec_add1 (value, 0);
22873       (void) clib_macro_set_value (&vam->macro_main,
22874                                    (char *) name, (char *) value);
22875     }
22876   else
22877     errmsg ("usage: set <name> <value>");
22878
22879   vec_free (name);
22880   vec_free (value);
22881   return 0;
22882 }
22883
22884 static int
22885 unset (vat_main_t * vam)
22886 {
22887   u8 *name = 0;
22888
22889   if (unformat (vam->input, "%s", &name))
22890     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22891       errmsg ("unset: %s wasn't set", name);
22892   vec_free (name);
22893   return 0;
22894 }
22895
22896 typedef struct
22897 {
22898   u8 *name;
22899   u8 *value;
22900 } macro_sort_t;
22901
22902
22903 static int
22904 macro_sort_cmp (void *a1, void *a2)
22905 {
22906   macro_sort_t *s1 = a1;
22907   macro_sort_t *s2 = a2;
22908
22909   return strcmp ((char *) (s1->name), (char *) (s2->name));
22910 }
22911
22912 static int
22913 dump_macro_table (vat_main_t * vam)
22914 {
22915   macro_sort_t *sort_me = 0, *sm;
22916   int i;
22917   hash_pair_t *p;
22918
22919     /* *INDENT-OFF* */
22920     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22921     ({
22922       vec_add2 (sort_me, sm, 1);
22923       sm->name = (u8 *)(p->key);
22924       sm->value = (u8 *) (p->value[0]);
22925     }));
22926     /* *INDENT-ON* */
22927
22928   vec_sort_with_function (sort_me, macro_sort_cmp);
22929
22930   if (vec_len (sort_me))
22931     print (vam->ofp, "%-15s%s", "Name", "Value");
22932   else
22933     print (vam->ofp, "The macro table is empty...");
22934
22935   for (i = 0; i < vec_len (sort_me); i++)
22936     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22937   return 0;
22938 }
22939
22940 static int
22941 dump_node_table (vat_main_t * vam)
22942 {
22943   int i, j;
22944   vlib_node_t *node, *next_node;
22945
22946   if (vec_len (vam->graph_nodes) == 0)
22947     {
22948       print (vam->ofp, "Node table empty, issue get_node_graph...");
22949       return 0;
22950     }
22951
22952   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22953     {
22954       node = vam->graph_nodes[0][i];
22955       print (vam->ofp, "[%d] %s", i, node->name);
22956       for (j = 0; j < vec_len (node->next_nodes); j++)
22957         {
22958           if (node->next_nodes[j] != ~0)
22959             {
22960               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22961               print (vam->ofp, "  [%d] %s", j, next_node->name);
22962             }
22963         }
22964     }
22965   return 0;
22966 }
22967
22968 static int
22969 value_sort_cmp (void *a1, void *a2)
22970 {
22971   name_sort_t *n1 = a1;
22972   name_sort_t *n2 = a2;
22973
22974   if (n1->value < n2->value)
22975     return -1;
22976   if (n1->value > n2->value)
22977     return 1;
22978   return 0;
22979 }
22980
22981
22982 static int
22983 dump_msg_api_table (vat_main_t * vam)
22984 {
22985   api_main_t *am = &api_main;
22986   name_sort_t *nses = 0, *ns;
22987   hash_pair_t *hp;
22988   int i;
22989
22990   /* *INDENT-OFF* */
22991   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22992   ({
22993     vec_add2 (nses, ns, 1);
22994     ns->name = (u8 *)(hp->key);
22995     ns->value = (u32) hp->value[0];
22996   }));
22997   /* *INDENT-ON* */
22998
22999   vec_sort_with_function (nses, value_sort_cmp);
23000
23001   for (i = 0; i < vec_len (nses); i++)
23002     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23003   vec_free (nses);
23004   return 0;
23005 }
23006
23007 static int
23008 get_msg_id (vat_main_t * vam)
23009 {
23010   u8 *name_and_crc;
23011   u32 message_index;
23012
23013   if (unformat (vam->input, "%s", &name_and_crc))
23014     {
23015       message_index = vl_msg_api_get_msg_index (name_and_crc);
23016       if (message_index == ~0)
23017         {
23018           print (vam->ofp, " '%s' not found", name_and_crc);
23019           return 0;
23020         }
23021       print (vam->ofp, " '%s' has message index %d",
23022              name_and_crc, message_index);
23023       return 0;
23024     }
23025   errmsg ("name_and_crc required...");
23026   return 0;
23027 }
23028
23029 static int
23030 search_node_table (vat_main_t * vam)
23031 {
23032   unformat_input_t *line_input = vam->input;
23033   u8 *node_to_find;
23034   int j;
23035   vlib_node_t *node, *next_node;
23036   uword *p;
23037
23038   if (vam->graph_node_index_by_name == 0)
23039     {
23040       print (vam->ofp, "Node table empty, issue get_node_graph...");
23041       return 0;
23042     }
23043
23044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23045     {
23046       if (unformat (line_input, "%s", &node_to_find))
23047         {
23048           vec_add1 (node_to_find, 0);
23049           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23050           if (p == 0)
23051             {
23052               print (vam->ofp, "%s not found...", node_to_find);
23053               goto out;
23054             }
23055           node = vam->graph_nodes[0][p[0]];
23056           print (vam->ofp, "[%d] %s", p[0], node->name);
23057           for (j = 0; j < vec_len (node->next_nodes); j++)
23058             {
23059               if (node->next_nodes[j] != ~0)
23060                 {
23061                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23062                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23063                 }
23064             }
23065         }
23066
23067       else
23068         {
23069           clib_warning ("parse error '%U'", format_unformat_error,
23070                         line_input);
23071           return -99;
23072         }
23073
23074     out:
23075       vec_free (node_to_find);
23076
23077     }
23078
23079   return 0;
23080 }
23081
23082
23083 static int
23084 script (vat_main_t * vam)
23085 {
23086 #if (VPP_API_TEST_BUILTIN==0)
23087   u8 *s = 0;
23088   char *save_current_file;
23089   unformat_input_t save_input;
23090   jmp_buf save_jump_buf;
23091   u32 save_line_number;
23092
23093   FILE *new_fp, *save_ifp;
23094
23095   if (unformat (vam->input, "%s", &s))
23096     {
23097       new_fp = fopen ((char *) s, "r");
23098       if (new_fp == 0)
23099         {
23100           errmsg ("Couldn't open script file %s", s);
23101           vec_free (s);
23102           return -99;
23103         }
23104     }
23105   else
23106     {
23107       errmsg ("Missing script name");
23108       return -99;
23109     }
23110
23111   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23112   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23113   save_ifp = vam->ifp;
23114   save_line_number = vam->input_line_number;
23115   save_current_file = (char *) vam->current_file;
23116
23117   vam->input_line_number = 0;
23118   vam->ifp = new_fp;
23119   vam->current_file = s;
23120   do_one_file (vam);
23121
23122   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23123   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23124   vam->ifp = save_ifp;
23125   vam->input_line_number = save_line_number;
23126   vam->current_file = (u8 *) save_current_file;
23127   vec_free (s);
23128
23129   return 0;
23130 #else
23131   clib_warning ("use the exec command...");
23132   return -99;
23133 #endif
23134 }
23135
23136 static int
23137 echo (vat_main_t * vam)
23138 {
23139   print (vam->ofp, "%v", vam->input->buffer);
23140   return 0;
23141 }
23142
23143 /* List of API message constructors, CLI names map to api_xxx */
23144 #define foreach_vpe_api_msg                                             \
23145 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23146 _(sw_interface_dump,"")                                                 \
23147 _(sw_interface_set_flags,                                               \
23148   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23149 _(sw_interface_add_del_address,                                         \
23150   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23151 _(sw_interface_set_rx_mode,                                             \
23152   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23153 _(sw_interface_set_table,                                               \
23154   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23155 _(sw_interface_set_mpls_enable,                                         \
23156   "<intfc> | sw_if_index [disable | dis]")                              \
23157 _(sw_interface_set_vpath,                                               \
23158   "<intfc> | sw_if_index <id> enable | disable")                        \
23159 _(sw_interface_set_vxlan_bypass,                                        \
23160   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23161 _(sw_interface_set_geneve_bypass,                                       \
23162   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23163 _(sw_interface_set_l2_xconnect,                                         \
23164   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23165   "enable | disable")                                                   \
23166 _(sw_interface_set_l2_bridge,                                           \
23167   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23168   "[shg <split-horizon-group>] [bvi]\n"                                 \
23169   "enable | disable")                                                   \
23170 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23171 _(bridge_domain_add_del,                                                \
23172   "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") \
23173 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23174 _(l2fib_add_del,                                                        \
23175   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23176 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23177 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23178 _(l2_flags,                                                             \
23179   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23180 _(bridge_flags,                                                         \
23181   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23182 _(tap_connect,                                                          \
23183   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23184 _(tap_modify,                                                           \
23185   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23186 _(tap_delete,                                                           \
23187   "<vpp-if-name> | sw_if_index <id>")                                   \
23188 _(sw_interface_tap_dump, "")                                            \
23189 _(tap_create_v2,                                                        \
23190   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23191 _(tap_delete_v2,                                                        \
23192   "<vpp-if-name> | sw_if_index <id>")                                   \
23193 _(sw_interface_tap_v2_dump, "")                                         \
23194 _(bond_create,                                                          \
23195   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23196   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23197 _(bond_delete,                                                          \
23198   "<vpp-if-name> | sw_if_index <id>")                                   \
23199 _(bond_enslave,                                                         \
23200   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23201 _(bond_detach_slave,                                                    \
23202   "sw_if_index <n>")                                                    \
23203 _(sw_interface_bond_dump, "")                                           \
23204 _(sw_interface_slave_dump,                                              \
23205   "<vpp-if-name> | sw_if_index <id>")                                   \
23206 _(ip_table_add_del,                                                     \
23207   "table-id <n> [ipv6]\n")                                              \
23208 _(ip_add_del_route,                                                     \
23209   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23210   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23211   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23212   "[multipath] [count <n>]")                                            \
23213 _(ip_mroute_add_del,                                                    \
23214   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23215   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23216 _(mpls_table_add_del,                                                   \
23217   "table-id <n>\n")                                                     \
23218 _(mpls_route_add_del,                                                   \
23219   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23220   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23221   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23222   "[multipath] [count <n>]")                                            \
23223 _(mpls_ip_bind_unbind,                                                  \
23224   "<label> <addr/len>")                                                 \
23225 _(mpls_tunnel_add_del,                                                  \
23226   " via <addr> [table-id <n>]\n"                                        \
23227   "sw_if_index <id>] [l2]  [del]")                                      \
23228 _(bier_table_add_del,                                                   \
23229   "<label> <sub-domain> <set> <bsl> [del]")                             \
23230 _(bier_route_add_del,                                                   \
23231   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23232   "[<intfc> | sw_if_index <id>]"                                        \
23233   "[weight <n>] [del] [multipath]")                                     \
23234 _(proxy_arp_add_del,                                                    \
23235   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23236 _(proxy_arp_intfc_enable_disable,                                       \
23237   "<intfc> | sw_if_index <id> enable | disable")                        \
23238 _(sw_interface_set_unnumbered,                                          \
23239   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23240 _(ip_neighbor_add_del,                                                  \
23241   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23242   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23243 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23244 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23245   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23246   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23247   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23248 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23249 _(reset_fib, "vrf <n> [ipv6]")                                          \
23250 _(dhcp_proxy_config,                                                    \
23251   "svr <v46-address> src <v46-address>\n"                               \
23252    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23253 _(dhcp_proxy_set_vss,                                                   \
23254   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23255 _(dhcp_proxy_dump, "ip6")                                               \
23256 _(dhcp_client_config,                                                   \
23257   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23258 _(set_ip_flow_hash,                                                     \
23259   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23260 _(sw_interface_ip6_enable_disable,                                      \
23261   "<intfc> | sw_if_index <id> enable | disable")                        \
23262 _(sw_interface_ip6_set_link_local_address,                              \
23263   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23264 _(ip6nd_proxy_add_del,                                                  \
23265   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23266 _(ip6nd_proxy_dump, "")                                                 \
23267 _(sw_interface_ip6nd_ra_prefix,                                         \
23268   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23269   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23270   "[nolink] [isno]")                                                    \
23271 _(sw_interface_ip6nd_ra_config,                                         \
23272   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23273   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23274   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23275 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23276 _(l2_patch_add_del,                                                     \
23277   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23278   "enable | disable")                                                   \
23279 _(sr_localsid_add_del,                                                  \
23280   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23281   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23282 _(classify_add_del_table,                                               \
23283   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23284   " [del] [del-chain] mask <mask-value>\n"                              \
23285   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23286   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23287 _(classify_add_del_session,                                             \
23288   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23289   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23290   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23291   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23292 _(classify_set_interface_ip_table,                                      \
23293   "<intfc> | sw_if_index <nn> table <nn>")                              \
23294 _(classify_set_interface_l2_tables,                                     \
23295   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23296   "  [other-table <nn>]")                                               \
23297 _(get_node_index, "node <node-name")                                    \
23298 _(add_node_next, "node <node-name> next <next-node-name>")              \
23299 _(l2tpv3_create_tunnel,                                                 \
23300   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23301   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23302   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23303 _(l2tpv3_set_tunnel_cookies,                                            \
23304   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23305   "[new_remote_cookie <nn>]\n")                                         \
23306 _(l2tpv3_interface_enable_disable,                                      \
23307   "<intfc> | sw_if_index <nn> enable | disable")                        \
23308 _(l2tpv3_set_lookup_key,                                                \
23309   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23310 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23311 _(vxlan_offload_rx,                                                     \
23312   "hw { <interface name> | hw_if_index <nn>} "                          \
23313   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23314 _(vxlan_add_del_tunnel,                                                 \
23315   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23316   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23317   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23318 _(geneve_add_del_tunnel,                                                \
23319   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23320   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23321   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23322 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23323 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23324 _(gre_add_del_tunnel,                                                   \
23325   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23326   "[teb | erspan <session-id>] [del]")                                  \
23327 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23328 _(l2_fib_clear_table, "")                                               \
23329 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23330 _(l2_interface_vlan_tag_rewrite,                                        \
23331   "<intfc> | sw_if_index <nn> \n"                                       \
23332   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23333   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23334 _(create_vhost_user_if,                                                 \
23335         "socket <filename> [server] [renumber <dev_instance>] "         \
23336         "[mac <mac_address>]")                                          \
23337 _(modify_vhost_user_if,                                                 \
23338         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23339         "[server] [renumber <dev_instance>]")                           \
23340 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23341 _(sw_interface_vhost_user_dump, "")                                     \
23342 _(show_version, "")                                                     \
23343 _(vxlan_gpe_add_del_tunnel,                                             \
23344   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23345   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23346   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23347   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23348 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23349 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23350 _(interface_name_renumber,                                              \
23351   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23352 _(input_acl_set_interface,                                              \
23353   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23354   "  [l2-table <nn>] [del]")                                            \
23355 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23356 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23357   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23358 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23359 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23360 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23361 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23362 _(ip_dump, "ipv4 | ipv6")                                               \
23363 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23364 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23365   "  spid_id <n> ")                                                     \
23366 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23367   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23368   "  integ_alg <alg> integ_key <hex>")                                  \
23369 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23370   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23371   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23372   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23373 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23374 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23375   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23376   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23377   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23378   "  [instance <n>]")     \
23379 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23380 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23381   "  <alg> <hex>\n")                                                    \
23382 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23383 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23384 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23385   "(auth_data 0x<data> | auth_data <data>)")                            \
23386 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23387   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23388 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23389   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23390   "(local|remote)")                                                     \
23391 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23392 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23393 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23394 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23395 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23396 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23397 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23398 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23399 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23400 _(delete_loopback,"sw_if_index <nn>")                                   \
23401 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23402 _(want_interface_events,  "enable|disable")                             \
23403 _(want_stats,"enable|disable")                                          \
23404 _(get_first_msg_id, "client <name>")                                    \
23405 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23406 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23407   "fib-id <nn> [ip4][ip6][default]")                                    \
23408 _(get_node_graph, " ")                                                  \
23409 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23410 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23411 _(ioam_disable, "")                                                     \
23412 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23413                             " sw_if_index <sw_if_index> p <priority> "  \
23414                             "w <weight>] [del]")                        \
23415 _(one_add_del_locator, "locator-set <locator_name> "                    \
23416                         "iface <intf> | sw_if_index <sw_if_index> "     \
23417                         "p <priority> w <weight> [del]")                \
23418 _(one_add_del_local_eid,"vni <vni> eid "                                \
23419                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23420                          "locator-set <locator_name> [del]"             \
23421                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23422 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23423 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23424 _(one_enable_disable, "enable|disable")                                 \
23425 _(one_map_register_enable_disable, "enable|disable")                    \
23426 _(one_map_register_fallback_threshold, "<value>")                       \
23427 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23428 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23429                                "[seid <seid>] "                         \
23430                                "rloc <locator> p <prio> "               \
23431                                "w <weight> [rloc <loc> ... ] "          \
23432                                "action <action> [del-all]")             \
23433 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23434                           "<local-eid>")                                \
23435 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23436 _(one_use_petr, "ip-address> | disable")                                \
23437 _(one_map_request_mode, "src-dst|dst-only")                             \
23438 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23439 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23440 _(one_locator_set_dump, "[local | remote]")                             \
23441 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23442 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23443                        "[local] | [remote]")                            \
23444 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23445 _(one_ndp_bd_get, "")                                                   \
23446 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23447 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23448 _(one_l2_arp_bd_get, "")                                                \
23449 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23450 _(one_stats_enable_disable, "enable|disalbe")                           \
23451 _(show_one_stats_enable_disable, "")                                    \
23452 _(one_eid_table_vni_dump, "")                                           \
23453 _(one_eid_table_map_dump, "l2|l3")                                      \
23454 _(one_map_resolver_dump, "")                                            \
23455 _(one_map_server_dump, "")                                              \
23456 _(one_adjacencies_get, "vni <vni>")                                     \
23457 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23458 _(show_one_rloc_probe_state, "")                                        \
23459 _(show_one_map_register_state, "")                                      \
23460 _(show_one_status, "")                                                  \
23461 _(one_stats_dump, "")                                                   \
23462 _(one_stats_flush, "")                                                  \
23463 _(one_get_map_request_itr_rlocs, "")                                    \
23464 _(one_map_register_set_ttl, "<ttl>")                                    \
23465 _(one_set_transport_protocol, "udp|api")                                \
23466 _(one_get_transport_protocol, "")                                       \
23467 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23468 _(one_show_xtr_mode, "")                                                \
23469 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23470 _(one_show_pitr_mode, "")                                               \
23471 _(one_enable_disable_petr_mode, "enable|disable")                       \
23472 _(one_show_petr_mode, "")                                               \
23473 _(show_one_nsh_mapping, "")                                             \
23474 _(show_one_pitr, "")                                                    \
23475 _(show_one_use_petr, "")                                                \
23476 _(show_one_map_request_mode, "")                                        \
23477 _(show_one_map_register_ttl, "")                                        \
23478 _(show_one_map_register_fallback_threshold, "")                         \
23479 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23480                             " sw_if_index <sw_if_index> p <priority> "  \
23481                             "w <weight>] [del]")                        \
23482 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23483                         "iface <intf> | sw_if_index <sw_if_index> "     \
23484                         "p <priority> w <weight> [del]")                \
23485 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23486                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23487                          "locator-set <locator_name> [del]"             \
23488                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23489 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23490 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23491 _(lisp_enable_disable, "enable|disable")                                \
23492 _(lisp_map_register_enable_disable, "enable|disable")                   \
23493 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23494 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23495                                "[seid <seid>] "                         \
23496                                "rloc <locator> p <prio> "               \
23497                                "w <weight> [rloc <loc> ... ] "          \
23498                                "action <action> [del-all]")             \
23499 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23500                           "<local-eid>")                                \
23501 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23502 _(lisp_use_petr, "<ip-address> | disable")                              \
23503 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23504 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23505 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23506 _(lisp_locator_set_dump, "[local | remote]")                            \
23507 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23508 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23509                        "[local] | [remote]")                            \
23510 _(lisp_eid_table_vni_dump, "")                                          \
23511 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23512 _(lisp_map_resolver_dump, "")                                           \
23513 _(lisp_map_server_dump, "")                                             \
23514 _(lisp_adjacencies_get, "vni <vni>")                                    \
23515 _(gpe_fwd_entry_vnis_get, "")                                           \
23516 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23517 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23518                                 "[table <table-id>]")                   \
23519 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23520 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23521 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23522 _(gpe_get_encap_mode, "")                                               \
23523 _(lisp_gpe_add_del_iface, "up|down")                                    \
23524 _(lisp_gpe_enable_disable, "enable|disable")                            \
23525 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23526   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23527 _(show_lisp_rloc_probe_state, "")                                       \
23528 _(show_lisp_map_register_state, "")                                     \
23529 _(show_lisp_status, "")                                                 \
23530 _(lisp_get_map_request_itr_rlocs, "")                                   \
23531 _(show_lisp_pitr, "")                                                   \
23532 _(show_lisp_use_petr, "")                                               \
23533 _(show_lisp_map_request_mode, "")                                       \
23534 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23535 _(af_packet_delete, "name <host interface name>")                       \
23536 _(af_packet_dump, "")                                                   \
23537 _(policer_add_del, "name <policer name> <params> [del]")                \
23538 _(policer_dump, "[name <policer name>]")                                \
23539 _(policer_classify_set_interface,                                       \
23540   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23541   "  [l2-table <nn>] [del]")                                            \
23542 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23543 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23544     "[master|slave]")                                                   \
23545 _(netmap_delete, "name <interface name>")                               \
23546 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23547 _(mpls_fib_dump, "")                                                    \
23548 _(classify_table_ids, "")                                               \
23549 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23550 _(classify_table_info, "table_id <nn>")                                 \
23551 _(classify_session_dump, "table_id <nn>")                               \
23552 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23553     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23554     "[template_interval <nn>] [udp_checksum]")                          \
23555 _(ipfix_exporter_dump, "")                                              \
23556 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23557 _(ipfix_classify_stream_dump, "")                                       \
23558 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23559 _(ipfix_classify_table_dump, "")                                        \
23560 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23561 _(sw_interface_span_dump, "[l2]")                                           \
23562 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23563 _(pg_create_interface, "if_id <nn>")                                    \
23564 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23565 _(pg_enable_disable, "[stream <id>] disable")                           \
23566 _(ip_source_and_port_range_check_add_del,                               \
23567   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23568 _(ip_source_and_port_range_check_interface_add_del,                     \
23569   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23570   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23571 _(ipsec_gre_add_del_tunnel,                                             \
23572   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23573 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23574 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23575 _(l2_interface_pbb_tag_rewrite,                                         \
23576   "<intfc> | sw_if_index <nn> \n"                                       \
23577   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23578   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23579 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23580 _(flow_classify_set_interface,                                          \
23581   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23582 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23583 _(ip_fib_dump, "")                                                      \
23584 _(ip_mfib_dump, "")                                                     \
23585 _(ip6_fib_dump, "")                                                     \
23586 _(ip6_mfib_dump, "")                                                    \
23587 _(feature_enable_disable, "arc_name <arc_name> "                        \
23588   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23589 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23590 "[disable]")                                                            \
23591 _(l2_xconnect_dump, "")                                                 \
23592 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23593 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23594 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23595 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23596 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23597 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23598 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23599   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23600 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23601 _(sock_init_shm, "size <nnn>")                                          \
23602 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23603 _(dns_enable_disable, "[enable][disable]")                              \
23604 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23605 _(dns_resolve_name, "<hostname>")                                       \
23606 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23607 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23608 _(dns_resolve_name, "<hostname>")                                       \
23609 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23610   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23611 _(session_rules_dump, "")                                               \
23612 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23613 _(output_acl_set_interface,                                             \
23614   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23615   "  [l2-table <nn>] [del]")                                            \
23616 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23617
23618 /* List of command functions, CLI names map directly to functions */
23619 #define foreach_cli_function                                    \
23620 _(comment, "usage: comment <ignore-rest-of-line>")              \
23621 _(dump_interface_table, "usage: dump_interface_table")          \
23622 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23623 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23624 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23625 _(dump_stats_table, "usage: dump_stats_table")                  \
23626 _(dump_macro_table, "usage: dump_macro_table ")                 \
23627 _(dump_node_table, "usage: dump_node_table")                    \
23628 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23629 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23630 _(echo, "usage: echo <message>")                                \
23631 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23632 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23633 _(help, "usage: help")                                          \
23634 _(q, "usage: quit")                                             \
23635 _(quit, "usage: quit")                                          \
23636 _(search_node_table, "usage: search_node_table <name>...")      \
23637 _(set, "usage: set <variable-name> <value>")                    \
23638 _(script, "usage: script <file-name>")                          \
23639 _(statseg, "usage: statseg");                                   \
23640 _(unset, "usage: unset <variable-name>")
23641
23642 #define _(N,n)                                  \
23643     static void vl_api_##n##_t_handler_uni      \
23644     (vl_api_##n##_t * mp)                       \
23645     {                                           \
23646         vat_main_t * vam = &vat_main;           \
23647         if (vam->json_output) {                 \
23648             vl_api_##n##_t_handler_json(mp);    \
23649         } else {                                \
23650             vl_api_##n##_t_handler(mp);         \
23651         }                                       \
23652     }
23653 foreach_vpe_api_reply_msg;
23654 #if VPP_API_TEST_BUILTIN == 0
23655 foreach_standalone_reply_msg;
23656 #endif
23657 #undef _
23658
23659 void
23660 vat_api_hookup (vat_main_t * vam)
23661 {
23662 #define _(N,n)                                                  \
23663     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23664                            vl_api_##n##_t_handler_uni,          \
23665                            vl_noop_handler,                     \
23666                            vl_api_##n##_t_endian,               \
23667                            vl_api_##n##_t_print,                \
23668                            sizeof(vl_api_##n##_t), 1);
23669   foreach_vpe_api_reply_msg;
23670 #if VPP_API_TEST_BUILTIN == 0
23671   foreach_standalone_reply_msg;
23672 #endif
23673 #undef _
23674
23675 #if (VPP_API_TEST_BUILTIN==0)
23676   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23677
23678   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23679
23680   vam->function_by_name = hash_create_string (0, sizeof (uword));
23681
23682   vam->help_by_name = hash_create_string (0, sizeof (uword));
23683 #endif
23684
23685   /* API messages we can send */
23686 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23687   foreach_vpe_api_msg;
23688 #undef _
23689
23690   /* Help strings */
23691 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23692   foreach_vpe_api_msg;
23693 #undef _
23694
23695   /* CLI functions */
23696 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23697   foreach_cli_function;
23698 #undef _
23699
23700   /* Help strings */
23701 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23702   foreach_cli_function;
23703 #undef _
23704 }
23705
23706 #if VPP_API_TEST_BUILTIN
23707 static clib_error_t *
23708 vat_api_hookup_shim (vlib_main_t * vm)
23709 {
23710   vat_api_hookup (&vat_main);
23711   return 0;
23712 }
23713
23714 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23715 #endif
23716
23717 /*
23718  * fd.io coding-style-patch-verification: ON
23719  *
23720  * Local Variables:
23721  * eval: (c-set-style "gnu")
23722  * End:
23723  */