Fix "Old Style VLA" build warnings
[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   mp->mask_len = ntohl (vec_len (mask));
11464   clib_memcpy (mp->mask, mask, vec_len (mask));
11465
11466   vec_free (mask);
11467
11468   S (mp);
11469   W (ret);
11470   return ret;
11471 }
11472
11473 #if VPP_API_TEST_BUILTIN == 0
11474 uword
11475 unformat_l4_match (unformat_input_t * input, va_list * args)
11476 {
11477   u8 **matchp = va_arg (*args, u8 **);
11478
11479   u8 *proto_header = 0;
11480   int src_port = 0;
11481   int dst_port = 0;
11482
11483   tcpudp_header_t h;
11484
11485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (input, "src_port %d", &src_port))
11488         ;
11489       else if (unformat (input, "dst_port %d", &dst_port))
11490         ;
11491       else
11492         return 0;
11493     }
11494
11495   h.src_port = clib_host_to_net_u16 (src_port);
11496   h.dst_port = clib_host_to_net_u16 (dst_port);
11497   vec_validate (proto_header, sizeof (h) - 1);
11498   memcpy (proto_header, &h, sizeof (h));
11499
11500   *matchp = proto_header;
11501
11502   return 1;
11503 }
11504
11505 uword
11506 unformat_ip4_match (unformat_input_t * input, va_list * args)
11507 {
11508   u8 **matchp = va_arg (*args, u8 **);
11509   u8 *match = 0;
11510   ip4_header_t *ip;
11511   int version = 0;
11512   u32 version_val;
11513   int hdr_length = 0;
11514   u32 hdr_length_val;
11515   int src = 0, dst = 0;
11516   ip4_address_t src_val, dst_val;
11517   int proto = 0;
11518   u32 proto_val;
11519   int tos = 0;
11520   u32 tos_val;
11521   int length = 0;
11522   u32 length_val;
11523   int fragment_id = 0;
11524   u32 fragment_id_val;
11525   int ttl = 0;
11526   int ttl_val;
11527   int checksum = 0;
11528   u32 checksum_val;
11529
11530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11531     {
11532       if (unformat (input, "version %d", &version_val))
11533         version = 1;
11534       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11535         hdr_length = 1;
11536       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11537         src = 1;
11538       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11539         dst = 1;
11540       else if (unformat (input, "proto %d", &proto_val))
11541         proto = 1;
11542       else if (unformat (input, "tos %d", &tos_val))
11543         tos = 1;
11544       else if (unformat (input, "length %d", &length_val))
11545         length = 1;
11546       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11547         fragment_id = 1;
11548       else if (unformat (input, "ttl %d", &ttl_val))
11549         ttl = 1;
11550       else if (unformat (input, "checksum %d", &checksum_val))
11551         checksum = 1;
11552       else
11553         break;
11554     }
11555
11556   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11557       + ttl + checksum == 0)
11558     return 0;
11559
11560   /*
11561    * Aligned because we use the real comparison functions
11562    */
11563   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11564
11565   ip = (ip4_header_t *) match;
11566
11567   /* These are realistically matched in practice */
11568   if (src)
11569     ip->src_address.as_u32 = src_val.as_u32;
11570
11571   if (dst)
11572     ip->dst_address.as_u32 = dst_val.as_u32;
11573
11574   if (proto)
11575     ip->protocol = proto_val;
11576
11577
11578   /* These are not, but they're included for completeness */
11579   if (version)
11580     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11581
11582   if (hdr_length)
11583     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11584
11585   if (tos)
11586     ip->tos = tos_val;
11587
11588   if (length)
11589     ip->length = clib_host_to_net_u16 (length_val);
11590
11591   if (ttl)
11592     ip->ttl = ttl_val;
11593
11594   if (checksum)
11595     ip->checksum = clib_host_to_net_u16 (checksum_val);
11596
11597   *matchp = match;
11598   return 1;
11599 }
11600
11601 uword
11602 unformat_ip6_match (unformat_input_t * input, va_list * args)
11603 {
11604   u8 **matchp = va_arg (*args, u8 **);
11605   u8 *match = 0;
11606   ip6_header_t *ip;
11607   int version = 0;
11608   u32 version_val;
11609   u8 traffic_class = 0;
11610   u32 traffic_class_val = 0;
11611   u8 flow_label = 0;
11612   u8 flow_label_val;
11613   int src = 0, dst = 0;
11614   ip6_address_t src_val, dst_val;
11615   int proto = 0;
11616   u32 proto_val;
11617   int payload_length = 0;
11618   u32 payload_length_val;
11619   int hop_limit = 0;
11620   int hop_limit_val;
11621   u32 ip_version_traffic_class_and_flow_label;
11622
11623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11624     {
11625       if (unformat (input, "version %d", &version_val))
11626         version = 1;
11627       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11628         traffic_class = 1;
11629       else if (unformat (input, "flow_label %d", &flow_label_val))
11630         flow_label = 1;
11631       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11632         src = 1;
11633       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11634         dst = 1;
11635       else if (unformat (input, "proto %d", &proto_val))
11636         proto = 1;
11637       else if (unformat (input, "payload_length %d", &payload_length_val))
11638         payload_length = 1;
11639       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11640         hop_limit = 1;
11641       else
11642         break;
11643     }
11644
11645   if (version + traffic_class + flow_label + src + dst + proto +
11646       payload_length + hop_limit == 0)
11647     return 0;
11648
11649   /*
11650    * Aligned because we use the real comparison functions
11651    */
11652   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11653
11654   ip = (ip6_header_t *) match;
11655
11656   if (src)
11657     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11658
11659   if (dst)
11660     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11661
11662   if (proto)
11663     ip->protocol = proto_val;
11664
11665   ip_version_traffic_class_and_flow_label = 0;
11666
11667   if (version)
11668     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11669
11670   if (traffic_class)
11671     ip_version_traffic_class_and_flow_label |=
11672       (traffic_class_val & 0xFF) << 20;
11673
11674   if (flow_label)
11675     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11676
11677   ip->ip_version_traffic_class_and_flow_label =
11678     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11679
11680   if (payload_length)
11681     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11682
11683   if (hop_limit)
11684     ip->hop_limit = hop_limit_val;
11685
11686   *matchp = match;
11687   return 1;
11688 }
11689
11690 uword
11691 unformat_l3_match (unformat_input_t * input, va_list * args)
11692 {
11693   u8 **matchp = va_arg (*args, u8 **);
11694
11695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11698         return 1;
11699       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11700         return 1;
11701       else
11702         break;
11703     }
11704   return 0;
11705 }
11706
11707 uword
11708 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11709 {
11710   u8 *tagp = va_arg (*args, u8 *);
11711   u32 tag;
11712
11713   if (unformat (input, "%d", &tag))
11714     {
11715       tagp[0] = (tag >> 8) & 0x0F;
11716       tagp[1] = tag & 0xFF;
11717       return 1;
11718     }
11719
11720   return 0;
11721 }
11722
11723 uword
11724 unformat_l2_match (unformat_input_t * input, va_list * args)
11725 {
11726   u8 **matchp = va_arg (*args, u8 **);
11727   u8 *match = 0;
11728   u8 src = 0;
11729   u8 src_val[6];
11730   u8 dst = 0;
11731   u8 dst_val[6];
11732   u8 proto = 0;
11733   u16 proto_val;
11734   u8 tag1 = 0;
11735   u8 tag1_val[2];
11736   u8 tag2 = 0;
11737   u8 tag2_val[2];
11738   int len = 14;
11739   u8 ignore_tag1 = 0;
11740   u8 ignore_tag2 = 0;
11741   u8 cos1 = 0;
11742   u8 cos2 = 0;
11743   u32 cos1_val = 0;
11744   u32 cos2_val = 0;
11745
11746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11747     {
11748       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11749         src = 1;
11750       else
11751         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11752         dst = 1;
11753       else if (unformat (input, "proto %U",
11754                          unformat_ethernet_type_host_byte_order, &proto_val))
11755         proto = 1;
11756       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11757         tag1 = 1;
11758       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11759         tag2 = 1;
11760       else if (unformat (input, "ignore-tag1"))
11761         ignore_tag1 = 1;
11762       else if (unformat (input, "ignore-tag2"))
11763         ignore_tag2 = 1;
11764       else if (unformat (input, "cos1 %d", &cos1_val))
11765         cos1 = 1;
11766       else if (unformat (input, "cos2 %d", &cos2_val))
11767         cos2 = 1;
11768       else
11769         break;
11770     }
11771   if ((src + dst + proto + tag1 + tag2 +
11772        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11773     return 0;
11774
11775   if (tag1 || ignore_tag1 || cos1)
11776     len = 18;
11777   if (tag2 || ignore_tag2 || cos2)
11778     len = 22;
11779
11780   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11781
11782   if (dst)
11783     clib_memcpy (match, dst_val, 6);
11784
11785   if (src)
11786     clib_memcpy (match + 6, src_val, 6);
11787
11788   if (tag2)
11789     {
11790       /* inner vlan tag */
11791       match[19] = tag2_val[1];
11792       match[18] = tag2_val[0];
11793       if (cos2)
11794         match[18] |= (cos2_val & 0x7) << 5;
11795       if (proto)
11796         {
11797           match[21] = proto_val & 0xff;
11798           match[20] = proto_val >> 8;
11799         }
11800       if (tag1)
11801         {
11802           match[15] = tag1_val[1];
11803           match[14] = tag1_val[0];
11804         }
11805       if (cos1)
11806         match[14] |= (cos1_val & 0x7) << 5;
11807       *matchp = match;
11808       return 1;
11809     }
11810   if (tag1)
11811     {
11812       match[15] = tag1_val[1];
11813       match[14] = tag1_val[0];
11814       if (proto)
11815         {
11816           match[17] = proto_val & 0xff;
11817           match[16] = proto_val >> 8;
11818         }
11819       if (cos1)
11820         match[14] |= (cos1_val & 0x7) << 5;
11821
11822       *matchp = match;
11823       return 1;
11824     }
11825   if (cos2)
11826     match[18] |= (cos2_val & 0x7) << 5;
11827   if (cos1)
11828     match[14] |= (cos1_val & 0x7) << 5;
11829   if (proto)
11830     {
11831       match[13] = proto_val & 0xff;
11832       match[12] = proto_val >> 8;
11833     }
11834
11835   *matchp = match;
11836   return 1;
11837 }
11838
11839 uword
11840 unformat_qos_source (unformat_input_t * input, va_list * args)
11841 {
11842   int *qs = va_arg (*args, int *);
11843
11844   if (unformat (input, "ip"))
11845     *qs = QOS_SOURCE_IP;
11846   else if (unformat (input, "mpls"))
11847     *qs = QOS_SOURCE_MPLS;
11848   else if (unformat (input, "ext"))
11849     *qs = QOS_SOURCE_EXT;
11850   else if (unformat (input, "vlan"))
11851     *qs = QOS_SOURCE_VLAN;
11852   else
11853     return 0;
11854
11855   return 1;
11856 }
11857 #endif
11858
11859 uword
11860 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11861 {
11862   u8 **matchp = va_arg (*args, u8 **);
11863   u32 skip_n_vectors = va_arg (*args, u32);
11864   u32 match_n_vectors = va_arg (*args, u32);
11865
11866   u8 *match = 0;
11867   u8 *l2 = 0;
11868   u8 *l3 = 0;
11869   u8 *l4 = 0;
11870
11871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11872     {
11873       if (unformat (input, "hex %U", unformat_hex_string, &match))
11874         ;
11875       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11876         ;
11877       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11878         ;
11879       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11880         ;
11881       else
11882         break;
11883     }
11884
11885   if (l4 && !l3)
11886     {
11887       vec_free (match);
11888       vec_free (l2);
11889       vec_free (l4);
11890       return 0;
11891     }
11892
11893   if (match || l2 || l3 || l4)
11894     {
11895       if (l2 || l3 || l4)
11896         {
11897           /* "Win a free Ethernet header in every packet" */
11898           if (l2 == 0)
11899             vec_validate_aligned (l2, 13, sizeof (u32x4));
11900           match = l2;
11901           if (vec_len (l3))
11902             {
11903               vec_append_aligned (match, l3, sizeof (u32x4));
11904               vec_free (l3);
11905             }
11906           if (vec_len (l4))
11907             {
11908               vec_append_aligned (match, l4, sizeof (u32x4));
11909               vec_free (l4);
11910             }
11911         }
11912
11913       /* Make sure the vector is big enough even if key is all 0's */
11914       vec_validate_aligned
11915         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11916          sizeof (u32x4));
11917
11918       /* Set size, include skipped vectors */
11919       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11920
11921       *matchp = match;
11922
11923       return 1;
11924     }
11925
11926   return 0;
11927 }
11928
11929 static int
11930 api_classify_add_del_session (vat_main_t * vam)
11931 {
11932   unformat_input_t *i = vam->input;
11933   vl_api_classify_add_del_session_t *mp;
11934   int is_add = 1;
11935   u32 table_index = ~0;
11936   u32 hit_next_index = ~0;
11937   u32 opaque_index = ~0;
11938   u8 *match = 0;
11939   i32 advance = 0;
11940   u32 skip_n_vectors = 0;
11941   u32 match_n_vectors = 0;
11942   u32 action = 0;
11943   u32 metadata = 0;
11944   int ret;
11945
11946   /*
11947    * Warning: you have to supply skip_n and match_n
11948    * because the API client cant simply look at the classify
11949    * table object.
11950    */
11951
11952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11953     {
11954       if (unformat (i, "del"))
11955         is_add = 0;
11956       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11957                          &hit_next_index))
11958         ;
11959       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11960                          &hit_next_index))
11961         ;
11962       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11963                          &hit_next_index))
11964         ;
11965       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11966         ;
11967       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11968         ;
11969       else if (unformat (i, "opaque-index %d", &opaque_index))
11970         ;
11971       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11972         ;
11973       else if (unformat (i, "match_n %d", &match_n_vectors))
11974         ;
11975       else if (unformat (i, "match %U", api_unformat_classify_match,
11976                          &match, skip_n_vectors, match_n_vectors))
11977         ;
11978       else if (unformat (i, "advance %d", &advance))
11979         ;
11980       else if (unformat (i, "table-index %d", &table_index))
11981         ;
11982       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11983         action = 1;
11984       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11985         action = 2;
11986       else if (unformat (i, "action %d", &action))
11987         ;
11988       else if (unformat (i, "metadata %d", &metadata))
11989         ;
11990       else
11991         break;
11992     }
11993
11994   if (table_index == ~0)
11995     {
11996       errmsg ("Table index required");
11997       return -99;
11998     }
11999
12000   if (is_add && match == 0)
12001     {
12002       errmsg ("Match value required");
12003       return -99;
12004     }
12005
12006   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12007
12008   mp->is_add = is_add;
12009   mp->table_index = ntohl (table_index);
12010   mp->hit_next_index = ntohl (hit_next_index);
12011   mp->opaque_index = ntohl (opaque_index);
12012   mp->advance = ntohl (advance);
12013   mp->action = action;
12014   mp->metadata = ntohl (metadata);
12015   mp->match_len = ntohl (vec_len (match));
12016   clib_memcpy (mp->match, match, vec_len (match));
12017   vec_free (match);
12018
12019   S (mp);
12020   W (ret);
12021   return ret;
12022 }
12023
12024 static int
12025 api_classify_set_interface_ip_table (vat_main_t * vam)
12026 {
12027   unformat_input_t *i = vam->input;
12028   vl_api_classify_set_interface_ip_table_t *mp;
12029   u32 sw_if_index;
12030   int sw_if_index_set;
12031   u32 table_index = ~0;
12032   u8 is_ipv6 = 0;
12033   int ret;
12034
12035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12036     {
12037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12038         sw_if_index_set = 1;
12039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12040         sw_if_index_set = 1;
12041       else if (unformat (i, "table %d", &table_index))
12042         ;
12043       else
12044         {
12045           clib_warning ("parse error '%U'", format_unformat_error, i);
12046           return -99;
12047         }
12048     }
12049
12050   if (sw_if_index_set == 0)
12051     {
12052       errmsg ("missing interface name or sw_if_index");
12053       return -99;
12054     }
12055
12056
12057   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12058
12059   mp->sw_if_index = ntohl (sw_if_index);
12060   mp->table_index = ntohl (table_index);
12061   mp->is_ipv6 = is_ipv6;
12062
12063   S (mp);
12064   W (ret);
12065   return ret;
12066 }
12067
12068 static int
12069 api_classify_set_interface_l2_tables (vat_main_t * vam)
12070 {
12071   unformat_input_t *i = vam->input;
12072   vl_api_classify_set_interface_l2_tables_t *mp;
12073   u32 sw_if_index;
12074   int sw_if_index_set;
12075   u32 ip4_table_index = ~0;
12076   u32 ip6_table_index = ~0;
12077   u32 other_table_index = ~0;
12078   u32 is_input = 1;
12079   int ret;
12080
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12084         sw_if_index_set = 1;
12085       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12086         sw_if_index_set = 1;
12087       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12088         ;
12089       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12090         ;
12091       else if (unformat (i, "other-table %d", &other_table_index))
12092         ;
12093       else if (unformat (i, "is-input %d", &is_input))
12094         ;
12095       else
12096         {
12097           clib_warning ("parse error '%U'", format_unformat_error, i);
12098           return -99;
12099         }
12100     }
12101
12102   if (sw_if_index_set == 0)
12103     {
12104       errmsg ("missing interface name or sw_if_index");
12105       return -99;
12106     }
12107
12108
12109   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12110
12111   mp->sw_if_index = ntohl (sw_if_index);
12112   mp->ip4_table_index = ntohl (ip4_table_index);
12113   mp->ip6_table_index = ntohl (ip6_table_index);
12114   mp->other_table_index = ntohl (other_table_index);
12115   mp->is_input = (u8) is_input;
12116
12117   S (mp);
12118   W (ret);
12119   return ret;
12120 }
12121
12122 static int
12123 api_set_ipfix_exporter (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   vl_api_set_ipfix_exporter_t *mp;
12127   ip4_address_t collector_address;
12128   u8 collector_address_set = 0;
12129   u32 collector_port = ~0;
12130   ip4_address_t src_address;
12131   u8 src_address_set = 0;
12132   u32 vrf_id = ~0;
12133   u32 path_mtu = ~0;
12134   u32 template_interval = ~0;
12135   u8 udp_checksum = 0;
12136   int ret;
12137
12138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12139     {
12140       if (unformat (i, "collector_address %U", unformat_ip4_address,
12141                     &collector_address))
12142         collector_address_set = 1;
12143       else if (unformat (i, "collector_port %d", &collector_port))
12144         ;
12145       else if (unformat (i, "src_address %U", unformat_ip4_address,
12146                          &src_address))
12147         src_address_set = 1;
12148       else if (unformat (i, "vrf_id %d", &vrf_id))
12149         ;
12150       else if (unformat (i, "path_mtu %d", &path_mtu))
12151         ;
12152       else if (unformat (i, "template_interval %d", &template_interval))
12153         ;
12154       else if (unformat (i, "udp_checksum"))
12155         udp_checksum = 1;
12156       else
12157         break;
12158     }
12159
12160   if (collector_address_set == 0)
12161     {
12162       errmsg ("collector_address required");
12163       return -99;
12164     }
12165
12166   if (src_address_set == 0)
12167     {
12168       errmsg ("src_address required");
12169       return -99;
12170     }
12171
12172   M (SET_IPFIX_EXPORTER, mp);
12173
12174   memcpy (mp->collector_address, collector_address.data,
12175           sizeof (collector_address.data));
12176   mp->collector_port = htons ((u16) collector_port);
12177   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12178   mp->vrf_id = htonl (vrf_id);
12179   mp->path_mtu = htonl (path_mtu);
12180   mp->template_interval = htonl (template_interval);
12181   mp->udp_checksum = udp_checksum;
12182
12183   S (mp);
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static int
12189 api_set_ipfix_classify_stream (vat_main_t * vam)
12190 {
12191   unformat_input_t *i = vam->input;
12192   vl_api_set_ipfix_classify_stream_t *mp;
12193   u32 domain_id = 0;
12194   u32 src_port = UDP_DST_PORT_ipfix;
12195   int ret;
12196
12197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12198     {
12199       if (unformat (i, "domain %d", &domain_id))
12200         ;
12201       else if (unformat (i, "src_port %d", &src_port))
12202         ;
12203       else
12204         {
12205           errmsg ("unknown input `%U'", format_unformat_error, i);
12206           return -99;
12207         }
12208     }
12209
12210   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12211
12212   mp->domain_id = htonl (domain_id);
12213   mp->src_port = htons ((u16) src_port);
12214
12215   S (mp);
12216   W (ret);
12217   return ret;
12218 }
12219
12220 static int
12221 api_ipfix_classify_table_add_del (vat_main_t * vam)
12222 {
12223   unformat_input_t *i = vam->input;
12224   vl_api_ipfix_classify_table_add_del_t *mp;
12225   int is_add = -1;
12226   u32 classify_table_index = ~0;
12227   u8 ip_version = 0;
12228   u8 transport_protocol = 255;
12229   int ret;
12230
12231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12232     {
12233       if (unformat (i, "add"))
12234         is_add = 1;
12235       else if (unformat (i, "del"))
12236         is_add = 0;
12237       else if (unformat (i, "table %d", &classify_table_index))
12238         ;
12239       else if (unformat (i, "ip4"))
12240         ip_version = 4;
12241       else if (unformat (i, "ip6"))
12242         ip_version = 6;
12243       else if (unformat (i, "tcp"))
12244         transport_protocol = 6;
12245       else if (unformat (i, "udp"))
12246         transport_protocol = 17;
12247       else
12248         {
12249           errmsg ("unknown input `%U'", format_unformat_error, i);
12250           return -99;
12251         }
12252     }
12253
12254   if (is_add == -1)
12255     {
12256       errmsg ("expecting: add|del");
12257       return -99;
12258     }
12259   if (classify_table_index == ~0)
12260     {
12261       errmsg ("classifier table not specified");
12262       return -99;
12263     }
12264   if (ip_version == 0)
12265     {
12266       errmsg ("IP version not specified");
12267       return -99;
12268     }
12269
12270   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12271
12272   mp->is_add = is_add;
12273   mp->table_id = htonl (classify_table_index);
12274   mp->ip_version = ip_version;
12275   mp->transport_protocol = transport_protocol;
12276
12277   S (mp);
12278   W (ret);
12279   return ret;
12280 }
12281
12282 static int
12283 api_get_node_index (vat_main_t * vam)
12284 {
12285   unformat_input_t *i = vam->input;
12286   vl_api_get_node_index_t *mp;
12287   u8 *name = 0;
12288   int ret;
12289
12290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12291     {
12292       if (unformat (i, "node %s", &name))
12293         ;
12294       else
12295         break;
12296     }
12297   if (name == 0)
12298     {
12299       errmsg ("node name required");
12300       return -99;
12301     }
12302   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12303     {
12304       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12305       return -99;
12306     }
12307
12308   M (GET_NODE_INDEX, mp);
12309   clib_memcpy (mp->node_name, name, vec_len (name));
12310   vec_free (name);
12311
12312   S (mp);
12313   W (ret);
12314   return ret;
12315 }
12316
12317 static int
12318 api_get_next_index (vat_main_t * vam)
12319 {
12320   unformat_input_t *i = vam->input;
12321   vl_api_get_next_index_t *mp;
12322   u8 *node_name = 0, *next_node_name = 0;
12323   int ret;
12324
12325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12326     {
12327       if (unformat (i, "node-name %s", &node_name))
12328         ;
12329       else if (unformat (i, "next-node-name %s", &next_node_name))
12330         break;
12331     }
12332
12333   if (node_name == 0)
12334     {
12335       errmsg ("node name required");
12336       return -99;
12337     }
12338   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12339     {
12340       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12341       return -99;
12342     }
12343
12344   if (next_node_name == 0)
12345     {
12346       errmsg ("next node name required");
12347       return -99;
12348     }
12349   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12350     {
12351       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12352       return -99;
12353     }
12354
12355   M (GET_NEXT_INDEX, mp);
12356   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12357   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12358   vec_free (node_name);
12359   vec_free (next_node_name);
12360
12361   S (mp);
12362   W (ret);
12363   return ret;
12364 }
12365
12366 static int
12367 api_add_node_next (vat_main_t * vam)
12368 {
12369   unformat_input_t *i = vam->input;
12370   vl_api_add_node_next_t *mp;
12371   u8 *name = 0;
12372   u8 *next = 0;
12373   int ret;
12374
12375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (i, "node %s", &name))
12378         ;
12379       else if (unformat (i, "next %s", &next))
12380         ;
12381       else
12382         break;
12383     }
12384   if (name == 0)
12385     {
12386       errmsg ("node name required");
12387       return -99;
12388     }
12389   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12390     {
12391       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12392       return -99;
12393     }
12394   if (next == 0)
12395     {
12396       errmsg ("next node required");
12397       return -99;
12398     }
12399   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12400     {
12401       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12402       return -99;
12403     }
12404
12405   M (ADD_NODE_NEXT, mp);
12406   clib_memcpy (mp->node_name, name, vec_len (name));
12407   clib_memcpy (mp->next_name, next, vec_len (next));
12408   vec_free (name);
12409   vec_free (next);
12410
12411   S (mp);
12412   W (ret);
12413   return ret;
12414 }
12415
12416 static int
12417 api_l2tpv3_create_tunnel (vat_main_t * vam)
12418 {
12419   unformat_input_t *i = vam->input;
12420   ip6_address_t client_address, our_address;
12421   int client_address_set = 0;
12422   int our_address_set = 0;
12423   u32 local_session_id = 0;
12424   u32 remote_session_id = 0;
12425   u64 local_cookie = 0;
12426   u64 remote_cookie = 0;
12427   u8 l2_sublayer_present = 0;
12428   vl_api_l2tpv3_create_tunnel_t *mp;
12429   int ret;
12430
12431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12432     {
12433       if (unformat (i, "client_address %U", unformat_ip6_address,
12434                     &client_address))
12435         client_address_set = 1;
12436       else if (unformat (i, "our_address %U", unformat_ip6_address,
12437                          &our_address))
12438         our_address_set = 1;
12439       else if (unformat (i, "local_session_id %d", &local_session_id))
12440         ;
12441       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12442         ;
12443       else if (unformat (i, "local_cookie %lld", &local_cookie))
12444         ;
12445       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12446         ;
12447       else if (unformat (i, "l2-sublayer-present"))
12448         l2_sublayer_present = 1;
12449       else
12450         break;
12451     }
12452
12453   if (client_address_set == 0)
12454     {
12455       errmsg ("client_address required");
12456       return -99;
12457     }
12458
12459   if (our_address_set == 0)
12460     {
12461       errmsg ("our_address required");
12462       return -99;
12463     }
12464
12465   M (L2TPV3_CREATE_TUNNEL, mp);
12466
12467   clib_memcpy (mp->client_address, client_address.as_u8,
12468                sizeof (mp->client_address));
12469
12470   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12471
12472   mp->local_session_id = ntohl (local_session_id);
12473   mp->remote_session_id = ntohl (remote_session_id);
12474   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12475   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12476   mp->l2_sublayer_present = l2_sublayer_present;
12477   mp->is_ipv6 = 1;
12478
12479   S (mp);
12480   W (ret);
12481   return ret;
12482 }
12483
12484 static int
12485 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12486 {
12487   unformat_input_t *i = vam->input;
12488   u32 sw_if_index;
12489   u8 sw_if_index_set = 0;
12490   u64 new_local_cookie = 0;
12491   u64 new_remote_cookie = 0;
12492   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12493   int ret;
12494
12495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12496     {
12497       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12498         sw_if_index_set = 1;
12499       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12500         sw_if_index_set = 1;
12501       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12502         ;
12503       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12504         ;
12505       else
12506         break;
12507     }
12508
12509   if (sw_if_index_set == 0)
12510     {
12511       errmsg ("missing interface name or sw_if_index");
12512       return -99;
12513     }
12514
12515   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12516
12517   mp->sw_if_index = ntohl (sw_if_index);
12518   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12519   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12520
12521   S (mp);
12522   W (ret);
12523   return ret;
12524 }
12525
12526 static int
12527 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12528 {
12529   unformat_input_t *i = vam->input;
12530   vl_api_l2tpv3_interface_enable_disable_t *mp;
12531   u32 sw_if_index;
12532   u8 sw_if_index_set = 0;
12533   u8 enable_disable = 1;
12534   int ret;
12535
12536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12537     {
12538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12539         sw_if_index_set = 1;
12540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12541         sw_if_index_set = 1;
12542       else if (unformat (i, "enable"))
12543         enable_disable = 1;
12544       else if (unformat (i, "disable"))
12545         enable_disable = 0;
12546       else
12547         break;
12548     }
12549
12550   if (sw_if_index_set == 0)
12551     {
12552       errmsg ("missing interface name or sw_if_index");
12553       return -99;
12554     }
12555
12556   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12557
12558   mp->sw_if_index = ntohl (sw_if_index);
12559   mp->enable_disable = enable_disable;
12560
12561   S (mp);
12562   W (ret);
12563   return ret;
12564 }
12565
12566 static int
12567 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12568 {
12569   unformat_input_t *i = vam->input;
12570   vl_api_l2tpv3_set_lookup_key_t *mp;
12571   u8 key = ~0;
12572   int ret;
12573
12574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12575     {
12576       if (unformat (i, "lookup_v6_src"))
12577         key = L2T_LOOKUP_SRC_ADDRESS;
12578       else if (unformat (i, "lookup_v6_dst"))
12579         key = L2T_LOOKUP_DST_ADDRESS;
12580       else if (unformat (i, "lookup_session_id"))
12581         key = L2T_LOOKUP_SESSION_ID;
12582       else
12583         break;
12584     }
12585
12586   if (key == (u8) ~ 0)
12587     {
12588       errmsg ("l2tp session lookup key unset");
12589       return -99;
12590     }
12591
12592   M (L2TPV3_SET_LOOKUP_KEY, mp);
12593
12594   mp->key = key;
12595
12596   S (mp);
12597   W (ret);
12598   return ret;
12599 }
12600
12601 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12602   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12603 {
12604   vat_main_t *vam = &vat_main;
12605
12606   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12607          format_ip6_address, mp->our_address,
12608          format_ip6_address, mp->client_address,
12609          clib_net_to_host_u32 (mp->sw_if_index));
12610
12611   print (vam->ofp,
12612          "   local cookies %016llx %016llx remote cookie %016llx",
12613          clib_net_to_host_u64 (mp->local_cookie[0]),
12614          clib_net_to_host_u64 (mp->local_cookie[1]),
12615          clib_net_to_host_u64 (mp->remote_cookie));
12616
12617   print (vam->ofp, "   local session-id %d remote session-id %d",
12618          clib_net_to_host_u32 (mp->local_session_id),
12619          clib_net_to_host_u32 (mp->remote_session_id));
12620
12621   print (vam->ofp, "   l2 specific sublayer %s\n",
12622          mp->l2_sublayer_present ? "preset" : "absent");
12623
12624 }
12625
12626 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12627   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12628 {
12629   vat_main_t *vam = &vat_main;
12630   vat_json_node_t *node = NULL;
12631   struct in6_addr addr;
12632
12633   if (VAT_JSON_ARRAY != vam->json_tree.type)
12634     {
12635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12636       vat_json_init_array (&vam->json_tree);
12637     }
12638   node = vat_json_array_add (&vam->json_tree);
12639
12640   vat_json_init_object (node);
12641
12642   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12643   vat_json_object_add_ip6 (node, "our_address", addr);
12644   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12645   vat_json_object_add_ip6 (node, "client_address", addr);
12646
12647   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12648   vat_json_init_array (lc);
12649   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12650   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12651   vat_json_object_add_uint (node, "remote_cookie",
12652                             clib_net_to_host_u64 (mp->remote_cookie));
12653
12654   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12655   vat_json_object_add_uint (node, "local_session_id",
12656                             clib_net_to_host_u32 (mp->local_session_id));
12657   vat_json_object_add_uint (node, "remote_session_id",
12658                             clib_net_to_host_u32 (mp->remote_session_id));
12659   vat_json_object_add_string_copy (node, "l2_sublayer",
12660                                    mp->l2_sublayer_present ? (u8 *) "present"
12661                                    : (u8 *) "absent");
12662 }
12663
12664 static int
12665 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12666 {
12667   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12668   vl_api_control_ping_t *mp_ping;
12669   int ret;
12670
12671   /* Get list of l2tpv3-tunnel interfaces */
12672   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12673   S (mp);
12674
12675   /* Use a control ping for synchronization */
12676   MPING (CONTROL_PING, mp_ping);
12677   S (mp_ping);
12678
12679   W (ret);
12680   return ret;
12681 }
12682
12683
12684 static void vl_api_sw_interface_tap_details_t_handler
12685   (vl_api_sw_interface_tap_details_t * mp)
12686 {
12687   vat_main_t *vam = &vat_main;
12688
12689   print (vam->ofp, "%-16s %d",
12690          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12691 }
12692
12693 static void vl_api_sw_interface_tap_details_t_handler_json
12694   (vl_api_sw_interface_tap_details_t * mp)
12695 {
12696   vat_main_t *vam = &vat_main;
12697   vat_json_node_t *node = NULL;
12698
12699   if (VAT_JSON_ARRAY != vam->json_tree.type)
12700     {
12701       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12702       vat_json_init_array (&vam->json_tree);
12703     }
12704   node = vat_json_array_add (&vam->json_tree);
12705
12706   vat_json_init_object (node);
12707   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12708   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12709 }
12710
12711 static int
12712 api_sw_interface_tap_dump (vat_main_t * vam)
12713 {
12714   vl_api_sw_interface_tap_dump_t *mp;
12715   vl_api_control_ping_t *mp_ping;
12716   int ret;
12717
12718   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12719   /* Get list of tap interfaces */
12720   M (SW_INTERFACE_TAP_DUMP, mp);
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   MPING (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731 static void vl_api_sw_interface_tap_v2_details_t_handler
12732   (vl_api_sw_interface_tap_v2_details_t * mp)
12733 {
12734   vat_main_t *vam = &vat_main;
12735
12736   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12737                     mp->host_ip4_prefix_len);
12738   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12739                     mp->host_ip6_prefix_len);
12740
12741   print (vam->ofp,
12742          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12743          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12744          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12745          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12746          mp->host_bridge, ip4, ip6);
12747
12748   vec_free (ip4);
12749   vec_free (ip6);
12750 }
12751
12752 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12753   (vl_api_sw_interface_tap_v2_details_t * mp)
12754 {
12755   vat_main_t *vam = &vat_main;
12756   vat_json_node_t *node = NULL;
12757
12758   if (VAT_JSON_ARRAY != vam->json_tree.type)
12759     {
12760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12761       vat_json_init_array (&vam->json_tree);
12762     }
12763   node = vat_json_array_add (&vam->json_tree);
12764
12765   vat_json_init_object (node);
12766   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12767   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12768   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12769   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12770   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12771   vat_json_object_add_string_copy (node, "host_mac_addr",
12772                                    format (0, "%U", format_ethernet_address,
12773                                            &mp->host_mac_addr));
12774   vat_json_object_add_string_copy (node, "host_namespace",
12775                                    mp->host_namespace);
12776   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12777   vat_json_object_add_string_copy (node, "host_ip4_addr",
12778                                    format (0, "%U/%d", format_ip4_address,
12779                                            mp->host_ip4_addr,
12780                                            mp->host_ip4_prefix_len));
12781   vat_json_object_add_string_copy (node, "host_ip6_addr",
12782                                    format (0, "%U/%d", format_ip6_address,
12783                                            mp->host_ip6_addr,
12784                                            mp->host_ip6_prefix_len));
12785
12786 }
12787
12788 static int
12789 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12790 {
12791   vl_api_sw_interface_tap_v2_dump_t *mp;
12792   vl_api_control_ping_t *mp_ping;
12793   int ret;
12794
12795   print (vam->ofp,
12796          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12797          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12798          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12799          "host_ip6_addr");
12800
12801   /* Get list of tap interfaces */
12802   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12803   S (mp);
12804
12805   /* Use a control ping for synchronization */
12806   MPING (CONTROL_PING, mp_ping);
12807   S (mp_ping);
12808
12809   W (ret);
12810   return ret;
12811 }
12812
12813 static int
12814 api_vxlan_offload_rx (vat_main_t * vam)
12815 {
12816   unformat_input_t *line_input = vam->input;
12817   vl_api_vxlan_offload_rx_t *mp;
12818   u32 hw_if_index = ~0, rx_if_index = ~0;
12819   u8 is_add = 1;
12820   int ret;
12821
12822   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12823     {
12824       if (unformat (line_input, "del"))
12825         is_add = 0;
12826       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12827                          &hw_if_index))
12828         ;
12829       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12830         ;
12831       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12832                          &rx_if_index))
12833         ;
12834       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12835         ;
12836       else
12837         {
12838           errmsg ("parse error '%U'", format_unformat_error, line_input);
12839           return -99;
12840         }
12841     }
12842
12843   if (hw_if_index == ~0)
12844     {
12845       errmsg ("no hw interface");
12846       return -99;
12847     }
12848
12849   if (rx_if_index == ~0)
12850     {
12851       errmsg ("no rx tunnel");
12852       return -99;
12853     }
12854
12855   M (VXLAN_OFFLOAD_RX, mp);
12856
12857   mp->hw_if_index = ntohl (hw_if_index);
12858   mp->sw_if_index = ntohl (rx_if_index);
12859   mp->enable = is_add;
12860
12861   S (mp);
12862   W (ret);
12863   return ret;
12864 }
12865
12866 static uword unformat_vxlan_decap_next
12867   (unformat_input_t * input, va_list * args)
12868 {
12869   u32 *result = va_arg (*args, u32 *);
12870   u32 tmp;
12871
12872   if (unformat (input, "l2"))
12873     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12874   else if (unformat (input, "%d", &tmp))
12875     *result = tmp;
12876   else
12877     return 0;
12878   return 1;
12879 }
12880
12881 static int
12882 api_vxlan_add_del_tunnel (vat_main_t * vam)
12883 {
12884   unformat_input_t *line_input = vam->input;
12885   vl_api_vxlan_add_del_tunnel_t *mp;
12886   ip46_address_t src, dst;
12887   u8 is_add = 1;
12888   u8 ipv4_set = 0, ipv6_set = 0;
12889   u8 src_set = 0;
12890   u8 dst_set = 0;
12891   u8 grp_set = 0;
12892   u32 instance = ~0;
12893   u32 mcast_sw_if_index = ~0;
12894   u32 encap_vrf_id = 0;
12895   u32 decap_next_index = ~0;
12896   u32 vni = 0;
12897   int ret;
12898
12899   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12900   memset (&src, 0, sizeof src);
12901   memset (&dst, 0, sizeof dst);
12902
12903   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12904     {
12905       if (unformat (line_input, "del"))
12906         is_add = 0;
12907       else if (unformat (line_input, "instance %d", &instance))
12908         ;
12909       else
12910         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12911         {
12912           ipv4_set = 1;
12913           src_set = 1;
12914         }
12915       else
12916         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12917         {
12918           ipv4_set = 1;
12919           dst_set = 1;
12920         }
12921       else
12922         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12923         {
12924           ipv6_set = 1;
12925           src_set = 1;
12926         }
12927       else
12928         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12929         {
12930           ipv6_set = 1;
12931           dst_set = 1;
12932         }
12933       else if (unformat (line_input, "group %U %U",
12934                          unformat_ip4_address, &dst.ip4,
12935                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12936         {
12937           grp_set = dst_set = 1;
12938           ipv4_set = 1;
12939         }
12940       else if (unformat (line_input, "group %U",
12941                          unformat_ip4_address, &dst.ip4))
12942         {
12943           grp_set = dst_set = 1;
12944           ipv4_set = 1;
12945         }
12946       else if (unformat (line_input, "group %U %U",
12947                          unformat_ip6_address, &dst.ip6,
12948                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12949         {
12950           grp_set = dst_set = 1;
12951           ipv6_set = 1;
12952         }
12953       else if (unformat (line_input, "group %U",
12954                          unformat_ip6_address, &dst.ip6))
12955         {
12956           grp_set = dst_set = 1;
12957           ipv6_set = 1;
12958         }
12959       else
12960         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12961         ;
12962       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12963         ;
12964       else if (unformat (line_input, "decap-next %U",
12965                          unformat_vxlan_decap_next, &decap_next_index))
12966         ;
12967       else if (unformat (line_input, "vni %d", &vni))
12968         ;
12969       else
12970         {
12971           errmsg ("parse error '%U'", format_unformat_error, line_input);
12972           return -99;
12973         }
12974     }
12975
12976   if (src_set == 0)
12977     {
12978       errmsg ("tunnel src address not specified");
12979       return -99;
12980     }
12981   if (dst_set == 0)
12982     {
12983       errmsg ("tunnel dst address not specified");
12984       return -99;
12985     }
12986
12987   if (grp_set && !ip46_address_is_multicast (&dst))
12988     {
12989       errmsg ("tunnel group address not multicast");
12990       return -99;
12991     }
12992   if (grp_set && mcast_sw_if_index == ~0)
12993     {
12994       errmsg ("tunnel nonexistent multicast device");
12995       return -99;
12996     }
12997   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12998     {
12999       errmsg ("tunnel dst address must be unicast");
13000       return -99;
13001     }
13002
13003
13004   if (ipv4_set && ipv6_set)
13005     {
13006       errmsg ("both IPv4 and IPv6 addresses specified");
13007       return -99;
13008     }
13009
13010   if ((vni == 0) || (vni >> 24))
13011     {
13012       errmsg ("vni not specified or out of range");
13013       return -99;
13014     }
13015
13016   M (VXLAN_ADD_DEL_TUNNEL, mp);
13017
13018   if (ipv6_set)
13019     {
13020       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13021       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13022     }
13023   else
13024     {
13025       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13026       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13027     }
13028
13029   mp->instance = htonl (instance);
13030   mp->encap_vrf_id = ntohl (encap_vrf_id);
13031   mp->decap_next_index = ntohl (decap_next_index);
13032   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13033   mp->vni = ntohl (vni);
13034   mp->is_add = is_add;
13035   mp->is_ipv6 = ipv6_set;
13036
13037   S (mp);
13038   W (ret);
13039   return ret;
13040 }
13041
13042 static void vl_api_vxlan_tunnel_details_t_handler
13043   (vl_api_vxlan_tunnel_details_t * mp)
13044 {
13045   vat_main_t *vam = &vat_main;
13046   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13047   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13048
13049   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13050          ntohl (mp->sw_if_index),
13051          ntohl (mp->instance),
13052          format_ip46_address, &src, IP46_TYPE_ANY,
13053          format_ip46_address, &dst, IP46_TYPE_ANY,
13054          ntohl (mp->encap_vrf_id),
13055          ntohl (mp->decap_next_index), ntohl (mp->vni),
13056          ntohl (mp->mcast_sw_if_index));
13057 }
13058
13059 static void vl_api_vxlan_tunnel_details_t_handler_json
13060   (vl_api_vxlan_tunnel_details_t * mp)
13061 {
13062   vat_main_t *vam = &vat_main;
13063   vat_json_node_t *node = NULL;
13064
13065   if (VAT_JSON_ARRAY != vam->json_tree.type)
13066     {
13067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13068       vat_json_init_array (&vam->json_tree);
13069     }
13070   node = vat_json_array_add (&vam->json_tree);
13071
13072   vat_json_init_object (node);
13073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13074
13075   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13076
13077   if (mp->is_ipv6)
13078     {
13079       struct in6_addr ip6;
13080
13081       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13082       vat_json_object_add_ip6 (node, "src_address", ip6);
13083       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13084       vat_json_object_add_ip6 (node, "dst_address", ip6);
13085     }
13086   else
13087     {
13088       struct in_addr ip4;
13089
13090       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13091       vat_json_object_add_ip4 (node, "src_address", ip4);
13092       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13093       vat_json_object_add_ip4 (node, "dst_address", ip4);
13094     }
13095   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13096   vat_json_object_add_uint (node, "decap_next_index",
13097                             ntohl (mp->decap_next_index));
13098   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13099   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13100   vat_json_object_add_uint (node, "mcast_sw_if_index",
13101                             ntohl (mp->mcast_sw_if_index));
13102 }
13103
13104 static int
13105 api_vxlan_tunnel_dump (vat_main_t * vam)
13106 {
13107   unformat_input_t *i = vam->input;
13108   vl_api_vxlan_tunnel_dump_t *mp;
13109   vl_api_control_ping_t *mp_ping;
13110   u32 sw_if_index;
13111   u8 sw_if_index_set = 0;
13112   int ret;
13113
13114   /* Parse args required to build the message */
13115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13116     {
13117       if (unformat (i, "sw_if_index %d", &sw_if_index))
13118         sw_if_index_set = 1;
13119       else
13120         break;
13121     }
13122
13123   if (sw_if_index_set == 0)
13124     {
13125       sw_if_index = ~0;
13126     }
13127
13128   if (!vam->json_output)
13129     {
13130       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13131              "sw_if_index", "instance", "src_address", "dst_address",
13132              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13133     }
13134
13135   /* Get list of vxlan-tunnel interfaces */
13136   M (VXLAN_TUNNEL_DUMP, mp);
13137
13138   mp->sw_if_index = htonl (sw_if_index);
13139
13140   S (mp);
13141
13142   /* Use a control ping for synchronization */
13143   MPING (CONTROL_PING, mp_ping);
13144   S (mp_ping);
13145
13146   W (ret);
13147   return ret;
13148 }
13149
13150 static uword unformat_geneve_decap_next
13151   (unformat_input_t * input, va_list * args)
13152 {
13153   u32 *result = va_arg (*args, u32 *);
13154   u32 tmp;
13155
13156   if (unformat (input, "l2"))
13157     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13158   else if (unformat (input, "%d", &tmp))
13159     *result = tmp;
13160   else
13161     return 0;
13162   return 1;
13163 }
13164
13165 static int
13166 api_geneve_add_del_tunnel (vat_main_t * vam)
13167 {
13168   unformat_input_t *line_input = vam->input;
13169   vl_api_geneve_add_del_tunnel_t *mp;
13170   ip46_address_t src, dst;
13171   u8 is_add = 1;
13172   u8 ipv4_set = 0, ipv6_set = 0;
13173   u8 src_set = 0;
13174   u8 dst_set = 0;
13175   u8 grp_set = 0;
13176   u32 mcast_sw_if_index = ~0;
13177   u32 encap_vrf_id = 0;
13178   u32 decap_next_index = ~0;
13179   u32 vni = 0;
13180   int ret;
13181
13182   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13183   memset (&src, 0, sizeof src);
13184   memset (&dst, 0, sizeof dst);
13185
13186   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (line_input, "del"))
13189         is_add = 0;
13190       else
13191         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13192         {
13193           ipv4_set = 1;
13194           src_set = 1;
13195         }
13196       else
13197         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13198         {
13199           ipv4_set = 1;
13200           dst_set = 1;
13201         }
13202       else
13203         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13204         {
13205           ipv6_set = 1;
13206           src_set = 1;
13207         }
13208       else
13209         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13210         {
13211           ipv6_set = 1;
13212           dst_set = 1;
13213         }
13214       else if (unformat (line_input, "group %U %U",
13215                          unformat_ip4_address, &dst.ip4,
13216                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13217         {
13218           grp_set = dst_set = 1;
13219           ipv4_set = 1;
13220         }
13221       else if (unformat (line_input, "group %U",
13222                          unformat_ip4_address, &dst.ip4))
13223         {
13224           grp_set = dst_set = 1;
13225           ipv4_set = 1;
13226         }
13227       else if (unformat (line_input, "group %U %U",
13228                          unformat_ip6_address, &dst.ip6,
13229                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13230         {
13231           grp_set = dst_set = 1;
13232           ipv6_set = 1;
13233         }
13234       else if (unformat (line_input, "group %U",
13235                          unformat_ip6_address, &dst.ip6))
13236         {
13237           grp_set = dst_set = 1;
13238           ipv6_set = 1;
13239         }
13240       else
13241         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13242         ;
13243       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13244         ;
13245       else if (unformat (line_input, "decap-next %U",
13246                          unformat_geneve_decap_next, &decap_next_index))
13247         ;
13248       else if (unformat (line_input, "vni %d", &vni))
13249         ;
13250       else
13251         {
13252           errmsg ("parse error '%U'", format_unformat_error, line_input);
13253           return -99;
13254         }
13255     }
13256
13257   if (src_set == 0)
13258     {
13259       errmsg ("tunnel src address not specified");
13260       return -99;
13261     }
13262   if (dst_set == 0)
13263     {
13264       errmsg ("tunnel dst address not specified");
13265       return -99;
13266     }
13267
13268   if (grp_set && !ip46_address_is_multicast (&dst))
13269     {
13270       errmsg ("tunnel group address not multicast");
13271       return -99;
13272     }
13273   if (grp_set && mcast_sw_if_index == ~0)
13274     {
13275       errmsg ("tunnel nonexistent multicast device");
13276       return -99;
13277     }
13278   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13279     {
13280       errmsg ("tunnel dst address must be unicast");
13281       return -99;
13282     }
13283
13284
13285   if (ipv4_set && ipv6_set)
13286     {
13287       errmsg ("both IPv4 and IPv6 addresses specified");
13288       return -99;
13289     }
13290
13291   if ((vni == 0) || (vni >> 24))
13292     {
13293       errmsg ("vni not specified or out of range");
13294       return -99;
13295     }
13296
13297   M (GENEVE_ADD_DEL_TUNNEL, mp);
13298
13299   if (ipv6_set)
13300     {
13301       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13302       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13303     }
13304   else
13305     {
13306       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13307       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13308     }
13309   mp->encap_vrf_id = ntohl (encap_vrf_id);
13310   mp->decap_next_index = ntohl (decap_next_index);
13311   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13312   mp->vni = ntohl (vni);
13313   mp->is_add = is_add;
13314   mp->is_ipv6 = ipv6_set;
13315
13316   S (mp);
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static void vl_api_geneve_tunnel_details_t_handler
13322   (vl_api_geneve_tunnel_details_t * mp)
13323 {
13324   vat_main_t *vam = &vat_main;
13325   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13326   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13327
13328   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13329          ntohl (mp->sw_if_index),
13330          format_ip46_address, &src, IP46_TYPE_ANY,
13331          format_ip46_address, &dst, IP46_TYPE_ANY,
13332          ntohl (mp->encap_vrf_id),
13333          ntohl (mp->decap_next_index), ntohl (mp->vni),
13334          ntohl (mp->mcast_sw_if_index));
13335 }
13336
13337 static void vl_api_geneve_tunnel_details_t_handler_json
13338   (vl_api_geneve_tunnel_details_t * mp)
13339 {
13340   vat_main_t *vam = &vat_main;
13341   vat_json_node_t *node = NULL;
13342
13343   if (VAT_JSON_ARRAY != vam->json_tree.type)
13344     {
13345       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13346       vat_json_init_array (&vam->json_tree);
13347     }
13348   node = vat_json_array_add (&vam->json_tree);
13349
13350   vat_json_init_object (node);
13351   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13352   if (mp->is_ipv6)
13353     {
13354       struct in6_addr ip6;
13355
13356       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13357       vat_json_object_add_ip6 (node, "src_address", ip6);
13358       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13359       vat_json_object_add_ip6 (node, "dst_address", ip6);
13360     }
13361   else
13362     {
13363       struct in_addr ip4;
13364
13365       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13366       vat_json_object_add_ip4 (node, "src_address", ip4);
13367       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13368       vat_json_object_add_ip4 (node, "dst_address", ip4);
13369     }
13370   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13371   vat_json_object_add_uint (node, "decap_next_index",
13372                             ntohl (mp->decap_next_index));
13373   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13374   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13375   vat_json_object_add_uint (node, "mcast_sw_if_index",
13376                             ntohl (mp->mcast_sw_if_index));
13377 }
13378
13379 static int
13380 api_geneve_tunnel_dump (vat_main_t * vam)
13381 {
13382   unformat_input_t *i = vam->input;
13383   vl_api_geneve_tunnel_dump_t *mp;
13384   vl_api_control_ping_t *mp_ping;
13385   u32 sw_if_index;
13386   u8 sw_if_index_set = 0;
13387   int ret;
13388
13389   /* Parse args required to build the message */
13390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (i, "sw_if_index %d", &sw_if_index))
13393         sw_if_index_set = 1;
13394       else
13395         break;
13396     }
13397
13398   if (sw_if_index_set == 0)
13399     {
13400       sw_if_index = ~0;
13401     }
13402
13403   if (!vam->json_output)
13404     {
13405       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13406              "sw_if_index", "local_address", "remote_address",
13407              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13408     }
13409
13410   /* Get list of geneve-tunnel interfaces */
13411   M (GENEVE_TUNNEL_DUMP, mp);
13412
13413   mp->sw_if_index = htonl (sw_if_index);
13414
13415   S (mp);
13416
13417   /* Use a control ping for synchronization */
13418   M (CONTROL_PING, mp_ping);
13419   S (mp_ping);
13420
13421   W (ret);
13422   return ret;
13423 }
13424
13425 static int
13426 api_gre_add_del_tunnel (vat_main_t * vam)
13427 {
13428   unformat_input_t *line_input = vam->input;
13429   vl_api_gre_add_del_tunnel_t *mp;
13430   ip4_address_t src4, dst4;
13431   ip6_address_t src6, dst6;
13432   u8 is_add = 1;
13433   u8 ipv4_set = 0;
13434   u8 ipv6_set = 0;
13435   u8 t_type = GRE_TUNNEL_TYPE_L3;
13436   u8 src_set = 0;
13437   u8 dst_set = 0;
13438   u32 outer_fib_id = 0;
13439   u32 session_id = 0;
13440   u32 instance = ~0;
13441   int ret;
13442
13443   memset (&src4, 0, sizeof src4);
13444   memset (&dst4, 0, sizeof dst4);
13445   memset (&src6, 0, sizeof src6);
13446   memset (&dst6, 0, sizeof dst6);
13447
13448   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13449     {
13450       if (unformat (line_input, "del"))
13451         is_add = 0;
13452       else if (unformat (line_input, "instance %d", &instance))
13453         ;
13454       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13455         {
13456           src_set = 1;
13457           ipv4_set = 1;
13458         }
13459       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13460         {
13461           dst_set = 1;
13462           ipv4_set = 1;
13463         }
13464       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13465         {
13466           src_set = 1;
13467           ipv6_set = 1;
13468         }
13469       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13470         {
13471           dst_set = 1;
13472           ipv6_set = 1;
13473         }
13474       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13475         ;
13476       else if (unformat (line_input, "teb"))
13477         t_type = GRE_TUNNEL_TYPE_TEB;
13478       else if (unformat (line_input, "erspan %d", &session_id))
13479         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13480       else
13481         {
13482           errmsg ("parse error '%U'", format_unformat_error, line_input);
13483           return -99;
13484         }
13485     }
13486
13487   if (src_set == 0)
13488     {
13489       errmsg ("tunnel src address not specified");
13490       return -99;
13491     }
13492   if (dst_set == 0)
13493     {
13494       errmsg ("tunnel dst address not specified");
13495       return -99;
13496     }
13497   if (ipv4_set && ipv6_set)
13498     {
13499       errmsg ("both IPv4 and IPv6 addresses specified");
13500       return -99;
13501     }
13502
13503
13504   M (GRE_ADD_DEL_TUNNEL, mp);
13505
13506   if (ipv4_set)
13507     {
13508       clib_memcpy (&mp->src_address, &src4, 4);
13509       clib_memcpy (&mp->dst_address, &dst4, 4);
13510     }
13511   else
13512     {
13513       clib_memcpy (&mp->src_address, &src6, 16);
13514       clib_memcpy (&mp->dst_address, &dst6, 16);
13515     }
13516   mp->instance = htonl (instance);
13517   mp->outer_fib_id = htonl (outer_fib_id);
13518   mp->is_add = is_add;
13519   mp->session_id = htons ((u16) session_id);
13520   mp->tunnel_type = t_type;
13521   mp->is_ipv6 = ipv6_set;
13522
13523   S (mp);
13524   W (ret);
13525   return ret;
13526 }
13527
13528 static void vl_api_gre_tunnel_details_t_handler
13529   (vl_api_gre_tunnel_details_t * mp)
13530 {
13531   vat_main_t *vam = &vat_main;
13532   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13533   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13534
13535   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13536          ntohl (mp->sw_if_index),
13537          ntohl (mp->instance),
13538          format_ip46_address, &src, IP46_TYPE_ANY,
13539          format_ip46_address, &dst, IP46_TYPE_ANY,
13540          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13541 }
13542
13543 static void vl_api_gre_tunnel_details_t_handler_json
13544   (vl_api_gre_tunnel_details_t * mp)
13545 {
13546   vat_main_t *vam = &vat_main;
13547   vat_json_node_t *node = NULL;
13548   struct in_addr ip4;
13549   struct in6_addr ip6;
13550
13551   if (VAT_JSON_ARRAY != vam->json_tree.type)
13552     {
13553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13554       vat_json_init_array (&vam->json_tree);
13555     }
13556   node = vat_json_array_add (&vam->json_tree);
13557
13558   vat_json_init_object (node);
13559   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13560   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13561   if (!mp->is_ipv6)
13562     {
13563       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13564       vat_json_object_add_ip4 (node, "src_address", ip4);
13565       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13566       vat_json_object_add_ip4 (node, "dst_address", ip4);
13567     }
13568   else
13569     {
13570       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13571       vat_json_object_add_ip6 (node, "src_address", ip6);
13572       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13573       vat_json_object_add_ip6 (node, "dst_address", ip6);
13574     }
13575   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13576   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13577   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13578   vat_json_object_add_uint (node, "session_id", mp->session_id);
13579 }
13580
13581 static int
13582 api_gre_tunnel_dump (vat_main_t * vam)
13583 {
13584   unformat_input_t *i = vam->input;
13585   vl_api_gre_tunnel_dump_t *mp;
13586   vl_api_control_ping_t *mp_ping;
13587   u32 sw_if_index;
13588   u8 sw_if_index_set = 0;
13589   int ret;
13590
13591   /* Parse args required to build the message */
13592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13593     {
13594       if (unformat (i, "sw_if_index %d", &sw_if_index))
13595         sw_if_index_set = 1;
13596       else
13597         break;
13598     }
13599
13600   if (sw_if_index_set == 0)
13601     {
13602       sw_if_index = ~0;
13603     }
13604
13605   if (!vam->json_output)
13606     {
13607       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13608              "sw_if_index", "instance", "src_address", "dst_address",
13609              "tunnel_type", "outer_fib_id", "session_id");
13610     }
13611
13612   /* Get list of gre-tunnel interfaces */
13613   M (GRE_TUNNEL_DUMP, mp);
13614
13615   mp->sw_if_index = htonl (sw_if_index);
13616
13617   S (mp);
13618
13619   /* Use a control ping for synchronization */
13620   MPING (CONTROL_PING, mp_ping);
13621   S (mp_ping);
13622
13623   W (ret);
13624   return ret;
13625 }
13626
13627 static int
13628 api_l2_fib_clear_table (vat_main_t * vam)
13629 {
13630 //  unformat_input_t * i = vam->input;
13631   vl_api_l2_fib_clear_table_t *mp;
13632   int ret;
13633
13634   M (L2_FIB_CLEAR_TABLE, mp);
13635
13636   S (mp);
13637   W (ret);
13638   return ret;
13639 }
13640
13641 static int
13642 api_l2_interface_efp_filter (vat_main_t * vam)
13643 {
13644   unformat_input_t *i = vam->input;
13645   vl_api_l2_interface_efp_filter_t *mp;
13646   u32 sw_if_index;
13647   u8 enable = 1;
13648   u8 sw_if_index_set = 0;
13649   int ret;
13650
13651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13652     {
13653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13654         sw_if_index_set = 1;
13655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13656         sw_if_index_set = 1;
13657       else if (unformat (i, "enable"))
13658         enable = 1;
13659       else if (unformat (i, "disable"))
13660         enable = 0;
13661       else
13662         {
13663           clib_warning ("parse error '%U'", format_unformat_error, i);
13664           return -99;
13665         }
13666     }
13667
13668   if (sw_if_index_set == 0)
13669     {
13670       errmsg ("missing sw_if_index");
13671       return -99;
13672     }
13673
13674   M (L2_INTERFACE_EFP_FILTER, mp);
13675
13676   mp->sw_if_index = ntohl (sw_if_index);
13677   mp->enable_disable = enable;
13678
13679   S (mp);
13680   W (ret);
13681   return ret;
13682 }
13683
13684 #define foreach_vtr_op                          \
13685 _("disable",  L2_VTR_DISABLED)                  \
13686 _("push-1",  L2_VTR_PUSH_1)                     \
13687 _("push-2",  L2_VTR_PUSH_2)                     \
13688 _("pop-1",  L2_VTR_POP_1)                       \
13689 _("pop-2",  L2_VTR_POP_2)                       \
13690 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13691 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13692 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13693 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13694
13695 static int
13696 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13697 {
13698   unformat_input_t *i = vam->input;
13699   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13700   u32 sw_if_index;
13701   u8 sw_if_index_set = 0;
13702   u8 vtr_op_set = 0;
13703   u32 vtr_op = 0;
13704   u32 push_dot1q = 1;
13705   u32 tag1 = ~0;
13706   u32 tag2 = ~0;
13707   int ret;
13708
13709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13710     {
13711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13712         sw_if_index_set = 1;
13713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13714         sw_if_index_set = 1;
13715       else if (unformat (i, "vtr_op %d", &vtr_op))
13716         vtr_op_set = 1;
13717 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13718       foreach_vtr_op
13719 #undef _
13720         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13721         ;
13722       else if (unformat (i, "tag1 %d", &tag1))
13723         ;
13724       else if (unformat (i, "tag2 %d", &tag2))
13725         ;
13726       else
13727         {
13728           clib_warning ("parse error '%U'", format_unformat_error, i);
13729           return -99;
13730         }
13731     }
13732
13733   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13734     {
13735       errmsg ("missing vtr operation or sw_if_index");
13736       return -99;
13737     }
13738
13739   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13740   mp->sw_if_index = ntohl (sw_if_index);
13741   mp->vtr_op = ntohl (vtr_op);
13742   mp->push_dot1q = ntohl (push_dot1q);
13743   mp->tag1 = ntohl (tag1);
13744   mp->tag2 = ntohl (tag2);
13745
13746   S (mp);
13747   W (ret);
13748   return ret;
13749 }
13750
13751 static int
13752 api_create_vhost_user_if (vat_main_t * vam)
13753 {
13754   unformat_input_t *i = vam->input;
13755   vl_api_create_vhost_user_if_t *mp;
13756   u8 *file_name;
13757   u8 is_server = 0;
13758   u8 file_name_set = 0;
13759   u32 custom_dev_instance = ~0;
13760   u8 hwaddr[6];
13761   u8 use_custom_mac = 0;
13762   u8 *tag = 0;
13763   int ret;
13764
13765   /* Shut up coverity */
13766   memset (hwaddr, 0, sizeof (hwaddr));
13767
13768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13769     {
13770       if (unformat (i, "socket %s", &file_name))
13771         {
13772           file_name_set = 1;
13773         }
13774       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13775         ;
13776       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13777         use_custom_mac = 1;
13778       else if (unformat (i, "server"))
13779         is_server = 1;
13780       else if (unformat (i, "tag %s", &tag))
13781         ;
13782       else
13783         break;
13784     }
13785
13786   if (file_name_set == 0)
13787     {
13788       errmsg ("missing socket file name");
13789       return -99;
13790     }
13791
13792   if (vec_len (file_name) > 255)
13793     {
13794       errmsg ("socket file name too long");
13795       return -99;
13796     }
13797   vec_add1 (file_name, 0);
13798
13799   M (CREATE_VHOST_USER_IF, mp);
13800
13801   mp->is_server = is_server;
13802   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13803   vec_free (file_name);
13804   if (custom_dev_instance != ~0)
13805     {
13806       mp->renumber = 1;
13807       mp->custom_dev_instance = ntohl (custom_dev_instance);
13808     }
13809   mp->use_custom_mac = use_custom_mac;
13810   clib_memcpy (mp->mac_address, hwaddr, 6);
13811   if (tag)
13812     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13813   vec_free (tag);
13814
13815   S (mp);
13816   W (ret);
13817   return ret;
13818 }
13819
13820 static int
13821 api_modify_vhost_user_if (vat_main_t * vam)
13822 {
13823   unformat_input_t *i = vam->input;
13824   vl_api_modify_vhost_user_if_t *mp;
13825   u8 *file_name;
13826   u8 is_server = 0;
13827   u8 file_name_set = 0;
13828   u32 custom_dev_instance = ~0;
13829   u8 sw_if_index_set = 0;
13830   u32 sw_if_index = (u32) ~ 0;
13831   int ret;
13832
13833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13834     {
13835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13836         sw_if_index_set = 1;
13837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13838         sw_if_index_set = 1;
13839       else if (unformat (i, "socket %s", &file_name))
13840         {
13841           file_name_set = 1;
13842         }
13843       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13844         ;
13845       else if (unformat (i, "server"))
13846         is_server = 1;
13847       else
13848         break;
13849     }
13850
13851   if (sw_if_index_set == 0)
13852     {
13853       errmsg ("missing sw_if_index or interface name");
13854       return -99;
13855     }
13856
13857   if (file_name_set == 0)
13858     {
13859       errmsg ("missing socket file name");
13860       return -99;
13861     }
13862
13863   if (vec_len (file_name) > 255)
13864     {
13865       errmsg ("socket file name too long");
13866       return -99;
13867     }
13868   vec_add1 (file_name, 0);
13869
13870   M (MODIFY_VHOST_USER_IF, mp);
13871
13872   mp->sw_if_index = ntohl (sw_if_index);
13873   mp->is_server = is_server;
13874   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13875   vec_free (file_name);
13876   if (custom_dev_instance != ~0)
13877     {
13878       mp->renumber = 1;
13879       mp->custom_dev_instance = ntohl (custom_dev_instance);
13880     }
13881
13882   S (mp);
13883   W (ret);
13884   return ret;
13885 }
13886
13887 static int
13888 api_delete_vhost_user_if (vat_main_t * vam)
13889 {
13890   unformat_input_t *i = vam->input;
13891   vl_api_delete_vhost_user_if_t *mp;
13892   u32 sw_if_index = ~0;
13893   u8 sw_if_index_set = 0;
13894   int ret;
13895
13896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13897     {
13898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13899         sw_if_index_set = 1;
13900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13901         sw_if_index_set = 1;
13902       else
13903         break;
13904     }
13905
13906   if (sw_if_index_set == 0)
13907     {
13908       errmsg ("missing sw_if_index or interface name");
13909       return -99;
13910     }
13911
13912
13913   M (DELETE_VHOST_USER_IF, mp);
13914
13915   mp->sw_if_index = ntohl (sw_if_index);
13916
13917   S (mp);
13918   W (ret);
13919   return ret;
13920 }
13921
13922 static void vl_api_sw_interface_vhost_user_details_t_handler
13923   (vl_api_sw_interface_vhost_user_details_t * mp)
13924 {
13925   vat_main_t *vam = &vat_main;
13926
13927   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13928          (char *) mp->interface_name,
13929          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13930          clib_net_to_host_u64 (mp->features), mp->is_server,
13931          ntohl (mp->num_regions), (char *) mp->sock_filename);
13932   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13933 }
13934
13935 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13936   (vl_api_sw_interface_vhost_user_details_t * mp)
13937 {
13938   vat_main_t *vam = &vat_main;
13939   vat_json_node_t *node = NULL;
13940
13941   if (VAT_JSON_ARRAY != vam->json_tree.type)
13942     {
13943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13944       vat_json_init_array (&vam->json_tree);
13945     }
13946   node = vat_json_array_add (&vam->json_tree);
13947
13948   vat_json_init_object (node);
13949   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13950   vat_json_object_add_string_copy (node, "interface_name",
13951                                    mp->interface_name);
13952   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13953                             ntohl (mp->virtio_net_hdr_sz));
13954   vat_json_object_add_uint (node, "features",
13955                             clib_net_to_host_u64 (mp->features));
13956   vat_json_object_add_uint (node, "is_server", mp->is_server);
13957   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13958   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13959   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13960 }
13961
13962 static int
13963 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13964 {
13965   vl_api_sw_interface_vhost_user_dump_t *mp;
13966   vl_api_control_ping_t *mp_ping;
13967   int ret;
13968   print (vam->ofp,
13969          "Interface name            idx hdr_sz features server regions filename");
13970
13971   /* Get list of vhost-user interfaces */
13972   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13973   S (mp);
13974
13975   /* Use a control ping for synchronization */
13976   MPING (CONTROL_PING, mp_ping);
13977   S (mp_ping);
13978
13979   W (ret);
13980   return ret;
13981 }
13982
13983 static int
13984 api_show_version (vat_main_t * vam)
13985 {
13986   vl_api_show_version_t *mp;
13987   int ret;
13988
13989   M (SHOW_VERSION, mp);
13990
13991   S (mp);
13992   W (ret);
13993   return ret;
13994 }
13995
13996
13997 static int
13998 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13999 {
14000   unformat_input_t *line_input = vam->input;
14001   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14002   ip4_address_t local4, remote4;
14003   ip6_address_t local6, remote6;
14004   u8 is_add = 1;
14005   u8 ipv4_set = 0, ipv6_set = 0;
14006   u8 local_set = 0;
14007   u8 remote_set = 0;
14008   u8 grp_set = 0;
14009   u32 mcast_sw_if_index = ~0;
14010   u32 encap_vrf_id = 0;
14011   u32 decap_vrf_id = 0;
14012   u8 protocol = ~0;
14013   u32 vni;
14014   u8 vni_set = 0;
14015   int ret;
14016
14017   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14018   memset (&local4, 0, sizeof local4);
14019   memset (&remote4, 0, sizeof remote4);
14020   memset (&local6, 0, sizeof local6);
14021   memset (&remote6, 0, sizeof remote6);
14022
14023   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14024     {
14025       if (unformat (line_input, "del"))
14026         is_add = 0;
14027       else if (unformat (line_input, "local %U",
14028                          unformat_ip4_address, &local4))
14029         {
14030           local_set = 1;
14031           ipv4_set = 1;
14032         }
14033       else if (unformat (line_input, "remote %U",
14034                          unformat_ip4_address, &remote4))
14035         {
14036           remote_set = 1;
14037           ipv4_set = 1;
14038         }
14039       else if (unformat (line_input, "local %U",
14040                          unformat_ip6_address, &local6))
14041         {
14042           local_set = 1;
14043           ipv6_set = 1;
14044         }
14045       else if (unformat (line_input, "remote %U",
14046                          unformat_ip6_address, &remote6))
14047         {
14048           remote_set = 1;
14049           ipv6_set = 1;
14050         }
14051       else if (unformat (line_input, "group %U %U",
14052                          unformat_ip4_address, &remote4,
14053                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14054         {
14055           grp_set = remote_set = 1;
14056           ipv4_set = 1;
14057         }
14058       else if (unformat (line_input, "group %U",
14059                          unformat_ip4_address, &remote4))
14060         {
14061           grp_set = remote_set = 1;
14062           ipv4_set = 1;
14063         }
14064       else if (unformat (line_input, "group %U %U",
14065                          unformat_ip6_address, &remote6,
14066                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14067         {
14068           grp_set = remote_set = 1;
14069           ipv6_set = 1;
14070         }
14071       else if (unformat (line_input, "group %U",
14072                          unformat_ip6_address, &remote6))
14073         {
14074           grp_set = remote_set = 1;
14075           ipv6_set = 1;
14076         }
14077       else
14078         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14079         ;
14080       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14081         ;
14082       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14083         ;
14084       else if (unformat (line_input, "vni %d", &vni))
14085         vni_set = 1;
14086       else if (unformat (line_input, "next-ip4"))
14087         protocol = 1;
14088       else if (unformat (line_input, "next-ip6"))
14089         protocol = 2;
14090       else if (unformat (line_input, "next-ethernet"))
14091         protocol = 3;
14092       else if (unformat (line_input, "next-nsh"))
14093         protocol = 4;
14094       else
14095         {
14096           errmsg ("parse error '%U'", format_unformat_error, line_input);
14097           return -99;
14098         }
14099     }
14100
14101   if (local_set == 0)
14102     {
14103       errmsg ("tunnel local address not specified");
14104       return -99;
14105     }
14106   if (remote_set == 0)
14107     {
14108       errmsg ("tunnel remote address not specified");
14109       return -99;
14110     }
14111   if (grp_set && mcast_sw_if_index == ~0)
14112     {
14113       errmsg ("tunnel nonexistent multicast device");
14114       return -99;
14115     }
14116   if (ipv4_set && ipv6_set)
14117     {
14118       errmsg ("both IPv4 and IPv6 addresses specified");
14119       return -99;
14120     }
14121
14122   if (vni_set == 0)
14123     {
14124       errmsg ("vni not specified");
14125       return -99;
14126     }
14127
14128   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14129
14130
14131   if (ipv6_set)
14132     {
14133       clib_memcpy (&mp->local, &local6, sizeof (local6));
14134       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14135     }
14136   else
14137     {
14138       clib_memcpy (&mp->local, &local4, sizeof (local4));
14139       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14140     }
14141
14142   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14143   mp->encap_vrf_id = ntohl (encap_vrf_id);
14144   mp->decap_vrf_id = ntohl (decap_vrf_id);
14145   mp->protocol = protocol;
14146   mp->vni = ntohl (vni);
14147   mp->is_add = is_add;
14148   mp->is_ipv6 = ipv6_set;
14149
14150   S (mp);
14151   W (ret);
14152   return ret;
14153 }
14154
14155 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14156   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14157 {
14158   vat_main_t *vam = &vat_main;
14159   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14160   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14161
14162   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14163          ntohl (mp->sw_if_index),
14164          format_ip46_address, &local, IP46_TYPE_ANY,
14165          format_ip46_address, &remote, IP46_TYPE_ANY,
14166          ntohl (mp->vni), mp->protocol,
14167          ntohl (mp->mcast_sw_if_index),
14168          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14169 }
14170
14171
14172 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14173   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14174 {
14175   vat_main_t *vam = &vat_main;
14176   vat_json_node_t *node = NULL;
14177   struct in_addr ip4;
14178   struct in6_addr ip6;
14179
14180   if (VAT_JSON_ARRAY != vam->json_tree.type)
14181     {
14182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14183       vat_json_init_array (&vam->json_tree);
14184     }
14185   node = vat_json_array_add (&vam->json_tree);
14186
14187   vat_json_init_object (node);
14188   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14189   if (mp->is_ipv6)
14190     {
14191       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14192       vat_json_object_add_ip6 (node, "local", ip6);
14193       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14194       vat_json_object_add_ip6 (node, "remote", ip6);
14195     }
14196   else
14197     {
14198       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14199       vat_json_object_add_ip4 (node, "local", ip4);
14200       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14201       vat_json_object_add_ip4 (node, "remote", ip4);
14202     }
14203   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14204   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14205   vat_json_object_add_uint (node, "mcast_sw_if_index",
14206                             ntohl (mp->mcast_sw_if_index));
14207   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14208   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14209   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14210 }
14211
14212 static int
14213 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14214 {
14215   unformat_input_t *i = vam->input;
14216   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14217   vl_api_control_ping_t *mp_ping;
14218   u32 sw_if_index;
14219   u8 sw_if_index_set = 0;
14220   int ret;
14221
14222   /* Parse args required to build the message */
14223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14224     {
14225       if (unformat (i, "sw_if_index %d", &sw_if_index))
14226         sw_if_index_set = 1;
14227       else
14228         break;
14229     }
14230
14231   if (sw_if_index_set == 0)
14232     {
14233       sw_if_index = ~0;
14234     }
14235
14236   if (!vam->json_output)
14237     {
14238       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14239              "sw_if_index", "local", "remote", "vni",
14240              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14241     }
14242
14243   /* Get list of vxlan-tunnel interfaces */
14244   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14245
14246   mp->sw_if_index = htonl (sw_if_index);
14247
14248   S (mp);
14249
14250   /* Use a control ping for synchronization */
14251   MPING (CONTROL_PING, mp_ping);
14252   S (mp_ping);
14253
14254   W (ret);
14255   return ret;
14256 }
14257
14258 static void vl_api_l2_fib_table_details_t_handler
14259   (vl_api_l2_fib_table_details_t * mp)
14260 {
14261   vat_main_t *vam = &vat_main;
14262
14263   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14264          "       %d       %d     %d",
14265          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14266          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14267          mp->bvi_mac);
14268 }
14269
14270 static void vl_api_l2_fib_table_details_t_handler_json
14271   (vl_api_l2_fib_table_details_t * mp)
14272 {
14273   vat_main_t *vam = &vat_main;
14274   vat_json_node_t *node = NULL;
14275
14276   if (VAT_JSON_ARRAY != vam->json_tree.type)
14277     {
14278       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14279       vat_json_init_array (&vam->json_tree);
14280     }
14281   node = vat_json_array_add (&vam->json_tree);
14282
14283   vat_json_init_object (node);
14284   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14285   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14286   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14287   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14288   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14289   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14290 }
14291
14292 static int
14293 api_l2_fib_table_dump (vat_main_t * vam)
14294 {
14295   unformat_input_t *i = vam->input;
14296   vl_api_l2_fib_table_dump_t *mp;
14297   vl_api_control_ping_t *mp_ping;
14298   u32 bd_id;
14299   u8 bd_id_set = 0;
14300   int ret;
14301
14302   /* Parse args required to build the message */
14303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14304     {
14305       if (unformat (i, "bd_id %d", &bd_id))
14306         bd_id_set = 1;
14307       else
14308         break;
14309     }
14310
14311   if (bd_id_set == 0)
14312     {
14313       errmsg ("missing bridge domain");
14314       return -99;
14315     }
14316
14317   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14318
14319   /* Get list of l2 fib entries */
14320   M (L2_FIB_TABLE_DUMP, mp);
14321
14322   mp->bd_id = ntohl (bd_id);
14323   S (mp);
14324
14325   /* Use a control ping for synchronization */
14326   MPING (CONTROL_PING, mp_ping);
14327   S (mp_ping);
14328
14329   W (ret);
14330   return ret;
14331 }
14332
14333
14334 static int
14335 api_interface_name_renumber (vat_main_t * vam)
14336 {
14337   unformat_input_t *line_input = vam->input;
14338   vl_api_interface_name_renumber_t *mp;
14339   u32 sw_if_index = ~0;
14340   u32 new_show_dev_instance = ~0;
14341   int ret;
14342
14343   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14344     {
14345       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14346                     &sw_if_index))
14347         ;
14348       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14349         ;
14350       else if (unformat (line_input, "new_show_dev_instance %d",
14351                          &new_show_dev_instance))
14352         ;
14353       else
14354         break;
14355     }
14356
14357   if (sw_if_index == ~0)
14358     {
14359       errmsg ("missing interface name or sw_if_index");
14360       return -99;
14361     }
14362
14363   if (new_show_dev_instance == ~0)
14364     {
14365       errmsg ("missing new_show_dev_instance");
14366       return -99;
14367     }
14368
14369   M (INTERFACE_NAME_RENUMBER, mp);
14370
14371   mp->sw_if_index = ntohl (sw_if_index);
14372   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14373
14374   S (mp);
14375   W (ret);
14376   return ret;
14377 }
14378
14379 static int
14380 api_ip_probe_neighbor (vat_main_t * vam)
14381 {
14382   unformat_input_t *i = vam->input;
14383   vl_api_ip_probe_neighbor_t *mp;
14384   u8 int_set = 0;
14385   u8 adr_set = 0;
14386   u8 is_ipv6 = 0;
14387   u8 dst_adr[16];
14388   u32 sw_if_index;
14389   int ret;
14390
14391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14392     {
14393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14394         int_set = 1;
14395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14396         int_set = 1;
14397       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14398         adr_set = 1;
14399       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14400         {
14401           adr_set = 1;
14402           is_ipv6 = 1;
14403         }
14404       else
14405         break;
14406     }
14407
14408   if (int_set == 0)
14409     {
14410       errmsg ("missing interface");
14411       return -99;
14412     }
14413
14414   if (adr_set == 0)
14415     {
14416       errmsg ("missing addresses");
14417       return -99;
14418     }
14419
14420   M (IP_PROBE_NEIGHBOR, mp);
14421
14422   mp->sw_if_index = ntohl (sw_if_index);
14423   mp->is_ipv6 = is_ipv6;
14424   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14425
14426   S (mp);
14427   W (ret);
14428   return ret;
14429 }
14430
14431 static int
14432 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14433 {
14434   unformat_input_t *i = vam->input;
14435   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14436   u8 mode = IP_SCAN_V46_NEIGHBORS;
14437   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14438   int ret;
14439
14440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14441     {
14442       if (unformat (i, "ip4"))
14443         mode = IP_SCAN_V4_NEIGHBORS;
14444       else if (unformat (i, "ip6"))
14445         mode = IP_SCAN_V6_NEIGHBORS;
14446       if (unformat (i, "both"))
14447         mode = IP_SCAN_V46_NEIGHBORS;
14448       else if (unformat (i, "disable"))
14449         mode = IP_SCAN_DISABLED;
14450       else if (unformat (i, "interval %d", &interval))
14451         ;
14452       else if (unformat (i, "max-time %d", &time))
14453         ;
14454       else if (unformat (i, "max-update %d", &update))
14455         ;
14456       else if (unformat (i, "delay %d", &delay))
14457         ;
14458       else if (unformat (i, "stale %d", &stale))
14459         ;
14460       else
14461         break;
14462     }
14463
14464   if (interval > 255)
14465     {
14466       errmsg ("interval cannot exceed 255 minutes.");
14467       return -99;
14468     }
14469   if (time > 255)
14470     {
14471       errmsg ("max-time cannot exceed 255 usec.");
14472       return -99;
14473     }
14474   if (update > 255)
14475     {
14476       errmsg ("max-update cannot exceed 255.");
14477       return -99;
14478     }
14479   if (delay > 255)
14480     {
14481       errmsg ("delay cannot exceed 255 msec.");
14482       return -99;
14483     }
14484   if (stale > 255)
14485     {
14486       errmsg ("stale cannot exceed 255 minutes.");
14487       return -99;
14488     }
14489
14490   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14491   mp->mode = mode;
14492   mp->scan_interval = interval;
14493   mp->max_proc_time = time;
14494   mp->max_update = update;
14495   mp->scan_int_delay = delay;
14496   mp->stale_threshold = stale;
14497
14498   S (mp);
14499   W (ret);
14500   return ret;
14501 }
14502
14503 static int
14504 api_want_ip4_arp_events (vat_main_t * vam)
14505 {
14506   unformat_input_t *line_input = vam->input;
14507   vl_api_want_ip4_arp_events_t *mp;
14508   ip4_address_t address;
14509   int address_set = 0;
14510   u32 enable_disable = 1;
14511   int ret;
14512
14513   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14514     {
14515       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14516         address_set = 1;
14517       else if (unformat (line_input, "del"))
14518         enable_disable = 0;
14519       else
14520         break;
14521     }
14522
14523   if (address_set == 0)
14524     {
14525       errmsg ("missing addresses");
14526       return -99;
14527     }
14528
14529   M (WANT_IP4_ARP_EVENTS, mp);
14530   mp->enable_disable = enable_disable;
14531   mp->pid = htonl (getpid ());
14532   mp->address = address.as_u32;
14533
14534   S (mp);
14535   W (ret);
14536   return ret;
14537 }
14538
14539 static int
14540 api_want_ip6_nd_events (vat_main_t * vam)
14541 {
14542   unformat_input_t *line_input = vam->input;
14543   vl_api_want_ip6_nd_events_t *mp;
14544   ip6_address_t address;
14545   int address_set = 0;
14546   u32 enable_disable = 1;
14547   int ret;
14548
14549   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14550     {
14551       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14552         address_set = 1;
14553       else if (unformat (line_input, "del"))
14554         enable_disable = 0;
14555       else
14556         break;
14557     }
14558
14559   if (address_set == 0)
14560     {
14561       errmsg ("missing addresses");
14562       return -99;
14563     }
14564
14565   M (WANT_IP6_ND_EVENTS, mp);
14566   mp->enable_disable = enable_disable;
14567   mp->pid = htonl (getpid ());
14568   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14569
14570   S (mp);
14571   W (ret);
14572   return ret;
14573 }
14574
14575 static int
14576 api_want_l2_macs_events (vat_main_t * vam)
14577 {
14578   unformat_input_t *line_input = vam->input;
14579   vl_api_want_l2_macs_events_t *mp;
14580   u8 enable_disable = 1;
14581   u32 scan_delay = 0;
14582   u32 max_macs_in_event = 0;
14583   u32 learn_limit = 0;
14584   int ret;
14585
14586   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14587     {
14588       if (unformat (line_input, "learn-limit %d", &learn_limit))
14589         ;
14590       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14591         ;
14592       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14593         ;
14594       else if (unformat (line_input, "disable"))
14595         enable_disable = 0;
14596       else
14597         break;
14598     }
14599
14600   M (WANT_L2_MACS_EVENTS, mp);
14601   mp->enable_disable = enable_disable;
14602   mp->pid = htonl (getpid ());
14603   mp->learn_limit = htonl (learn_limit);
14604   mp->scan_delay = (u8) scan_delay;
14605   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14606   S (mp);
14607   W (ret);
14608   return ret;
14609 }
14610
14611 static int
14612 api_input_acl_set_interface (vat_main_t * vam)
14613 {
14614   unformat_input_t *i = vam->input;
14615   vl_api_input_acl_set_interface_t *mp;
14616   u32 sw_if_index;
14617   int sw_if_index_set;
14618   u32 ip4_table_index = ~0;
14619   u32 ip6_table_index = ~0;
14620   u32 l2_table_index = ~0;
14621   u8 is_add = 1;
14622   int ret;
14623
14624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14627         sw_if_index_set = 1;
14628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14629         sw_if_index_set = 1;
14630       else if (unformat (i, "del"))
14631         is_add = 0;
14632       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14633         ;
14634       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14635         ;
14636       else if (unformat (i, "l2-table %d", &l2_table_index))
14637         ;
14638       else
14639         {
14640           clib_warning ("parse error '%U'", format_unformat_error, i);
14641           return -99;
14642         }
14643     }
14644
14645   if (sw_if_index_set == 0)
14646     {
14647       errmsg ("missing interface name or sw_if_index");
14648       return -99;
14649     }
14650
14651   M (INPUT_ACL_SET_INTERFACE, mp);
14652
14653   mp->sw_if_index = ntohl (sw_if_index);
14654   mp->ip4_table_index = ntohl (ip4_table_index);
14655   mp->ip6_table_index = ntohl (ip6_table_index);
14656   mp->l2_table_index = ntohl (l2_table_index);
14657   mp->is_add = is_add;
14658
14659   S (mp);
14660   W (ret);
14661   return ret;
14662 }
14663
14664 static int
14665 api_output_acl_set_interface (vat_main_t * vam)
14666 {
14667   unformat_input_t *i = vam->input;
14668   vl_api_output_acl_set_interface_t *mp;
14669   u32 sw_if_index;
14670   int sw_if_index_set;
14671   u32 ip4_table_index = ~0;
14672   u32 ip6_table_index = ~0;
14673   u32 l2_table_index = ~0;
14674   u8 is_add = 1;
14675   int ret;
14676
14677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14680         sw_if_index_set = 1;
14681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14682         sw_if_index_set = 1;
14683       else if (unformat (i, "del"))
14684         is_add = 0;
14685       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14686         ;
14687       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14688         ;
14689       else if (unformat (i, "l2-table %d", &l2_table_index))
14690         ;
14691       else
14692         {
14693           clib_warning ("parse error '%U'", format_unformat_error, i);
14694           return -99;
14695         }
14696     }
14697
14698   if (sw_if_index_set == 0)
14699     {
14700       errmsg ("missing interface name or sw_if_index");
14701       return -99;
14702     }
14703
14704   M (OUTPUT_ACL_SET_INTERFACE, mp);
14705
14706   mp->sw_if_index = ntohl (sw_if_index);
14707   mp->ip4_table_index = ntohl (ip4_table_index);
14708   mp->ip6_table_index = ntohl (ip6_table_index);
14709   mp->l2_table_index = ntohl (l2_table_index);
14710   mp->is_add = is_add;
14711
14712   S (mp);
14713   W (ret);
14714   return ret;
14715 }
14716
14717 static int
14718 api_ip_address_dump (vat_main_t * vam)
14719 {
14720   unformat_input_t *i = vam->input;
14721   vl_api_ip_address_dump_t *mp;
14722   vl_api_control_ping_t *mp_ping;
14723   u32 sw_if_index = ~0;
14724   u8 sw_if_index_set = 0;
14725   u8 ipv4_set = 0;
14726   u8 ipv6_set = 0;
14727   int ret;
14728
14729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14730     {
14731       if (unformat (i, "sw_if_index %d", &sw_if_index))
14732         sw_if_index_set = 1;
14733       else
14734         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14735         sw_if_index_set = 1;
14736       else if (unformat (i, "ipv4"))
14737         ipv4_set = 1;
14738       else if (unformat (i, "ipv6"))
14739         ipv6_set = 1;
14740       else
14741         break;
14742     }
14743
14744   if (ipv4_set && ipv6_set)
14745     {
14746       errmsg ("ipv4 and ipv6 flags cannot be both set");
14747       return -99;
14748     }
14749
14750   if ((!ipv4_set) && (!ipv6_set))
14751     {
14752       errmsg ("no ipv4 nor ipv6 flag set");
14753       return -99;
14754     }
14755
14756   if (sw_if_index_set == 0)
14757     {
14758       errmsg ("missing interface name or sw_if_index");
14759       return -99;
14760     }
14761
14762   vam->current_sw_if_index = sw_if_index;
14763   vam->is_ipv6 = ipv6_set;
14764
14765   M (IP_ADDRESS_DUMP, mp);
14766   mp->sw_if_index = ntohl (sw_if_index);
14767   mp->is_ipv6 = ipv6_set;
14768   S (mp);
14769
14770   /* Use a control ping for synchronization */
14771   MPING (CONTROL_PING, mp_ping);
14772   S (mp_ping);
14773
14774   W (ret);
14775   return ret;
14776 }
14777
14778 static int
14779 api_ip_dump (vat_main_t * vam)
14780 {
14781   vl_api_ip_dump_t *mp;
14782   vl_api_control_ping_t *mp_ping;
14783   unformat_input_t *in = vam->input;
14784   int ipv4_set = 0;
14785   int ipv6_set = 0;
14786   int is_ipv6;
14787   int i;
14788   int ret;
14789
14790   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14791     {
14792       if (unformat (in, "ipv4"))
14793         ipv4_set = 1;
14794       else if (unformat (in, "ipv6"))
14795         ipv6_set = 1;
14796       else
14797         break;
14798     }
14799
14800   if (ipv4_set && ipv6_set)
14801     {
14802       errmsg ("ipv4 and ipv6 flags cannot be both set");
14803       return -99;
14804     }
14805
14806   if ((!ipv4_set) && (!ipv6_set))
14807     {
14808       errmsg ("no ipv4 nor ipv6 flag set");
14809       return -99;
14810     }
14811
14812   is_ipv6 = ipv6_set;
14813   vam->is_ipv6 = is_ipv6;
14814
14815   /* free old data */
14816   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14817     {
14818       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14819     }
14820   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14821
14822   M (IP_DUMP, mp);
14823   mp->is_ipv6 = ipv6_set;
14824   S (mp);
14825
14826   /* Use a control ping for synchronization */
14827   MPING (CONTROL_PING, mp_ping);
14828   S (mp_ping);
14829
14830   W (ret);
14831   return ret;
14832 }
14833
14834 static int
14835 api_ipsec_spd_add_del (vat_main_t * vam)
14836 {
14837   unformat_input_t *i = vam->input;
14838   vl_api_ipsec_spd_add_del_t *mp;
14839   u32 spd_id = ~0;
14840   u8 is_add = 1;
14841   int ret;
14842
14843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14844     {
14845       if (unformat (i, "spd_id %d", &spd_id))
14846         ;
14847       else if (unformat (i, "del"))
14848         is_add = 0;
14849       else
14850         {
14851           clib_warning ("parse error '%U'", format_unformat_error, i);
14852           return -99;
14853         }
14854     }
14855   if (spd_id == ~0)
14856     {
14857       errmsg ("spd_id must be set");
14858       return -99;
14859     }
14860
14861   M (IPSEC_SPD_ADD_DEL, mp);
14862
14863   mp->spd_id = ntohl (spd_id);
14864   mp->is_add = is_add;
14865
14866   S (mp);
14867   W (ret);
14868   return ret;
14869 }
14870
14871 static int
14872 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14873 {
14874   unformat_input_t *i = vam->input;
14875   vl_api_ipsec_interface_add_del_spd_t *mp;
14876   u32 sw_if_index;
14877   u8 sw_if_index_set = 0;
14878   u32 spd_id = (u32) ~ 0;
14879   u8 is_add = 1;
14880   int ret;
14881
14882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14883     {
14884       if (unformat (i, "del"))
14885         is_add = 0;
14886       else if (unformat (i, "spd_id %d", &spd_id))
14887         ;
14888       else
14889         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14890         sw_if_index_set = 1;
14891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14892         sw_if_index_set = 1;
14893       else
14894         {
14895           clib_warning ("parse error '%U'", format_unformat_error, i);
14896           return -99;
14897         }
14898
14899     }
14900
14901   if (spd_id == (u32) ~ 0)
14902     {
14903       errmsg ("spd_id must be set");
14904       return -99;
14905     }
14906
14907   if (sw_if_index_set == 0)
14908     {
14909       errmsg ("missing interface name or sw_if_index");
14910       return -99;
14911     }
14912
14913   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14914
14915   mp->spd_id = ntohl (spd_id);
14916   mp->sw_if_index = ntohl (sw_if_index);
14917   mp->is_add = is_add;
14918
14919   S (mp);
14920   W (ret);
14921   return ret;
14922 }
14923
14924 static int
14925 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14926 {
14927   unformat_input_t *i = vam->input;
14928   vl_api_ipsec_spd_add_del_entry_t *mp;
14929   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14930   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14931   i32 priority = 0;
14932   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14933   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14934   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14935   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14936   int ret;
14937
14938   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14939   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14940   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14941   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14942   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14943   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14944
14945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14946     {
14947       if (unformat (i, "del"))
14948         is_add = 0;
14949       if (unformat (i, "outbound"))
14950         is_outbound = 1;
14951       if (unformat (i, "inbound"))
14952         is_outbound = 0;
14953       else if (unformat (i, "spd_id %d", &spd_id))
14954         ;
14955       else if (unformat (i, "sa_id %d", &sa_id))
14956         ;
14957       else if (unformat (i, "priority %d", &priority))
14958         ;
14959       else if (unformat (i, "protocol %d", &protocol))
14960         ;
14961       else if (unformat (i, "lport_start %d", &lport_start))
14962         ;
14963       else if (unformat (i, "lport_stop %d", &lport_stop))
14964         ;
14965       else if (unformat (i, "rport_start %d", &rport_start))
14966         ;
14967       else if (unformat (i, "rport_stop %d", &rport_stop))
14968         ;
14969       else
14970         if (unformat
14971             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14972         {
14973           is_ipv6 = 0;
14974           is_ip_any = 0;
14975         }
14976       else
14977         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14978         {
14979           is_ipv6 = 0;
14980           is_ip_any = 0;
14981         }
14982       else
14983         if (unformat
14984             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14985         {
14986           is_ipv6 = 0;
14987           is_ip_any = 0;
14988         }
14989       else
14990         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14991         {
14992           is_ipv6 = 0;
14993           is_ip_any = 0;
14994         }
14995       else
14996         if (unformat
14997             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14998         {
14999           is_ipv6 = 1;
15000           is_ip_any = 0;
15001         }
15002       else
15003         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15004         {
15005           is_ipv6 = 1;
15006           is_ip_any = 0;
15007         }
15008       else
15009         if (unformat
15010             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15011         {
15012           is_ipv6 = 1;
15013           is_ip_any = 0;
15014         }
15015       else
15016         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15017         {
15018           is_ipv6 = 1;
15019           is_ip_any = 0;
15020         }
15021       else
15022         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15023         {
15024           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15025             {
15026               clib_warning ("unsupported action: 'resolve'");
15027               return -99;
15028             }
15029         }
15030       else
15031         {
15032           clib_warning ("parse error '%U'", format_unformat_error, i);
15033           return -99;
15034         }
15035
15036     }
15037
15038   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15039
15040   mp->spd_id = ntohl (spd_id);
15041   mp->priority = ntohl (priority);
15042   mp->is_outbound = is_outbound;
15043
15044   mp->is_ipv6 = is_ipv6;
15045   if (is_ipv6 || is_ip_any)
15046     {
15047       clib_memcpy (mp->remote_address_start, &raddr6_start,
15048                    sizeof (ip6_address_t));
15049       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15050                    sizeof (ip6_address_t));
15051       clib_memcpy (mp->local_address_start, &laddr6_start,
15052                    sizeof (ip6_address_t));
15053       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15054                    sizeof (ip6_address_t));
15055     }
15056   else
15057     {
15058       clib_memcpy (mp->remote_address_start, &raddr4_start,
15059                    sizeof (ip4_address_t));
15060       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15061                    sizeof (ip4_address_t));
15062       clib_memcpy (mp->local_address_start, &laddr4_start,
15063                    sizeof (ip4_address_t));
15064       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15065                    sizeof (ip4_address_t));
15066     }
15067   mp->protocol = (u8) protocol;
15068   mp->local_port_start = ntohs ((u16) lport_start);
15069   mp->local_port_stop = ntohs ((u16) lport_stop);
15070   mp->remote_port_start = ntohs ((u16) rport_start);
15071   mp->remote_port_stop = ntohs ((u16) rport_stop);
15072   mp->policy = (u8) policy;
15073   mp->sa_id = ntohl (sa_id);
15074   mp->is_add = is_add;
15075   mp->is_ip_any = is_ip_any;
15076   S (mp);
15077   W (ret);
15078   return ret;
15079 }
15080
15081 static int
15082 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15083 {
15084   unformat_input_t *i = vam->input;
15085   vl_api_ipsec_sad_add_del_entry_t *mp;
15086   u32 sad_id = 0, spi = 0;
15087   u8 *ck = 0, *ik = 0;
15088   u8 is_add = 1;
15089
15090   u8 protocol = IPSEC_PROTOCOL_AH;
15091   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15092   u32 crypto_alg = 0, integ_alg = 0;
15093   ip4_address_t tun_src4;
15094   ip4_address_t tun_dst4;
15095   ip6_address_t tun_src6;
15096   ip6_address_t tun_dst6;
15097   int ret;
15098
15099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15100     {
15101       if (unformat (i, "del"))
15102         is_add = 0;
15103       else if (unformat (i, "sad_id %d", &sad_id))
15104         ;
15105       else if (unformat (i, "spi %d", &spi))
15106         ;
15107       else if (unformat (i, "esp"))
15108         protocol = IPSEC_PROTOCOL_ESP;
15109       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15110         {
15111           is_tunnel = 1;
15112           is_tunnel_ipv6 = 0;
15113         }
15114       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15115         {
15116           is_tunnel = 1;
15117           is_tunnel_ipv6 = 0;
15118         }
15119       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15120         {
15121           is_tunnel = 1;
15122           is_tunnel_ipv6 = 1;
15123         }
15124       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15125         {
15126           is_tunnel = 1;
15127           is_tunnel_ipv6 = 1;
15128         }
15129       else
15130         if (unformat
15131             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15132         {
15133           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15134             {
15135               clib_warning ("unsupported crypto-alg: '%U'",
15136                             format_ipsec_crypto_alg, crypto_alg);
15137               return -99;
15138             }
15139         }
15140       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15141         ;
15142       else
15143         if (unformat
15144             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15145         {
15146           if (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_N_ALG)
15304             {
15305               errmsg ("unsupported crypto-alg: '%U'\n",
15306                       format_ipsec_crypto_alg, crypto_alg);
15307               return -99;
15308             }
15309         }
15310       else
15311         if (unformat
15312             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15313         {
15314           if (integ_alg >= IPSEC_INTEG_N_ALG)
15315             {
15316               errmsg ("unsupported integ-alg: '%U'\n",
15317                       format_ipsec_integ_alg, integ_alg);
15318               return -99;
15319             }
15320         }
15321       else if (unformat (i, "instance %u", &instance))
15322         renumber = 1;
15323       else
15324         {
15325           errmsg ("parse error '%U'\n", format_unformat_error, i);
15326           return -99;
15327         }
15328     }
15329
15330   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15331
15332   mp->is_add = is_add;
15333   mp->esn = esn;
15334   mp->anti_replay = anti_replay;
15335
15336   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15337   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15338
15339   mp->local_spi = htonl (local_spi);
15340   mp->remote_spi = htonl (remote_spi);
15341   mp->crypto_alg = (u8) crypto_alg;
15342
15343   mp->local_crypto_key_len = 0;
15344   if (lck)
15345     {
15346       mp->local_crypto_key_len = vec_len (lck);
15347       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15348         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15349       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15350     }
15351
15352   mp->remote_crypto_key_len = 0;
15353   if (rck)
15354     {
15355       mp->remote_crypto_key_len = vec_len (rck);
15356       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15357         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15358       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15359     }
15360
15361   mp->integ_alg = (u8) integ_alg;
15362
15363   mp->local_integ_key_len = 0;
15364   if (lik)
15365     {
15366       mp->local_integ_key_len = vec_len (lik);
15367       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15368         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15369       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15370     }
15371
15372   mp->remote_integ_key_len = 0;
15373   if (rik)
15374     {
15375       mp->remote_integ_key_len = vec_len (rik);
15376       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15377         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15378       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15379     }
15380
15381   if (renumber)
15382     {
15383       mp->renumber = renumber;
15384       mp->show_instance = ntohl (instance);
15385     }
15386
15387   S (mp);
15388   W (ret);
15389   return ret;
15390 }
15391
15392 static void
15393 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15394 {
15395   vat_main_t *vam = &vat_main;
15396
15397   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15398          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15399          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15400          "tunnel_src_addr %U tunnel_dst_addr %U "
15401          "salt %u seq_outbound %lu last_seq_inbound %lu "
15402          "replay_window %lu total_data_size %lu\n",
15403          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15404          mp->protocol,
15405          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15406          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15407          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15408          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15409          mp->tunnel_src_addr,
15410          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15411          mp->tunnel_dst_addr,
15412          ntohl (mp->salt),
15413          clib_net_to_host_u64 (mp->seq_outbound),
15414          clib_net_to_host_u64 (mp->last_seq_inbound),
15415          clib_net_to_host_u64 (mp->replay_window),
15416          clib_net_to_host_u64 (mp->total_data_size));
15417 }
15418
15419 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15420 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15421
15422 static void vl_api_ipsec_sa_details_t_handler_json
15423   (vl_api_ipsec_sa_details_t * mp)
15424 {
15425   vat_main_t *vam = &vat_main;
15426   vat_json_node_t *node = NULL;
15427   struct in_addr src_ip4, dst_ip4;
15428   struct in6_addr src_ip6, dst_ip6;
15429
15430   if (VAT_JSON_ARRAY != vam->json_tree.type)
15431     {
15432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15433       vat_json_init_array (&vam->json_tree);
15434     }
15435   node = vat_json_array_add (&vam->json_tree);
15436
15437   vat_json_init_object (node);
15438   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15439   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15440   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15441   vat_json_object_add_uint (node, "proto", mp->protocol);
15442   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15443   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15444   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15445   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15446   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15447   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15448   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15449                              mp->crypto_key_len);
15450   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15451                              mp->integ_key_len);
15452   if (mp->is_tunnel_ip6)
15453     {
15454       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15455       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15456       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15457       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15458     }
15459   else
15460     {
15461       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15462       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15463       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15464       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15465     }
15466   vat_json_object_add_uint (node, "replay_window",
15467                             clib_net_to_host_u64 (mp->replay_window));
15468   vat_json_object_add_uint (node, "total_data_size",
15469                             clib_net_to_host_u64 (mp->total_data_size));
15470
15471 }
15472
15473 static int
15474 api_ipsec_sa_dump (vat_main_t * vam)
15475 {
15476   unformat_input_t *i = vam->input;
15477   vl_api_ipsec_sa_dump_t *mp;
15478   vl_api_control_ping_t *mp_ping;
15479   u32 sa_id = ~0;
15480   int ret;
15481
15482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15483     {
15484       if (unformat (i, "sa_id %d", &sa_id))
15485         ;
15486       else
15487         {
15488           clib_warning ("parse error '%U'", format_unformat_error, i);
15489           return -99;
15490         }
15491     }
15492
15493   M (IPSEC_SA_DUMP, mp);
15494
15495   mp->sa_id = ntohl (sa_id);
15496
15497   S (mp);
15498
15499   /* Use a control ping for synchronization */
15500   M (CONTROL_PING, mp_ping);
15501   S (mp_ping);
15502
15503   W (ret);
15504   return ret;
15505 }
15506
15507 static int
15508 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15509 {
15510   unformat_input_t *i = vam->input;
15511   vl_api_ipsec_tunnel_if_set_key_t *mp;
15512   u32 sw_if_index = ~0;
15513   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15514   u8 *key = 0;
15515   u32 alg = ~0;
15516   int ret;
15517
15518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15519     {
15520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15521         ;
15522       else
15523         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15524         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15525       else
15526         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15527         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15528       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15529         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15530       else
15531         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15532         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15533       else if (unformat (i, "%U", unformat_hex_string, &key))
15534         ;
15535       else
15536         {
15537           clib_warning ("parse error '%U'", format_unformat_error, i);
15538           return -99;
15539         }
15540     }
15541
15542   if (sw_if_index == ~0)
15543     {
15544       errmsg ("interface must be specified");
15545       return -99;
15546     }
15547
15548   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15549     {
15550       errmsg ("key type must be specified");
15551       return -99;
15552     }
15553
15554   if (alg == ~0)
15555     {
15556       errmsg ("algorithm must be specified");
15557       return -99;
15558     }
15559
15560   if (vec_len (key) == 0)
15561     {
15562       errmsg ("key must be specified");
15563       return -99;
15564     }
15565
15566   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15567
15568   mp->sw_if_index = htonl (sw_if_index);
15569   mp->alg = alg;
15570   mp->key_type = key_type;
15571   mp->key_len = vec_len (key);
15572   clib_memcpy (mp->key, key, vec_len (key));
15573
15574   S (mp);
15575   W (ret);
15576
15577   return ret;
15578 }
15579
15580 static int
15581 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15582 {
15583   unformat_input_t *i = vam->input;
15584   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15585   u32 sw_if_index = ~0;
15586   u32 sa_id = ~0;
15587   u8 is_outbound = (u8) ~ 0;
15588   int ret;
15589
15590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15591     {
15592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15593         ;
15594       else if (unformat (i, "sa_id %d", &sa_id))
15595         ;
15596       else if (unformat (i, "outbound"))
15597         is_outbound = 1;
15598       else if (unformat (i, "inbound"))
15599         is_outbound = 0;
15600       else
15601         {
15602           clib_warning ("parse error '%U'", format_unformat_error, i);
15603           return -99;
15604         }
15605     }
15606
15607   if (sw_if_index == ~0)
15608     {
15609       errmsg ("interface must be specified");
15610       return -99;
15611     }
15612
15613   if (sa_id == ~0)
15614     {
15615       errmsg ("SA ID must be specified");
15616       return -99;
15617     }
15618
15619   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15620
15621   mp->sw_if_index = htonl (sw_if_index);
15622   mp->sa_id = htonl (sa_id);
15623   mp->is_outbound = is_outbound;
15624
15625   S (mp);
15626   W (ret);
15627
15628   return ret;
15629 }
15630
15631 static int
15632 api_ikev2_profile_add_del (vat_main_t * vam)
15633 {
15634   unformat_input_t *i = vam->input;
15635   vl_api_ikev2_profile_add_del_t *mp;
15636   u8 is_add = 1;
15637   u8 *name = 0;
15638   int ret;
15639
15640   const char *valid_chars = "a-zA-Z0-9_";
15641
15642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15643     {
15644       if (unformat (i, "del"))
15645         is_add = 0;
15646       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15647         vec_add1 (name, 0);
15648       else
15649         {
15650           errmsg ("parse error '%U'", format_unformat_error, i);
15651           return -99;
15652         }
15653     }
15654
15655   if (!vec_len (name))
15656     {
15657       errmsg ("profile name must be specified");
15658       return -99;
15659     }
15660
15661   if (vec_len (name) > 64)
15662     {
15663       errmsg ("profile name too long");
15664       return -99;
15665     }
15666
15667   M (IKEV2_PROFILE_ADD_DEL, mp);
15668
15669   clib_memcpy (mp->name, name, vec_len (name));
15670   mp->is_add = is_add;
15671   vec_free (name);
15672
15673   S (mp);
15674   W (ret);
15675   return ret;
15676 }
15677
15678 static int
15679 api_ikev2_profile_set_auth (vat_main_t * vam)
15680 {
15681   unformat_input_t *i = vam->input;
15682   vl_api_ikev2_profile_set_auth_t *mp;
15683   u8 *name = 0;
15684   u8 *data = 0;
15685   u32 auth_method = 0;
15686   u8 is_hex = 0;
15687   int ret;
15688
15689   const char *valid_chars = "a-zA-Z0-9_";
15690
15691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15692     {
15693       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15694         vec_add1 (name, 0);
15695       else if (unformat (i, "auth_method %U",
15696                          unformat_ikev2_auth_method, &auth_method))
15697         ;
15698       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15699         is_hex = 1;
15700       else if (unformat (i, "auth_data %v", &data))
15701         ;
15702       else
15703         {
15704           errmsg ("parse error '%U'", format_unformat_error, i);
15705           return -99;
15706         }
15707     }
15708
15709   if (!vec_len (name))
15710     {
15711       errmsg ("profile name must be specified");
15712       return -99;
15713     }
15714
15715   if (vec_len (name) > 64)
15716     {
15717       errmsg ("profile name too long");
15718       return -99;
15719     }
15720
15721   if (!vec_len (data))
15722     {
15723       errmsg ("auth_data must be specified");
15724       return -99;
15725     }
15726
15727   if (!auth_method)
15728     {
15729       errmsg ("auth_method must be specified");
15730       return -99;
15731     }
15732
15733   M (IKEV2_PROFILE_SET_AUTH, mp);
15734
15735   mp->is_hex = is_hex;
15736   mp->auth_method = (u8) auth_method;
15737   mp->data_len = vec_len (data);
15738   clib_memcpy (mp->name, name, vec_len (name));
15739   clib_memcpy (mp->data, data, vec_len (data));
15740   vec_free (name);
15741   vec_free (data);
15742
15743   S (mp);
15744   W (ret);
15745   return ret;
15746 }
15747
15748 static int
15749 api_ikev2_profile_set_id (vat_main_t * vam)
15750 {
15751   unformat_input_t *i = vam->input;
15752   vl_api_ikev2_profile_set_id_t *mp;
15753   u8 *name = 0;
15754   u8 *data = 0;
15755   u8 is_local = 0;
15756   u32 id_type = 0;
15757   ip4_address_t ip4;
15758   int ret;
15759
15760   const char *valid_chars = "a-zA-Z0-9_";
15761
15762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15763     {
15764       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15765         vec_add1 (name, 0);
15766       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15767         ;
15768       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15769         {
15770           data = vec_new (u8, 4);
15771           clib_memcpy (data, ip4.as_u8, 4);
15772         }
15773       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15774         ;
15775       else if (unformat (i, "id_data %v", &data))
15776         ;
15777       else if (unformat (i, "local"))
15778         is_local = 1;
15779       else if (unformat (i, "remote"))
15780         is_local = 0;
15781       else
15782         {
15783           errmsg ("parse error '%U'", format_unformat_error, i);
15784           return -99;
15785         }
15786     }
15787
15788   if (!vec_len (name))
15789     {
15790       errmsg ("profile name must be specified");
15791       return -99;
15792     }
15793
15794   if (vec_len (name) > 64)
15795     {
15796       errmsg ("profile name too long");
15797       return -99;
15798     }
15799
15800   if (!vec_len (data))
15801     {
15802       errmsg ("id_data must be specified");
15803       return -99;
15804     }
15805
15806   if (!id_type)
15807     {
15808       errmsg ("id_type must be specified");
15809       return -99;
15810     }
15811
15812   M (IKEV2_PROFILE_SET_ID, mp);
15813
15814   mp->is_local = is_local;
15815   mp->id_type = (u8) id_type;
15816   mp->data_len = vec_len (data);
15817   clib_memcpy (mp->name, name, vec_len (name));
15818   clib_memcpy (mp->data, data, vec_len (data));
15819   vec_free (name);
15820   vec_free (data);
15821
15822   S (mp);
15823   W (ret);
15824   return ret;
15825 }
15826
15827 static int
15828 api_ikev2_profile_set_ts (vat_main_t * vam)
15829 {
15830   unformat_input_t *i = vam->input;
15831   vl_api_ikev2_profile_set_ts_t *mp;
15832   u8 *name = 0;
15833   u8 is_local = 0;
15834   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15835   ip4_address_t start_addr, end_addr;
15836
15837   const char *valid_chars = "a-zA-Z0-9_";
15838   int ret;
15839
15840   start_addr.as_u32 = 0;
15841   end_addr.as_u32 = (u32) ~ 0;
15842
15843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15844     {
15845       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15846         vec_add1 (name, 0);
15847       else if (unformat (i, "protocol %d", &proto))
15848         ;
15849       else if (unformat (i, "start_port %d", &start_port))
15850         ;
15851       else if (unformat (i, "end_port %d", &end_port))
15852         ;
15853       else
15854         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15855         ;
15856       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15857         ;
15858       else if (unformat (i, "local"))
15859         is_local = 1;
15860       else if (unformat (i, "remote"))
15861         is_local = 0;
15862       else
15863         {
15864           errmsg ("parse error '%U'", format_unformat_error, i);
15865           return -99;
15866         }
15867     }
15868
15869   if (!vec_len (name))
15870     {
15871       errmsg ("profile name must be specified");
15872       return -99;
15873     }
15874
15875   if (vec_len (name) > 64)
15876     {
15877       errmsg ("profile name too long");
15878       return -99;
15879     }
15880
15881   M (IKEV2_PROFILE_SET_TS, mp);
15882
15883   mp->is_local = is_local;
15884   mp->proto = (u8) proto;
15885   mp->start_port = (u16) start_port;
15886   mp->end_port = (u16) end_port;
15887   mp->start_addr = start_addr.as_u32;
15888   mp->end_addr = end_addr.as_u32;
15889   clib_memcpy (mp->name, name, vec_len (name));
15890   vec_free (name);
15891
15892   S (mp);
15893   W (ret);
15894   return ret;
15895 }
15896
15897 static int
15898 api_ikev2_set_local_key (vat_main_t * vam)
15899 {
15900   unformat_input_t *i = vam->input;
15901   vl_api_ikev2_set_local_key_t *mp;
15902   u8 *file = 0;
15903   int ret;
15904
15905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15906     {
15907       if (unformat (i, "file %v", &file))
15908         vec_add1 (file, 0);
15909       else
15910         {
15911           errmsg ("parse error '%U'", format_unformat_error, i);
15912           return -99;
15913         }
15914     }
15915
15916   if (!vec_len (file))
15917     {
15918       errmsg ("RSA key file must be specified");
15919       return -99;
15920     }
15921
15922   if (vec_len (file) > 256)
15923     {
15924       errmsg ("file name too long");
15925       return -99;
15926     }
15927
15928   M (IKEV2_SET_LOCAL_KEY, mp);
15929
15930   clib_memcpy (mp->key_file, file, vec_len (file));
15931   vec_free (file);
15932
15933   S (mp);
15934   W (ret);
15935   return ret;
15936 }
15937
15938 static int
15939 api_ikev2_set_responder (vat_main_t * vam)
15940 {
15941   unformat_input_t *i = vam->input;
15942   vl_api_ikev2_set_responder_t *mp;
15943   int ret;
15944   u8 *name = 0;
15945   u32 sw_if_index = ~0;
15946   ip4_address_t address;
15947
15948   const char *valid_chars = "a-zA-Z0-9_";
15949
15950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat
15953           (i, "%U interface %d address %U", unformat_token, valid_chars,
15954            &name, &sw_if_index, unformat_ip4_address, &address))
15955         vec_add1 (name, 0);
15956       else
15957         {
15958           errmsg ("parse error '%U'", format_unformat_error, i);
15959           return -99;
15960         }
15961     }
15962
15963   if (!vec_len (name))
15964     {
15965       errmsg ("profile name must be specified");
15966       return -99;
15967     }
15968
15969   if (vec_len (name) > 64)
15970     {
15971       errmsg ("profile name too long");
15972       return -99;
15973     }
15974
15975   M (IKEV2_SET_RESPONDER, mp);
15976
15977   clib_memcpy (mp->name, name, vec_len (name));
15978   vec_free (name);
15979
15980   mp->sw_if_index = sw_if_index;
15981   clib_memcpy (mp->address, &address, sizeof (address));
15982
15983   S (mp);
15984   W (ret);
15985   return ret;
15986 }
15987
15988 static int
15989 api_ikev2_set_ike_transforms (vat_main_t * vam)
15990 {
15991   unformat_input_t *i = vam->input;
15992   vl_api_ikev2_set_ike_transforms_t *mp;
15993   int ret;
15994   u8 *name = 0;
15995   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15996
15997   const char *valid_chars = "a-zA-Z0-9_";
15998
15999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16000     {
16001       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16002                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16003         vec_add1 (name, 0);
16004       else
16005         {
16006           errmsg ("parse error '%U'", format_unformat_error, i);
16007           return -99;
16008         }
16009     }
16010
16011   if (!vec_len (name))
16012     {
16013       errmsg ("profile name must be specified");
16014       return -99;
16015     }
16016
16017   if (vec_len (name) > 64)
16018     {
16019       errmsg ("profile name too long");
16020       return -99;
16021     }
16022
16023   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16024
16025   clib_memcpy (mp->name, name, vec_len (name));
16026   vec_free (name);
16027   mp->crypto_alg = crypto_alg;
16028   mp->crypto_key_size = crypto_key_size;
16029   mp->integ_alg = integ_alg;
16030   mp->dh_group = dh_group;
16031
16032   S (mp);
16033   W (ret);
16034   return ret;
16035 }
16036
16037
16038 static int
16039 api_ikev2_set_esp_transforms (vat_main_t * vam)
16040 {
16041   unformat_input_t *i = vam->input;
16042   vl_api_ikev2_set_esp_transforms_t *mp;
16043   int ret;
16044   u8 *name = 0;
16045   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16046
16047   const char *valid_chars = "a-zA-Z0-9_";
16048
16049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16050     {
16051       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16052                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16053         vec_add1 (name, 0);
16054       else
16055         {
16056           errmsg ("parse error '%U'", format_unformat_error, i);
16057           return -99;
16058         }
16059     }
16060
16061   if (!vec_len (name))
16062     {
16063       errmsg ("profile name must be specified");
16064       return -99;
16065     }
16066
16067   if (vec_len (name) > 64)
16068     {
16069       errmsg ("profile name too long");
16070       return -99;
16071     }
16072
16073   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16074
16075   clib_memcpy (mp->name, name, vec_len (name));
16076   vec_free (name);
16077   mp->crypto_alg = crypto_alg;
16078   mp->crypto_key_size = crypto_key_size;
16079   mp->integ_alg = integ_alg;
16080   mp->dh_group = dh_group;
16081
16082   S (mp);
16083   W (ret);
16084   return ret;
16085 }
16086
16087 static int
16088 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16089 {
16090   unformat_input_t *i = vam->input;
16091   vl_api_ikev2_set_sa_lifetime_t *mp;
16092   int ret;
16093   u8 *name = 0;
16094   u64 lifetime, lifetime_maxdata;
16095   u32 lifetime_jitter, handover;
16096
16097   const char *valid_chars = "a-zA-Z0-9_";
16098
16099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16100     {
16101       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16102                     &lifetime, &lifetime_jitter, &handover,
16103                     &lifetime_maxdata))
16104         vec_add1 (name, 0);
16105       else
16106         {
16107           errmsg ("parse error '%U'", format_unformat_error, i);
16108           return -99;
16109         }
16110     }
16111
16112   if (!vec_len (name))
16113     {
16114       errmsg ("profile name must be specified");
16115       return -99;
16116     }
16117
16118   if (vec_len (name) > 64)
16119     {
16120       errmsg ("profile name too long");
16121       return -99;
16122     }
16123
16124   M (IKEV2_SET_SA_LIFETIME, mp);
16125
16126   clib_memcpy (mp->name, name, vec_len (name));
16127   vec_free (name);
16128   mp->lifetime = lifetime;
16129   mp->lifetime_jitter = lifetime_jitter;
16130   mp->handover = handover;
16131   mp->lifetime_maxdata = lifetime_maxdata;
16132
16133   S (mp);
16134   W (ret);
16135   return ret;
16136 }
16137
16138 static int
16139 api_ikev2_initiate_sa_init (vat_main_t * vam)
16140 {
16141   unformat_input_t *i = vam->input;
16142   vl_api_ikev2_initiate_sa_init_t *mp;
16143   int ret;
16144   u8 *name = 0;
16145
16146   const char *valid_chars = "a-zA-Z0-9_";
16147
16148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16151         vec_add1 (name, 0);
16152       else
16153         {
16154           errmsg ("parse error '%U'", format_unformat_error, i);
16155           return -99;
16156         }
16157     }
16158
16159   if (!vec_len (name))
16160     {
16161       errmsg ("profile name must be specified");
16162       return -99;
16163     }
16164
16165   if (vec_len (name) > 64)
16166     {
16167       errmsg ("profile name too long");
16168       return -99;
16169     }
16170
16171   M (IKEV2_INITIATE_SA_INIT, mp);
16172
16173   clib_memcpy (mp->name, name, vec_len (name));
16174   vec_free (name);
16175
16176   S (mp);
16177   W (ret);
16178   return ret;
16179 }
16180
16181 static int
16182 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16183 {
16184   unformat_input_t *i = vam->input;
16185   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16186   int ret;
16187   u64 ispi;
16188
16189
16190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16191     {
16192       if (unformat (i, "%lx", &ispi))
16193         ;
16194       else
16195         {
16196           errmsg ("parse error '%U'", format_unformat_error, i);
16197           return -99;
16198         }
16199     }
16200
16201   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16202
16203   mp->ispi = ispi;
16204
16205   S (mp);
16206   W (ret);
16207   return ret;
16208 }
16209
16210 static int
16211 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16212 {
16213   unformat_input_t *i = vam->input;
16214   vl_api_ikev2_initiate_del_child_sa_t *mp;
16215   int ret;
16216   u32 ispi;
16217
16218
16219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16220     {
16221       if (unformat (i, "%x", &ispi))
16222         ;
16223       else
16224         {
16225           errmsg ("parse error '%U'", format_unformat_error, i);
16226           return -99;
16227         }
16228     }
16229
16230   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16231
16232   mp->ispi = ispi;
16233
16234   S (mp);
16235   W (ret);
16236   return ret;
16237 }
16238
16239 static int
16240 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16241 {
16242   unformat_input_t *i = vam->input;
16243   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16244   int ret;
16245   u32 ispi;
16246
16247
16248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16249     {
16250       if (unformat (i, "%x", &ispi))
16251         ;
16252       else
16253         {
16254           errmsg ("parse error '%U'", format_unformat_error, i);
16255           return -99;
16256         }
16257     }
16258
16259   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16260
16261   mp->ispi = ispi;
16262
16263   S (mp);
16264   W (ret);
16265   return ret;
16266 }
16267
16268 static int
16269 api_get_first_msg_id (vat_main_t * vam)
16270 {
16271   vl_api_get_first_msg_id_t *mp;
16272   unformat_input_t *i = vam->input;
16273   u8 *name;
16274   u8 name_set = 0;
16275   int ret;
16276
16277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16278     {
16279       if (unformat (i, "client %s", &name))
16280         name_set = 1;
16281       else
16282         break;
16283     }
16284
16285   if (name_set == 0)
16286     {
16287       errmsg ("missing client name");
16288       return -99;
16289     }
16290   vec_add1 (name, 0);
16291
16292   if (vec_len (name) > 63)
16293     {
16294       errmsg ("client name too long");
16295       return -99;
16296     }
16297
16298   M (GET_FIRST_MSG_ID, mp);
16299   clib_memcpy (mp->name, name, vec_len (name));
16300   S (mp);
16301   W (ret);
16302   return ret;
16303 }
16304
16305 static int
16306 api_cop_interface_enable_disable (vat_main_t * vam)
16307 {
16308   unformat_input_t *line_input = vam->input;
16309   vl_api_cop_interface_enable_disable_t *mp;
16310   u32 sw_if_index = ~0;
16311   u8 enable_disable = 1;
16312   int ret;
16313
16314   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (line_input, "disable"))
16317         enable_disable = 0;
16318       if (unformat (line_input, "enable"))
16319         enable_disable = 1;
16320       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16321                          vam, &sw_if_index))
16322         ;
16323       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16324         ;
16325       else
16326         break;
16327     }
16328
16329   if (sw_if_index == ~0)
16330     {
16331       errmsg ("missing interface name or sw_if_index");
16332       return -99;
16333     }
16334
16335   /* Construct the API message */
16336   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16337   mp->sw_if_index = ntohl (sw_if_index);
16338   mp->enable_disable = enable_disable;
16339
16340   /* send it... */
16341   S (mp);
16342   /* Wait for the reply */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_cop_whitelist_enable_disable (vat_main_t * vam)
16349 {
16350   unformat_input_t *line_input = vam->input;
16351   vl_api_cop_whitelist_enable_disable_t *mp;
16352   u32 sw_if_index = ~0;
16353   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16354   u32 fib_id = 0;
16355   int ret;
16356
16357   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16358     {
16359       if (unformat (line_input, "ip4"))
16360         ip4 = 1;
16361       else if (unformat (line_input, "ip6"))
16362         ip6 = 1;
16363       else if (unformat (line_input, "default"))
16364         default_cop = 1;
16365       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16366                          vam, &sw_if_index))
16367         ;
16368       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16369         ;
16370       else if (unformat (line_input, "fib-id %d", &fib_id))
16371         ;
16372       else
16373         break;
16374     }
16375
16376   if (sw_if_index == ~0)
16377     {
16378       errmsg ("missing interface name or sw_if_index");
16379       return -99;
16380     }
16381
16382   /* Construct the API message */
16383   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16384   mp->sw_if_index = ntohl (sw_if_index);
16385   mp->fib_id = ntohl (fib_id);
16386   mp->ip4 = ip4;
16387   mp->ip6 = ip6;
16388   mp->default_cop = default_cop;
16389
16390   /* send it... */
16391   S (mp);
16392   /* Wait for the reply */
16393   W (ret);
16394   return ret;
16395 }
16396
16397 static int
16398 api_get_node_graph (vat_main_t * vam)
16399 {
16400   vl_api_get_node_graph_t *mp;
16401   int ret;
16402
16403   M (GET_NODE_GRAPH, mp);
16404
16405   /* send it... */
16406   S (mp);
16407   /* Wait for the reply */
16408   W (ret);
16409   return ret;
16410 }
16411
16412 /* *INDENT-OFF* */
16413 /** Used for parsing LISP eids */
16414 typedef CLIB_PACKED(struct{
16415   u8 addr[16];   /**< eid address */
16416   u32 len;       /**< prefix length if IP */
16417   u8 type;      /**< type of eid */
16418 }) lisp_eid_vat_t;
16419 /* *INDENT-ON* */
16420
16421 static uword
16422 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16423 {
16424   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16425
16426   memset (a, 0, sizeof (a[0]));
16427
16428   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16429     {
16430       a->type = 0;              /* ipv4 type */
16431     }
16432   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16433     {
16434       a->type = 1;              /* ipv6 type */
16435     }
16436   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16437     {
16438       a->type = 2;              /* mac type */
16439     }
16440   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16441     {
16442       a->type = 3;              /* NSH type */
16443       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16444       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16445     }
16446   else
16447     {
16448       return 0;
16449     }
16450
16451   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16452     {
16453       return 0;
16454     }
16455
16456   return 1;
16457 }
16458
16459 static int
16460 lisp_eid_size_vat (u8 type)
16461 {
16462   switch (type)
16463     {
16464     case 0:
16465       return 4;
16466     case 1:
16467       return 16;
16468     case 2:
16469       return 6;
16470     case 3:
16471       return 5;
16472     }
16473   return 0;
16474 }
16475
16476 static void
16477 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16478 {
16479   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16480 }
16481
16482 static int
16483 api_one_add_del_locator_set (vat_main_t * vam)
16484 {
16485   unformat_input_t *input = vam->input;
16486   vl_api_one_add_del_locator_set_t *mp;
16487   u8 is_add = 1;
16488   u8 *locator_set_name = NULL;
16489   u8 locator_set_name_set = 0;
16490   vl_api_local_locator_t locator, *locators = 0;
16491   u32 sw_if_index, priority, weight;
16492   u32 data_len = 0;
16493
16494   int ret;
16495   /* Parse args required to build the message */
16496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16497     {
16498       if (unformat (input, "del"))
16499         {
16500           is_add = 0;
16501         }
16502       else if (unformat (input, "locator-set %s", &locator_set_name))
16503         {
16504           locator_set_name_set = 1;
16505         }
16506       else if (unformat (input, "sw_if_index %u p %u w %u",
16507                          &sw_if_index, &priority, &weight))
16508         {
16509           locator.sw_if_index = htonl (sw_if_index);
16510           locator.priority = priority;
16511           locator.weight = weight;
16512           vec_add1 (locators, locator);
16513         }
16514       else
16515         if (unformat
16516             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16517              &sw_if_index, &priority, &weight))
16518         {
16519           locator.sw_if_index = htonl (sw_if_index);
16520           locator.priority = priority;
16521           locator.weight = weight;
16522           vec_add1 (locators, locator);
16523         }
16524       else
16525         break;
16526     }
16527
16528   if (locator_set_name_set == 0)
16529     {
16530       errmsg ("missing locator-set name");
16531       vec_free (locators);
16532       return -99;
16533     }
16534
16535   if (vec_len (locator_set_name) > 64)
16536     {
16537       errmsg ("locator-set name too long");
16538       vec_free (locator_set_name);
16539       vec_free (locators);
16540       return -99;
16541     }
16542   vec_add1 (locator_set_name, 0);
16543
16544   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16545
16546   /* Construct the API message */
16547   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16548
16549   mp->is_add = is_add;
16550   clib_memcpy (mp->locator_set_name, locator_set_name,
16551                vec_len (locator_set_name));
16552   vec_free (locator_set_name);
16553
16554   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16555   if (locators)
16556     clib_memcpy (mp->locators, locators, data_len);
16557   vec_free (locators);
16558
16559   /* send it... */
16560   S (mp);
16561
16562   /* Wait for a reply... */
16563   W (ret);
16564   return ret;
16565 }
16566
16567 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16568
16569 static int
16570 api_one_add_del_locator (vat_main_t * vam)
16571 {
16572   unformat_input_t *input = vam->input;
16573   vl_api_one_add_del_locator_t *mp;
16574   u32 tmp_if_index = ~0;
16575   u32 sw_if_index = ~0;
16576   u8 sw_if_index_set = 0;
16577   u8 sw_if_index_if_name_set = 0;
16578   u32 priority = ~0;
16579   u8 priority_set = 0;
16580   u32 weight = ~0;
16581   u8 weight_set = 0;
16582   u8 is_add = 1;
16583   u8 *locator_set_name = NULL;
16584   u8 locator_set_name_set = 0;
16585   int ret;
16586
16587   /* Parse args required to build the message */
16588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16589     {
16590       if (unformat (input, "del"))
16591         {
16592           is_add = 0;
16593         }
16594       else if (unformat (input, "locator-set %s", &locator_set_name))
16595         {
16596           locator_set_name_set = 1;
16597         }
16598       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16599                          &tmp_if_index))
16600         {
16601           sw_if_index_if_name_set = 1;
16602           sw_if_index = tmp_if_index;
16603         }
16604       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16605         {
16606           sw_if_index_set = 1;
16607           sw_if_index = tmp_if_index;
16608         }
16609       else if (unformat (input, "p %d", &priority))
16610         {
16611           priority_set = 1;
16612         }
16613       else if (unformat (input, "w %d", &weight))
16614         {
16615           weight_set = 1;
16616         }
16617       else
16618         break;
16619     }
16620
16621   if (locator_set_name_set == 0)
16622     {
16623       errmsg ("missing locator-set name");
16624       return -99;
16625     }
16626
16627   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16628     {
16629       errmsg ("missing sw_if_index");
16630       vec_free (locator_set_name);
16631       return -99;
16632     }
16633
16634   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16635     {
16636       errmsg ("cannot use both params interface name and sw_if_index");
16637       vec_free (locator_set_name);
16638       return -99;
16639     }
16640
16641   if (priority_set == 0)
16642     {
16643       errmsg ("missing locator-set priority");
16644       vec_free (locator_set_name);
16645       return -99;
16646     }
16647
16648   if (weight_set == 0)
16649     {
16650       errmsg ("missing locator-set weight");
16651       vec_free (locator_set_name);
16652       return -99;
16653     }
16654
16655   if (vec_len (locator_set_name) > 64)
16656     {
16657       errmsg ("locator-set name too long");
16658       vec_free (locator_set_name);
16659       return -99;
16660     }
16661   vec_add1 (locator_set_name, 0);
16662
16663   /* Construct the API message */
16664   M (ONE_ADD_DEL_LOCATOR, mp);
16665
16666   mp->is_add = is_add;
16667   mp->sw_if_index = ntohl (sw_if_index);
16668   mp->priority = priority;
16669   mp->weight = weight;
16670   clib_memcpy (mp->locator_set_name, locator_set_name,
16671                vec_len (locator_set_name));
16672   vec_free (locator_set_name);
16673
16674   /* send it... */
16675   S (mp);
16676
16677   /* Wait for a reply... */
16678   W (ret);
16679   return ret;
16680 }
16681
16682 #define api_lisp_add_del_locator api_one_add_del_locator
16683
16684 uword
16685 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16686 {
16687   u32 *key_id = va_arg (*args, u32 *);
16688   u8 *s = 0;
16689
16690   if (unformat (input, "%s", &s))
16691     {
16692       if (!strcmp ((char *) s, "sha1"))
16693         key_id[0] = HMAC_SHA_1_96;
16694       else if (!strcmp ((char *) s, "sha256"))
16695         key_id[0] = HMAC_SHA_256_128;
16696       else
16697         {
16698           clib_warning ("invalid key_id: '%s'", s);
16699           key_id[0] = HMAC_NO_KEY;
16700         }
16701     }
16702   else
16703     return 0;
16704
16705   vec_free (s);
16706   return 1;
16707 }
16708
16709 static int
16710 api_one_add_del_local_eid (vat_main_t * vam)
16711 {
16712   unformat_input_t *input = vam->input;
16713   vl_api_one_add_del_local_eid_t *mp;
16714   u8 is_add = 1;
16715   u8 eid_set = 0;
16716   lisp_eid_vat_t _eid, *eid = &_eid;
16717   u8 *locator_set_name = 0;
16718   u8 locator_set_name_set = 0;
16719   u32 vni = 0;
16720   u16 key_id = 0;
16721   u8 *key = 0;
16722   int ret;
16723
16724   /* Parse args required to build the message */
16725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16726     {
16727       if (unformat (input, "del"))
16728         {
16729           is_add = 0;
16730         }
16731       else if (unformat (input, "vni %d", &vni))
16732         {
16733           ;
16734         }
16735       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16736         {
16737           eid_set = 1;
16738         }
16739       else if (unformat (input, "locator-set %s", &locator_set_name))
16740         {
16741           locator_set_name_set = 1;
16742         }
16743       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16744         ;
16745       else if (unformat (input, "secret-key %_%v%_", &key))
16746         ;
16747       else
16748         break;
16749     }
16750
16751   if (locator_set_name_set == 0)
16752     {
16753       errmsg ("missing locator-set name");
16754       return -99;
16755     }
16756
16757   if (0 == eid_set)
16758     {
16759       errmsg ("EID address not set!");
16760       vec_free (locator_set_name);
16761       return -99;
16762     }
16763
16764   if (key && (0 == key_id))
16765     {
16766       errmsg ("invalid key_id!");
16767       return -99;
16768     }
16769
16770   if (vec_len (key) > 64)
16771     {
16772       errmsg ("key too long");
16773       vec_free (key);
16774       return -99;
16775     }
16776
16777   if (vec_len (locator_set_name) > 64)
16778     {
16779       errmsg ("locator-set name too long");
16780       vec_free (locator_set_name);
16781       return -99;
16782     }
16783   vec_add1 (locator_set_name, 0);
16784
16785   /* Construct the API message */
16786   M (ONE_ADD_DEL_LOCAL_EID, mp);
16787
16788   mp->is_add = is_add;
16789   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16790   mp->eid_type = eid->type;
16791   mp->prefix_len = eid->len;
16792   mp->vni = clib_host_to_net_u32 (vni);
16793   mp->key_id = clib_host_to_net_u16 (key_id);
16794   clib_memcpy (mp->locator_set_name, locator_set_name,
16795                vec_len (locator_set_name));
16796   clib_memcpy (mp->key, key, vec_len (key));
16797
16798   vec_free (locator_set_name);
16799   vec_free (key);
16800
16801   /* send it... */
16802   S (mp);
16803
16804   /* Wait for a reply... */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16810
16811 static int
16812 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16813 {
16814   u32 dp_table = 0, vni = 0;;
16815   unformat_input_t *input = vam->input;
16816   vl_api_gpe_add_del_fwd_entry_t *mp;
16817   u8 is_add = 1;
16818   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16819   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16820   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16821   u32 action = ~0, w;
16822   ip4_address_t rmt_rloc4, lcl_rloc4;
16823   ip6_address_t rmt_rloc6, lcl_rloc6;
16824   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16825   int ret;
16826
16827   memset (&rloc, 0, sizeof (rloc));
16828
16829   /* Parse args required to build the message */
16830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16831     {
16832       if (unformat (input, "del"))
16833         is_add = 0;
16834       else if (unformat (input, "add"))
16835         is_add = 1;
16836       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16837         {
16838           rmt_eid_set = 1;
16839         }
16840       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16841         {
16842           lcl_eid_set = 1;
16843         }
16844       else if (unformat (input, "vrf %d", &dp_table))
16845         ;
16846       else if (unformat (input, "bd %d", &dp_table))
16847         ;
16848       else if (unformat (input, "vni %d", &vni))
16849         ;
16850       else if (unformat (input, "w %d", &w))
16851         {
16852           if (!curr_rloc)
16853             {
16854               errmsg ("No RLOC configured for setting priority/weight!");
16855               return -99;
16856             }
16857           curr_rloc->weight = w;
16858         }
16859       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16860                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16861         {
16862           rloc.is_ip4 = 1;
16863
16864           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16865           rloc.weight = 0;
16866           vec_add1 (lcl_locs, rloc);
16867
16868           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16869           vec_add1 (rmt_locs, rloc);
16870           /* weight saved in rmt loc */
16871           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16872         }
16873       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16874                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16875         {
16876           rloc.is_ip4 = 0;
16877           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16878           rloc.weight = 0;
16879           vec_add1 (lcl_locs, rloc);
16880
16881           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16882           vec_add1 (rmt_locs, rloc);
16883           /* weight saved in rmt loc */
16884           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16885         }
16886       else if (unformat (input, "action %d", &action))
16887         {
16888           ;
16889         }
16890       else
16891         {
16892           clib_warning ("parse error '%U'", format_unformat_error, input);
16893           return -99;
16894         }
16895     }
16896
16897   if (!rmt_eid_set)
16898     {
16899       errmsg ("remote eid addresses not set");
16900       return -99;
16901     }
16902
16903   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16904     {
16905       errmsg ("eid types don't match");
16906       return -99;
16907     }
16908
16909   if (0 == rmt_locs && (u32) ~ 0 == action)
16910     {
16911       errmsg ("action not set for negative mapping");
16912       return -99;
16913     }
16914
16915   /* Construct the API message */
16916   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16917       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16918
16919   mp->is_add = is_add;
16920   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16921   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16922   mp->eid_type = rmt_eid->type;
16923   mp->dp_table = clib_host_to_net_u32 (dp_table);
16924   mp->vni = clib_host_to_net_u32 (vni);
16925   mp->rmt_len = rmt_eid->len;
16926   mp->lcl_len = lcl_eid->len;
16927   mp->action = action;
16928
16929   if (0 != rmt_locs && 0 != lcl_locs)
16930     {
16931       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16932       clib_memcpy (mp->locs, lcl_locs,
16933                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16934
16935       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16936       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16937                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16938     }
16939   vec_free (lcl_locs);
16940   vec_free (rmt_locs);
16941
16942   /* send it... */
16943   S (mp);
16944
16945   /* Wait for a reply... */
16946   W (ret);
16947   return ret;
16948 }
16949
16950 static int
16951 api_one_add_del_map_server (vat_main_t * vam)
16952 {
16953   unformat_input_t *input = vam->input;
16954   vl_api_one_add_del_map_server_t *mp;
16955   u8 is_add = 1;
16956   u8 ipv4_set = 0;
16957   u8 ipv6_set = 0;
16958   ip4_address_t ipv4;
16959   ip6_address_t ipv6;
16960   int ret;
16961
16962   /* Parse args required to build the message */
16963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16964     {
16965       if (unformat (input, "del"))
16966         {
16967           is_add = 0;
16968         }
16969       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16970         {
16971           ipv4_set = 1;
16972         }
16973       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16974         {
16975           ipv6_set = 1;
16976         }
16977       else
16978         break;
16979     }
16980
16981   if (ipv4_set && ipv6_set)
16982     {
16983       errmsg ("both eid v4 and v6 addresses set");
16984       return -99;
16985     }
16986
16987   if (!ipv4_set && !ipv6_set)
16988     {
16989       errmsg ("eid addresses not set");
16990       return -99;
16991     }
16992
16993   /* Construct the API message */
16994   M (ONE_ADD_DEL_MAP_SERVER, mp);
16995
16996   mp->is_add = is_add;
16997   if (ipv6_set)
16998     {
16999       mp->is_ipv6 = 1;
17000       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17001     }
17002   else
17003     {
17004       mp->is_ipv6 = 0;
17005       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17006     }
17007
17008   /* send it... */
17009   S (mp);
17010
17011   /* Wait for a reply... */
17012   W (ret);
17013   return ret;
17014 }
17015
17016 #define api_lisp_add_del_map_server api_one_add_del_map_server
17017
17018 static int
17019 api_one_add_del_map_resolver (vat_main_t * vam)
17020 {
17021   unformat_input_t *input = vam->input;
17022   vl_api_one_add_del_map_resolver_t *mp;
17023   u8 is_add = 1;
17024   u8 ipv4_set = 0;
17025   u8 ipv6_set = 0;
17026   ip4_address_t ipv4;
17027   ip6_address_t ipv6;
17028   int ret;
17029
17030   /* Parse args required to build the message */
17031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17032     {
17033       if (unformat (input, "del"))
17034         {
17035           is_add = 0;
17036         }
17037       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17038         {
17039           ipv4_set = 1;
17040         }
17041       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17042         {
17043           ipv6_set = 1;
17044         }
17045       else
17046         break;
17047     }
17048
17049   if (ipv4_set && ipv6_set)
17050     {
17051       errmsg ("both eid v4 and v6 addresses set");
17052       return -99;
17053     }
17054
17055   if (!ipv4_set && !ipv6_set)
17056     {
17057       errmsg ("eid addresses not set");
17058       return -99;
17059     }
17060
17061   /* Construct the API message */
17062   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17063
17064   mp->is_add = is_add;
17065   if (ipv6_set)
17066     {
17067       mp->is_ipv6 = 1;
17068       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17069     }
17070   else
17071     {
17072       mp->is_ipv6 = 0;
17073       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17074     }
17075
17076   /* send it... */
17077   S (mp);
17078
17079   /* Wait for a reply... */
17080   W (ret);
17081   return ret;
17082 }
17083
17084 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17085
17086 static int
17087 api_lisp_gpe_enable_disable (vat_main_t * vam)
17088 {
17089   unformat_input_t *input = vam->input;
17090   vl_api_gpe_enable_disable_t *mp;
17091   u8 is_set = 0;
17092   u8 is_en = 1;
17093   int ret;
17094
17095   /* Parse args required to build the message */
17096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17097     {
17098       if (unformat (input, "enable"))
17099         {
17100           is_set = 1;
17101           is_en = 1;
17102         }
17103       else if (unformat (input, "disable"))
17104         {
17105           is_set = 1;
17106           is_en = 0;
17107         }
17108       else
17109         break;
17110     }
17111
17112   if (is_set == 0)
17113     {
17114       errmsg ("Value not set");
17115       return -99;
17116     }
17117
17118   /* Construct the API message */
17119   M (GPE_ENABLE_DISABLE, mp);
17120
17121   mp->is_en = is_en;
17122
17123   /* send it... */
17124   S (mp);
17125
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 static int
17132 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17133 {
17134   unformat_input_t *input = vam->input;
17135   vl_api_one_rloc_probe_enable_disable_t *mp;
17136   u8 is_set = 0;
17137   u8 is_en = 0;
17138   int ret;
17139
17140   /* Parse args required to build the message */
17141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17142     {
17143       if (unformat (input, "enable"))
17144         {
17145           is_set = 1;
17146           is_en = 1;
17147         }
17148       else if (unformat (input, "disable"))
17149         is_set = 1;
17150       else
17151         break;
17152     }
17153
17154   if (!is_set)
17155     {
17156       errmsg ("Value not set");
17157       return -99;
17158     }
17159
17160   /* Construct the API message */
17161   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17162
17163   mp->is_enabled = is_en;
17164
17165   /* send it... */
17166   S (mp);
17167
17168   /* Wait for a reply... */
17169   W (ret);
17170   return ret;
17171 }
17172
17173 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17174
17175 static int
17176 api_one_map_register_enable_disable (vat_main_t * vam)
17177 {
17178   unformat_input_t *input = vam->input;
17179   vl_api_one_map_register_enable_disable_t *mp;
17180   u8 is_set = 0;
17181   u8 is_en = 0;
17182   int ret;
17183
17184   /* Parse args required to build the message */
17185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17186     {
17187       if (unformat (input, "enable"))
17188         {
17189           is_set = 1;
17190           is_en = 1;
17191         }
17192       else if (unformat (input, "disable"))
17193         is_set = 1;
17194       else
17195         break;
17196     }
17197
17198   if (!is_set)
17199     {
17200       errmsg ("Value not set");
17201       return -99;
17202     }
17203
17204   /* Construct the API message */
17205   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17206
17207   mp->is_enabled = is_en;
17208
17209   /* send it... */
17210   S (mp);
17211
17212   /* Wait for a reply... */
17213   W (ret);
17214   return ret;
17215 }
17216
17217 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17218
17219 static int
17220 api_one_enable_disable (vat_main_t * vam)
17221 {
17222   unformat_input_t *input = vam->input;
17223   vl_api_one_enable_disable_t *mp;
17224   u8 is_set = 0;
17225   u8 is_en = 0;
17226   int ret;
17227
17228   /* Parse args required to build the message */
17229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17230     {
17231       if (unformat (input, "enable"))
17232         {
17233           is_set = 1;
17234           is_en = 1;
17235         }
17236       else if (unformat (input, "disable"))
17237         {
17238           is_set = 1;
17239         }
17240       else
17241         break;
17242     }
17243
17244   if (!is_set)
17245     {
17246       errmsg ("Value not set");
17247       return -99;
17248     }
17249
17250   /* Construct the API message */
17251   M (ONE_ENABLE_DISABLE, mp);
17252
17253   mp->is_en = is_en;
17254
17255   /* send it... */
17256   S (mp);
17257
17258   /* Wait for a reply... */
17259   W (ret);
17260   return ret;
17261 }
17262
17263 #define api_lisp_enable_disable api_one_enable_disable
17264
17265 static int
17266 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17267 {
17268   unformat_input_t *input = vam->input;
17269   vl_api_one_enable_disable_xtr_mode_t *mp;
17270   u8 is_set = 0;
17271   u8 is_en = 0;
17272   int ret;
17273
17274   /* Parse args required to build the message */
17275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17276     {
17277       if (unformat (input, "enable"))
17278         {
17279           is_set = 1;
17280           is_en = 1;
17281         }
17282       else if (unformat (input, "disable"))
17283         {
17284           is_set = 1;
17285         }
17286       else
17287         break;
17288     }
17289
17290   if (!is_set)
17291     {
17292       errmsg ("Value not set");
17293       return -99;
17294     }
17295
17296   /* Construct the API message */
17297   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17298
17299   mp->is_en = is_en;
17300
17301   /* send it... */
17302   S (mp);
17303
17304   /* Wait for a reply... */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static int
17310 api_one_show_xtr_mode (vat_main_t * vam)
17311 {
17312   vl_api_one_show_xtr_mode_t *mp;
17313   int ret;
17314
17315   /* Construct the API message */
17316   M (ONE_SHOW_XTR_MODE, mp);
17317
17318   /* send it... */
17319   S (mp);
17320
17321   /* Wait for a reply... */
17322   W (ret);
17323   return ret;
17324 }
17325
17326 static int
17327 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17328 {
17329   unformat_input_t *input = vam->input;
17330   vl_api_one_enable_disable_pitr_mode_t *mp;
17331   u8 is_set = 0;
17332   u8 is_en = 0;
17333   int ret;
17334
17335   /* Parse args required to build the message */
17336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17337     {
17338       if (unformat (input, "enable"))
17339         {
17340           is_set = 1;
17341           is_en = 1;
17342         }
17343       else if (unformat (input, "disable"))
17344         {
17345           is_set = 1;
17346         }
17347       else
17348         break;
17349     }
17350
17351   if (!is_set)
17352     {
17353       errmsg ("Value not set");
17354       return -99;
17355     }
17356
17357   /* Construct the API message */
17358   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17359
17360   mp->is_en = is_en;
17361
17362   /* send it... */
17363   S (mp);
17364
17365   /* Wait for a reply... */
17366   W (ret);
17367   return ret;
17368 }
17369
17370 static int
17371 api_one_show_pitr_mode (vat_main_t * vam)
17372 {
17373   vl_api_one_show_pitr_mode_t *mp;
17374   int ret;
17375
17376   /* Construct the API message */
17377   M (ONE_SHOW_PITR_MODE, mp);
17378
17379   /* send it... */
17380   S (mp);
17381
17382   /* Wait for a reply... */
17383   W (ret);
17384   return ret;
17385 }
17386
17387 static int
17388 api_one_enable_disable_petr_mode (vat_main_t * vam)
17389 {
17390   unformat_input_t *input = vam->input;
17391   vl_api_one_enable_disable_petr_mode_t *mp;
17392   u8 is_set = 0;
17393   u8 is_en = 0;
17394   int ret;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "enable"))
17400         {
17401           is_set = 1;
17402           is_en = 1;
17403         }
17404       else if (unformat (input, "disable"))
17405         {
17406           is_set = 1;
17407         }
17408       else
17409         break;
17410     }
17411
17412   if (!is_set)
17413     {
17414       errmsg ("Value not set");
17415       return -99;
17416     }
17417
17418   /* Construct the API message */
17419   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17420
17421   mp->is_en = is_en;
17422
17423   /* send it... */
17424   S (mp);
17425
17426   /* Wait for a reply... */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_one_show_petr_mode (vat_main_t * vam)
17433 {
17434   vl_api_one_show_petr_mode_t *mp;
17435   int ret;
17436
17437   /* Construct the API message */
17438   M (ONE_SHOW_PETR_MODE, mp);
17439
17440   /* send it... */
17441   S (mp);
17442
17443   /* Wait for a reply... */
17444   W (ret);
17445   return ret;
17446 }
17447
17448 static int
17449 api_show_one_map_register_state (vat_main_t * vam)
17450 {
17451   vl_api_show_one_map_register_state_t *mp;
17452   int ret;
17453
17454   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17455
17456   /* send */
17457   S (mp);
17458
17459   /* wait for reply */
17460   W (ret);
17461   return ret;
17462 }
17463
17464 #define api_show_lisp_map_register_state api_show_one_map_register_state
17465
17466 static int
17467 api_show_one_rloc_probe_state (vat_main_t * vam)
17468 {
17469   vl_api_show_one_rloc_probe_state_t *mp;
17470   int ret;
17471
17472   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17473
17474   /* send */
17475   S (mp);
17476
17477   /* wait for reply */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17483
17484 static int
17485 api_one_add_del_ndp_entry (vat_main_t * vam)
17486 {
17487   vl_api_one_add_del_ndp_entry_t *mp;
17488   unformat_input_t *input = vam->input;
17489   u8 is_add = 1;
17490   u8 mac_set = 0;
17491   u8 bd_set = 0;
17492   u8 ip_set = 0;
17493   u8 mac[6] = { 0, };
17494   u8 ip6[16] = { 0, };
17495   u32 bd = ~0;
17496   int ret;
17497
17498   /* Parse args required to build the message */
17499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17500     {
17501       if (unformat (input, "del"))
17502         is_add = 0;
17503       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17504         mac_set = 1;
17505       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17506         ip_set = 1;
17507       else if (unformat (input, "bd %d", &bd))
17508         bd_set = 1;
17509       else
17510         {
17511           errmsg ("parse error '%U'", format_unformat_error, input);
17512           return -99;
17513         }
17514     }
17515
17516   if (!bd_set || !ip_set || (!mac_set && is_add))
17517     {
17518       errmsg ("Missing BD, IP or MAC!");
17519       return -99;
17520     }
17521
17522   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17523   mp->is_add = is_add;
17524   clib_memcpy (mp->mac, mac, 6);
17525   mp->bd = clib_host_to_net_u32 (bd);
17526   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17527
17528   /* send */
17529   S (mp);
17530
17531   /* wait for reply */
17532   W (ret);
17533   return ret;
17534 }
17535
17536 static int
17537 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17538 {
17539   vl_api_one_add_del_l2_arp_entry_t *mp;
17540   unformat_input_t *input = vam->input;
17541   u8 is_add = 1;
17542   u8 mac_set = 0;
17543   u8 bd_set = 0;
17544   u8 ip_set = 0;
17545   u8 mac[6] = { 0, };
17546   u32 ip4 = 0, bd = ~0;
17547   int ret;
17548
17549   /* Parse args required to build the message */
17550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17551     {
17552       if (unformat (input, "del"))
17553         is_add = 0;
17554       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17555         mac_set = 1;
17556       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17557         ip_set = 1;
17558       else if (unformat (input, "bd %d", &bd))
17559         bd_set = 1;
17560       else
17561         {
17562           errmsg ("parse error '%U'", format_unformat_error, input);
17563           return -99;
17564         }
17565     }
17566
17567   if (!bd_set || !ip_set || (!mac_set && is_add))
17568     {
17569       errmsg ("Missing BD, IP or MAC!");
17570       return -99;
17571     }
17572
17573   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17574   mp->is_add = is_add;
17575   clib_memcpy (mp->mac, mac, 6);
17576   mp->bd = clib_host_to_net_u32 (bd);
17577   mp->ip4 = ip4;
17578
17579   /* send */
17580   S (mp);
17581
17582   /* wait for reply */
17583   W (ret);
17584   return ret;
17585 }
17586
17587 static int
17588 api_one_ndp_bd_get (vat_main_t * vam)
17589 {
17590   vl_api_one_ndp_bd_get_t *mp;
17591   int ret;
17592
17593   M (ONE_NDP_BD_GET, mp);
17594
17595   /* send */
17596   S (mp);
17597
17598   /* wait for reply */
17599   W (ret);
17600   return ret;
17601 }
17602
17603 static int
17604 api_one_ndp_entries_get (vat_main_t * vam)
17605 {
17606   vl_api_one_ndp_entries_get_t *mp;
17607   unformat_input_t *input = vam->input;
17608   u8 bd_set = 0;
17609   u32 bd = ~0;
17610   int ret;
17611
17612   /* Parse args required to build the message */
17613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17614     {
17615       if (unformat (input, "bd %d", &bd))
17616         bd_set = 1;
17617       else
17618         {
17619           errmsg ("parse error '%U'", format_unformat_error, input);
17620           return -99;
17621         }
17622     }
17623
17624   if (!bd_set)
17625     {
17626       errmsg ("Expected bridge domain!");
17627       return -99;
17628     }
17629
17630   M (ONE_NDP_ENTRIES_GET, mp);
17631   mp->bd = clib_host_to_net_u32 (bd);
17632
17633   /* send */
17634   S (mp);
17635
17636   /* wait for reply */
17637   W (ret);
17638   return ret;
17639 }
17640
17641 static int
17642 api_one_l2_arp_bd_get (vat_main_t * vam)
17643 {
17644   vl_api_one_l2_arp_bd_get_t *mp;
17645   int ret;
17646
17647   M (ONE_L2_ARP_BD_GET, mp);
17648
17649   /* send */
17650   S (mp);
17651
17652   /* wait for reply */
17653   W (ret);
17654   return ret;
17655 }
17656
17657 static int
17658 api_one_l2_arp_entries_get (vat_main_t * vam)
17659 {
17660   vl_api_one_l2_arp_entries_get_t *mp;
17661   unformat_input_t *input = vam->input;
17662   u8 bd_set = 0;
17663   u32 bd = ~0;
17664   int ret;
17665
17666   /* Parse args required to build the message */
17667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17668     {
17669       if (unformat (input, "bd %d", &bd))
17670         bd_set = 1;
17671       else
17672         {
17673           errmsg ("parse error '%U'", format_unformat_error, input);
17674           return -99;
17675         }
17676     }
17677
17678   if (!bd_set)
17679     {
17680       errmsg ("Expected bridge domain!");
17681       return -99;
17682     }
17683
17684   M (ONE_L2_ARP_ENTRIES_GET, mp);
17685   mp->bd = clib_host_to_net_u32 (bd);
17686
17687   /* send */
17688   S (mp);
17689
17690   /* wait for reply */
17691   W (ret);
17692   return ret;
17693 }
17694
17695 static int
17696 api_one_stats_enable_disable (vat_main_t * vam)
17697 {
17698   vl_api_one_stats_enable_disable_t *mp;
17699   unformat_input_t *input = vam->input;
17700   u8 is_set = 0;
17701   u8 is_en = 0;
17702   int ret;
17703
17704   /* Parse args required to build the message */
17705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17706     {
17707       if (unformat (input, "enable"))
17708         {
17709           is_set = 1;
17710           is_en = 1;
17711         }
17712       else if (unformat (input, "disable"))
17713         {
17714           is_set = 1;
17715         }
17716       else
17717         break;
17718     }
17719
17720   if (!is_set)
17721     {
17722       errmsg ("Value not set");
17723       return -99;
17724     }
17725
17726   M (ONE_STATS_ENABLE_DISABLE, mp);
17727   mp->is_en = is_en;
17728
17729   /* send */
17730   S (mp);
17731
17732   /* wait for reply */
17733   W (ret);
17734   return ret;
17735 }
17736
17737 static int
17738 api_show_one_stats_enable_disable (vat_main_t * vam)
17739 {
17740   vl_api_show_one_stats_enable_disable_t *mp;
17741   int ret;
17742
17743   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17744
17745   /* send */
17746   S (mp);
17747
17748   /* wait for reply */
17749   W (ret);
17750   return ret;
17751 }
17752
17753 static int
17754 api_show_one_map_request_mode (vat_main_t * vam)
17755 {
17756   vl_api_show_one_map_request_mode_t *mp;
17757   int ret;
17758
17759   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17760
17761   /* send */
17762   S (mp);
17763
17764   /* wait for reply */
17765   W (ret);
17766   return ret;
17767 }
17768
17769 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17770
17771 static int
17772 api_one_map_request_mode (vat_main_t * vam)
17773 {
17774   unformat_input_t *input = vam->input;
17775   vl_api_one_map_request_mode_t *mp;
17776   u8 mode = 0;
17777   int ret;
17778
17779   /* Parse args required to build the message */
17780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17781     {
17782       if (unformat (input, "dst-only"))
17783         mode = 0;
17784       else if (unformat (input, "src-dst"))
17785         mode = 1;
17786       else
17787         {
17788           errmsg ("parse error '%U'", format_unformat_error, input);
17789           return -99;
17790         }
17791     }
17792
17793   M (ONE_MAP_REQUEST_MODE, mp);
17794
17795   mp->mode = mode;
17796
17797   /* send */
17798   S (mp);
17799
17800   /* wait for reply */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_lisp_map_request_mode api_one_map_request_mode
17806
17807 /**
17808  * Enable/disable ONE proxy ITR.
17809  *
17810  * @param vam vpp API test context
17811  * @return return code
17812  */
17813 static int
17814 api_one_pitr_set_locator_set (vat_main_t * vam)
17815 {
17816   u8 ls_name_set = 0;
17817   unformat_input_t *input = vam->input;
17818   vl_api_one_pitr_set_locator_set_t *mp;
17819   u8 is_add = 1;
17820   u8 *ls_name = 0;
17821   int ret;
17822
17823   /* Parse args required to build the message */
17824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17825     {
17826       if (unformat (input, "del"))
17827         is_add = 0;
17828       else if (unformat (input, "locator-set %s", &ls_name))
17829         ls_name_set = 1;
17830       else
17831         {
17832           errmsg ("parse error '%U'", format_unformat_error, input);
17833           return -99;
17834         }
17835     }
17836
17837   if (!ls_name_set)
17838     {
17839       errmsg ("locator-set name not set!");
17840       return -99;
17841     }
17842
17843   M (ONE_PITR_SET_LOCATOR_SET, mp);
17844
17845   mp->is_add = is_add;
17846   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17847   vec_free (ls_name);
17848
17849   /* send */
17850   S (mp);
17851
17852   /* wait for reply */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17858
17859 static int
17860 api_one_nsh_set_locator_set (vat_main_t * vam)
17861 {
17862   u8 ls_name_set = 0;
17863   unformat_input_t *input = vam->input;
17864   vl_api_one_nsh_set_locator_set_t *mp;
17865   u8 is_add = 1;
17866   u8 *ls_name = 0;
17867   int ret;
17868
17869   /* Parse args required to build the message */
17870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17871     {
17872       if (unformat (input, "del"))
17873         is_add = 0;
17874       else if (unformat (input, "ls %s", &ls_name))
17875         ls_name_set = 1;
17876       else
17877         {
17878           errmsg ("parse error '%U'", format_unformat_error, input);
17879           return -99;
17880         }
17881     }
17882
17883   if (!ls_name_set && is_add)
17884     {
17885       errmsg ("locator-set name not set!");
17886       return -99;
17887     }
17888
17889   M (ONE_NSH_SET_LOCATOR_SET, mp);
17890
17891   mp->is_add = is_add;
17892   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17893   vec_free (ls_name);
17894
17895   /* send */
17896   S (mp);
17897
17898   /* wait for reply */
17899   W (ret);
17900   return ret;
17901 }
17902
17903 static int
17904 api_show_one_pitr (vat_main_t * vam)
17905 {
17906   vl_api_show_one_pitr_t *mp;
17907   int ret;
17908
17909   if (!vam->json_output)
17910     {
17911       print (vam->ofp, "%=20s", "lisp status:");
17912     }
17913
17914   M (SHOW_ONE_PITR, mp);
17915   /* send it... */
17916   S (mp);
17917
17918   /* Wait for a reply... */
17919   W (ret);
17920   return ret;
17921 }
17922
17923 #define api_show_lisp_pitr api_show_one_pitr
17924
17925 static int
17926 api_one_use_petr (vat_main_t * vam)
17927 {
17928   unformat_input_t *input = vam->input;
17929   vl_api_one_use_petr_t *mp;
17930   u8 is_add = 0;
17931   ip_address_t ip;
17932   int ret;
17933
17934   memset (&ip, 0, sizeof (ip));
17935
17936   /* Parse args required to build the message */
17937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17938     {
17939       if (unformat (input, "disable"))
17940         is_add = 0;
17941       else
17942         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17943         {
17944           is_add = 1;
17945           ip_addr_version (&ip) = IP4;
17946         }
17947       else
17948         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17949         {
17950           is_add = 1;
17951           ip_addr_version (&ip) = IP6;
17952         }
17953       else
17954         {
17955           errmsg ("parse error '%U'", format_unformat_error, input);
17956           return -99;
17957         }
17958     }
17959
17960   M (ONE_USE_PETR, mp);
17961
17962   mp->is_add = is_add;
17963   if (is_add)
17964     {
17965       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17966       if (mp->is_ip4)
17967         clib_memcpy (mp->address, &ip, 4);
17968       else
17969         clib_memcpy (mp->address, &ip, 16);
17970     }
17971
17972   /* send */
17973   S (mp);
17974
17975   /* wait for reply */
17976   W (ret);
17977   return ret;
17978 }
17979
17980 #define api_lisp_use_petr api_one_use_petr
17981
17982 static int
17983 api_show_one_nsh_mapping (vat_main_t * vam)
17984 {
17985   vl_api_show_one_use_petr_t *mp;
17986   int ret;
17987
17988   if (!vam->json_output)
17989     {
17990       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17991     }
17992
17993   M (SHOW_ONE_NSH_MAPPING, mp);
17994   /* send it... */
17995   S (mp);
17996
17997   /* Wait for a reply... */
17998   W (ret);
17999   return ret;
18000 }
18001
18002 static int
18003 api_show_one_use_petr (vat_main_t * vam)
18004 {
18005   vl_api_show_one_use_petr_t *mp;
18006   int ret;
18007
18008   if (!vam->json_output)
18009     {
18010       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18011     }
18012
18013   M (SHOW_ONE_USE_PETR, mp);
18014   /* send it... */
18015   S (mp);
18016
18017   /* Wait for a reply... */
18018   W (ret);
18019   return ret;
18020 }
18021
18022 #define api_show_lisp_use_petr api_show_one_use_petr
18023
18024 /**
18025  * Add/delete mapping between vni and vrf
18026  */
18027 static int
18028 api_one_eid_table_add_del_map (vat_main_t * vam)
18029 {
18030   unformat_input_t *input = vam->input;
18031   vl_api_one_eid_table_add_del_map_t *mp;
18032   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18033   u32 vni, vrf, bd_index;
18034   int ret;
18035
18036   /* Parse args required to build the message */
18037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18038     {
18039       if (unformat (input, "del"))
18040         is_add = 0;
18041       else if (unformat (input, "vrf %d", &vrf))
18042         vrf_set = 1;
18043       else if (unformat (input, "bd_index %d", &bd_index))
18044         bd_index_set = 1;
18045       else if (unformat (input, "vni %d", &vni))
18046         vni_set = 1;
18047       else
18048         break;
18049     }
18050
18051   if (!vni_set || (!vrf_set && !bd_index_set))
18052     {
18053       errmsg ("missing arguments!");
18054       return -99;
18055     }
18056
18057   if (vrf_set && bd_index_set)
18058     {
18059       errmsg ("error: both vrf and bd entered!");
18060       return -99;
18061     }
18062
18063   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18064
18065   mp->is_add = is_add;
18066   mp->vni = htonl (vni);
18067   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18068   mp->is_l2 = bd_index_set;
18069
18070   /* send */
18071   S (mp);
18072
18073   /* wait for reply */
18074   W (ret);
18075   return ret;
18076 }
18077
18078 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18079
18080 uword
18081 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18082 {
18083   u32 *action = va_arg (*args, u32 *);
18084   u8 *s = 0;
18085
18086   if (unformat (input, "%s", &s))
18087     {
18088       if (!strcmp ((char *) s, "no-action"))
18089         action[0] = 0;
18090       else if (!strcmp ((char *) s, "natively-forward"))
18091         action[0] = 1;
18092       else if (!strcmp ((char *) s, "send-map-request"))
18093         action[0] = 2;
18094       else if (!strcmp ((char *) s, "drop"))
18095         action[0] = 3;
18096       else
18097         {
18098           clib_warning ("invalid action: '%s'", s);
18099           action[0] = 3;
18100         }
18101     }
18102   else
18103     return 0;
18104
18105   vec_free (s);
18106   return 1;
18107 }
18108
18109 /**
18110  * Add/del remote mapping to/from ONE control plane
18111  *
18112  * @param vam vpp API test context
18113  * @return return code
18114  */
18115 static int
18116 api_one_add_del_remote_mapping (vat_main_t * vam)
18117 {
18118   unformat_input_t *input = vam->input;
18119   vl_api_one_add_del_remote_mapping_t *mp;
18120   u32 vni = 0;
18121   lisp_eid_vat_t _eid, *eid = &_eid;
18122   lisp_eid_vat_t _seid, *seid = &_seid;
18123   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18124   u32 action = ~0, p, w, data_len;
18125   ip4_address_t rloc4;
18126   ip6_address_t rloc6;
18127   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18128   int ret;
18129
18130   memset (&rloc, 0, sizeof (rloc));
18131
18132   /* Parse args required to build the message */
18133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18134     {
18135       if (unformat (input, "del-all"))
18136         {
18137           del_all = 1;
18138         }
18139       else if (unformat (input, "del"))
18140         {
18141           is_add = 0;
18142         }
18143       else if (unformat (input, "add"))
18144         {
18145           is_add = 1;
18146         }
18147       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18148         {
18149           eid_set = 1;
18150         }
18151       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18152         {
18153           seid_set = 1;
18154         }
18155       else if (unformat (input, "vni %d", &vni))
18156         {
18157           ;
18158         }
18159       else if (unformat (input, "p %d w %d", &p, &w))
18160         {
18161           if (!curr_rloc)
18162             {
18163               errmsg ("No RLOC configured for setting priority/weight!");
18164               return -99;
18165             }
18166           curr_rloc->priority = p;
18167           curr_rloc->weight = w;
18168         }
18169       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18170         {
18171           rloc.is_ip4 = 1;
18172           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18173           vec_add1 (rlocs, rloc);
18174           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18175         }
18176       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18177         {
18178           rloc.is_ip4 = 0;
18179           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18180           vec_add1 (rlocs, rloc);
18181           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18182         }
18183       else if (unformat (input, "action %U",
18184                          unformat_negative_mapping_action, &action))
18185         {
18186           ;
18187         }
18188       else
18189         {
18190           clib_warning ("parse error '%U'", format_unformat_error, input);
18191           return -99;
18192         }
18193     }
18194
18195   if (0 == eid_set)
18196     {
18197       errmsg ("missing params!");
18198       return -99;
18199     }
18200
18201   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18202     {
18203       errmsg ("no action set for negative map-reply!");
18204       return -99;
18205     }
18206
18207   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18208
18209   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18210   mp->is_add = is_add;
18211   mp->vni = htonl (vni);
18212   mp->action = (u8) action;
18213   mp->is_src_dst = seid_set;
18214   mp->eid_len = eid->len;
18215   mp->seid_len = seid->len;
18216   mp->del_all = del_all;
18217   mp->eid_type = eid->type;
18218   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18219   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18220
18221   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18222   clib_memcpy (mp->rlocs, rlocs, data_len);
18223   vec_free (rlocs);
18224
18225   /* send it... */
18226   S (mp);
18227
18228   /* Wait for a reply... */
18229   W (ret);
18230   return ret;
18231 }
18232
18233 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18234
18235 /**
18236  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18237  * forwarding entries in data-plane accordingly.
18238  *
18239  * @param vam vpp API test context
18240  * @return return code
18241  */
18242 static int
18243 api_one_add_del_adjacency (vat_main_t * vam)
18244 {
18245   unformat_input_t *input = vam->input;
18246   vl_api_one_add_del_adjacency_t *mp;
18247   u32 vni = 0;
18248   ip4_address_t leid4, reid4;
18249   ip6_address_t leid6, reid6;
18250   u8 reid_mac[6] = { 0 };
18251   u8 leid_mac[6] = { 0 };
18252   u8 reid_type, leid_type;
18253   u32 leid_len = 0, reid_len = 0, len;
18254   u8 is_add = 1;
18255   int ret;
18256
18257   leid_type = reid_type = (u8) ~ 0;
18258
18259   /* Parse args required to build the message */
18260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18261     {
18262       if (unformat (input, "del"))
18263         {
18264           is_add = 0;
18265         }
18266       else if (unformat (input, "add"))
18267         {
18268           is_add = 1;
18269         }
18270       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18271                          &reid4, &len))
18272         {
18273           reid_type = 0;        /* ipv4 */
18274           reid_len = len;
18275         }
18276       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18277                          &reid6, &len))
18278         {
18279           reid_type = 1;        /* ipv6 */
18280           reid_len = len;
18281         }
18282       else if (unformat (input, "reid %U", unformat_ethernet_address,
18283                          reid_mac))
18284         {
18285           reid_type = 2;        /* mac */
18286         }
18287       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18288                          &leid4, &len))
18289         {
18290           leid_type = 0;        /* ipv4 */
18291           leid_len = len;
18292         }
18293       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18294                          &leid6, &len))
18295         {
18296           leid_type = 1;        /* ipv6 */
18297           leid_len = len;
18298         }
18299       else if (unformat (input, "leid %U", unformat_ethernet_address,
18300                          leid_mac))
18301         {
18302           leid_type = 2;        /* mac */
18303         }
18304       else if (unformat (input, "vni %d", &vni))
18305         {
18306           ;
18307         }
18308       else
18309         {
18310           errmsg ("parse error '%U'", format_unformat_error, input);
18311           return -99;
18312         }
18313     }
18314
18315   if ((u8) ~ 0 == reid_type)
18316     {
18317       errmsg ("missing params!");
18318       return -99;
18319     }
18320
18321   if (leid_type != reid_type)
18322     {
18323       errmsg ("remote and local EIDs are of different types!");
18324       return -99;
18325     }
18326
18327   M (ONE_ADD_DEL_ADJACENCY, mp);
18328   mp->is_add = is_add;
18329   mp->vni = htonl (vni);
18330   mp->leid_len = leid_len;
18331   mp->reid_len = reid_len;
18332   mp->eid_type = reid_type;
18333
18334   switch (mp->eid_type)
18335     {
18336     case 0:
18337       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18338       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18339       break;
18340     case 1:
18341       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18342       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18343       break;
18344     case 2:
18345       clib_memcpy (mp->leid, leid_mac, 6);
18346       clib_memcpy (mp->reid, reid_mac, 6);
18347       break;
18348     default:
18349       errmsg ("unknown EID type %d!", mp->eid_type);
18350       return 0;
18351     }
18352
18353   /* send it... */
18354   S (mp);
18355
18356   /* Wait for a reply... */
18357   W (ret);
18358   return ret;
18359 }
18360
18361 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18362
18363 uword
18364 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18365 {
18366   u32 *mode = va_arg (*args, u32 *);
18367
18368   if (unformat (input, "lisp"))
18369     *mode = 0;
18370   else if (unformat (input, "vxlan"))
18371     *mode = 1;
18372   else
18373     return 0;
18374
18375   return 1;
18376 }
18377
18378 static int
18379 api_gpe_get_encap_mode (vat_main_t * vam)
18380 {
18381   vl_api_gpe_get_encap_mode_t *mp;
18382   int ret;
18383
18384   /* Construct the API message */
18385   M (GPE_GET_ENCAP_MODE, mp);
18386
18387   /* send it... */
18388   S (mp);
18389
18390   /* Wait for a reply... */
18391   W (ret);
18392   return ret;
18393 }
18394
18395 static int
18396 api_gpe_set_encap_mode (vat_main_t * vam)
18397 {
18398   unformat_input_t *input = vam->input;
18399   vl_api_gpe_set_encap_mode_t *mp;
18400   int ret;
18401   u32 mode = 0;
18402
18403   /* Parse args required to build the message */
18404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18405     {
18406       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18407         ;
18408       else
18409         break;
18410     }
18411
18412   /* Construct the API message */
18413   M (GPE_SET_ENCAP_MODE, mp);
18414
18415   mp->mode = mode;
18416
18417   /* send it... */
18418   S (mp);
18419
18420   /* Wait for a reply... */
18421   W (ret);
18422   return ret;
18423 }
18424
18425 static int
18426 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18427 {
18428   unformat_input_t *input = vam->input;
18429   vl_api_gpe_add_del_iface_t *mp;
18430   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18431   u32 dp_table = 0, vni = 0;
18432   int ret;
18433
18434   /* Parse args required to build the message */
18435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18436     {
18437       if (unformat (input, "up"))
18438         {
18439           action_set = 1;
18440           is_add = 1;
18441         }
18442       else if (unformat (input, "down"))
18443         {
18444           action_set = 1;
18445           is_add = 0;
18446         }
18447       else if (unformat (input, "table_id %d", &dp_table))
18448         {
18449           dp_table_set = 1;
18450         }
18451       else if (unformat (input, "bd_id %d", &dp_table))
18452         {
18453           dp_table_set = 1;
18454           is_l2 = 1;
18455         }
18456       else if (unformat (input, "vni %d", &vni))
18457         {
18458           vni_set = 1;
18459         }
18460       else
18461         break;
18462     }
18463
18464   if (action_set == 0)
18465     {
18466       errmsg ("Action not set");
18467       return -99;
18468     }
18469   if (dp_table_set == 0 || vni_set == 0)
18470     {
18471       errmsg ("vni and dp_table must be set");
18472       return -99;
18473     }
18474
18475   /* Construct the API message */
18476   M (GPE_ADD_DEL_IFACE, mp);
18477
18478   mp->is_add = is_add;
18479   mp->dp_table = clib_host_to_net_u32 (dp_table);
18480   mp->is_l2 = is_l2;
18481   mp->vni = clib_host_to_net_u32 (vni);
18482
18483   /* send it... */
18484   S (mp);
18485
18486   /* Wait for a reply... */
18487   W (ret);
18488   return ret;
18489 }
18490
18491 static int
18492 api_one_map_register_fallback_threshold (vat_main_t * vam)
18493 {
18494   unformat_input_t *input = vam->input;
18495   vl_api_one_map_register_fallback_threshold_t *mp;
18496   u32 value = 0;
18497   u8 is_set = 0;
18498   int ret;
18499
18500   /* Parse args required to build the message */
18501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18502     {
18503       if (unformat (input, "%u", &value))
18504         is_set = 1;
18505       else
18506         {
18507           clib_warning ("parse error '%U'", format_unformat_error, input);
18508           return -99;
18509         }
18510     }
18511
18512   if (!is_set)
18513     {
18514       errmsg ("fallback threshold value is missing!");
18515       return -99;
18516     }
18517
18518   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18519   mp->value = clib_host_to_net_u32 (value);
18520
18521   /* send it... */
18522   S (mp);
18523
18524   /* Wait for a reply... */
18525   W (ret);
18526   return ret;
18527 }
18528
18529 static int
18530 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18531 {
18532   vl_api_show_one_map_register_fallback_threshold_t *mp;
18533   int ret;
18534
18535   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18536
18537   /* send it... */
18538   S (mp);
18539
18540   /* Wait for a reply... */
18541   W (ret);
18542   return ret;
18543 }
18544
18545 uword
18546 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18547 {
18548   u32 *proto = va_arg (*args, u32 *);
18549
18550   if (unformat (input, "udp"))
18551     *proto = 1;
18552   else if (unformat (input, "api"))
18553     *proto = 2;
18554   else
18555     return 0;
18556
18557   return 1;
18558 }
18559
18560 static int
18561 api_one_set_transport_protocol (vat_main_t * vam)
18562 {
18563   unformat_input_t *input = vam->input;
18564   vl_api_one_set_transport_protocol_t *mp;
18565   u8 is_set = 0;
18566   u32 protocol = 0;
18567   int ret;
18568
18569   /* Parse args required to build the message */
18570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18571     {
18572       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18573         is_set = 1;
18574       else
18575         {
18576           clib_warning ("parse error '%U'", format_unformat_error, input);
18577           return -99;
18578         }
18579     }
18580
18581   if (!is_set)
18582     {
18583       errmsg ("Transport protocol missing!");
18584       return -99;
18585     }
18586
18587   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18588   mp->protocol = (u8) protocol;
18589
18590   /* send it... */
18591   S (mp);
18592
18593   /* Wait for a reply... */
18594   W (ret);
18595   return ret;
18596 }
18597
18598 static int
18599 api_one_get_transport_protocol (vat_main_t * vam)
18600 {
18601   vl_api_one_get_transport_protocol_t *mp;
18602   int ret;
18603
18604   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18605
18606   /* send it... */
18607   S (mp);
18608
18609   /* Wait for a reply... */
18610   W (ret);
18611   return ret;
18612 }
18613
18614 static int
18615 api_one_map_register_set_ttl (vat_main_t * vam)
18616 {
18617   unformat_input_t *input = vam->input;
18618   vl_api_one_map_register_set_ttl_t *mp;
18619   u32 ttl = 0;
18620   u8 is_set = 0;
18621   int ret;
18622
18623   /* Parse args required to build the message */
18624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18625     {
18626       if (unformat (input, "%u", &ttl))
18627         is_set = 1;
18628       else
18629         {
18630           clib_warning ("parse error '%U'", format_unformat_error, input);
18631           return -99;
18632         }
18633     }
18634
18635   if (!is_set)
18636     {
18637       errmsg ("TTL value missing!");
18638       return -99;
18639     }
18640
18641   M (ONE_MAP_REGISTER_SET_TTL, mp);
18642   mp->ttl = clib_host_to_net_u32 (ttl);
18643
18644   /* send it... */
18645   S (mp);
18646
18647   /* Wait for a reply... */
18648   W (ret);
18649   return ret;
18650 }
18651
18652 static int
18653 api_show_one_map_register_ttl (vat_main_t * vam)
18654 {
18655   vl_api_show_one_map_register_ttl_t *mp;
18656   int ret;
18657
18658   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18659
18660   /* send it... */
18661   S (mp);
18662
18663   /* Wait for a reply... */
18664   W (ret);
18665   return ret;
18666 }
18667
18668 /**
18669  * Add/del map request itr rlocs from ONE control plane and updates
18670  *
18671  * @param vam vpp API test context
18672  * @return return code
18673  */
18674 static int
18675 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18676 {
18677   unformat_input_t *input = vam->input;
18678   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18679   u8 *locator_set_name = 0;
18680   u8 locator_set_name_set = 0;
18681   u8 is_add = 1;
18682   int ret;
18683
18684   /* Parse args required to build the message */
18685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18686     {
18687       if (unformat (input, "del"))
18688         {
18689           is_add = 0;
18690         }
18691       else if (unformat (input, "%_%v%_", &locator_set_name))
18692         {
18693           locator_set_name_set = 1;
18694         }
18695       else
18696         {
18697           clib_warning ("parse error '%U'", format_unformat_error, input);
18698           return -99;
18699         }
18700     }
18701
18702   if (is_add && !locator_set_name_set)
18703     {
18704       errmsg ("itr-rloc is not set!");
18705       return -99;
18706     }
18707
18708   if (is_add && vec_len (locator_set_name) > 64)
18709     {
18710       errmsg ("itr-rloc locator-set name too long");
18711       vec_free (locator_set_name);
18712       return -99;
18713     }
18714
18715   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18716   mp->is_add = is_add;
18717   if (is_add)
18718     {
18719       clib_memcpy (mp->locator_set_name, locator_set_name,
18720                    vec_len (locator_set_name));
18721     }
18722   else
18723     {
18724       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18725     }
18726   vec_free (locator_set_name);
18727
18728   /* send it... */
18729   S (mp);
18730
18731   /* Wait for a reply... */
18732   W (ret);
18733   return ret;
18734 }
18735
18736 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18737
18738 static int
18739 api_one_locator_dump (vat_main_t * vam)
18740 {
18741   unformat_input_t *input = vam->input;
18742   vl_api_one_locator_dump_t *mp;
18743   vl_api_control_ping_t *mp_ping;
18744   u8 is_index_set = 0, is_name_set = 0;
18745   u8 *ls_name = 0;
18746   u32 ls_index = ~0;
18747   int ret;
18748
18749   /* Parse args required to build the message */
18750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (input, "ls_name %_%v%_", &ls_name))
18753         {
18754           is_name_set = 1;
18755         }
18756       else if (unformat (input, "ls_index %d", &ls_index))
18757         {
18758           is_index_set = 1;
18759         }
18760       else
18761         {
18762           errmsg ("parse error '%U'", format_unformat_error, input);
18763           return -99;
18764         }
18765     }
18766
18767   if (!is_index_set && !is_name_set)
18768     {
18769       errmsg ("error: expected one of index or name!");
18770       return -99;
18771     }
18772
18773   if (is_index_set && is_name_set)
18774     {
18775       errmsg ("error: only one param expected!");
18776       return -99;
18777     }
18778
18779   if (vec_len (ls_name) > 62)
18780     {
18781       errmsg ("error: locator set name too long!");
18782       return -99;
18783     }
18784
18785   if (!vam->json_output)
18786     {
18787       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18788     }
18789
18790   M (ONE_LOCATOR_DUMP, mp);
18791   mp->is_index_set = is_index_set;
18792
18793   if (is_index_set)
18794     mp->ls_index = clib_host_to_net_u32 (ls_index);
18795   else
18796     {
18797       vec_add1 (ls_name, 0);
18798       strncpy ((char *) mp->ls_name, (char *) ls_name,
18799                sizeof (mp->ls_name) - 1);
18800     }
18801
18802   /* send it... */
18803   S (mp);
18804
18805   /* Use a control ping for synchronization */
18806   MPING (CONTROL_PING, mp_ping);
18807   S (mp_ping);
18808
18809   /* Wait for a reply... */
18810   W (ret);
18811   return ret;
18812 }
18813
18814 #define api_lisp_locator_dump api_one_locator_dump
18815
18816 static int
18817 api_one_locator_set_dump (vat_main_t * vam)
18818 {
18819   vl_api_one_locator_set_dump_t *mp;
18820   vl_api_control_ping_t *mp_ping;
18821   unformat_input_t *input = vam->input;
18822   u8 filter = 0;
18823   int ret;
18824
18825   /* Parse args required to build the message */
18826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18827     {
18828       if (unformat (input, "local"))
18829         {
18830           filter = 1;
18831         }
18832       else if (unformat (input, "remote"))
18833         {
18834           filter = 2;
18835         }
18836       else
18837         {
18838           errmsg ("parse error '%U'", format_unformat_error, input);
18839           return -99;
18840         }
18841     }
18842
18843   if (!vam->json_output)
18844     {
18845       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18846     }
18847
18848   M (ONE_LOCATOR_SET_DUMP, mp);
18849
18850   mp->filter = filter;
18851
18852   /* send it... */
18853   S (mp);
18854
18855   /* Use a control ping for synchronization */
18856   MPING (CONTROL_PING, mp_ping);
18857   S (mp_ping);
18858
18859   /* Wait for a reply... */
18860   W (ret);
18861   return ret;
18862 }
18863
18864 #define api_lisp_locator_set_dump api_one_locator_set_dump
18865
18866 static int
18867 api_one_eid_table_map_dump (vat_main_t * vam)
18868 {
18869   u8 is_l2 = 0;
18870   u8 mode_set = 0;
18871   unformat_input_t *input = vam->input;
18872   vl_api_one_eid_table_map_dump_t *mp;
18873   vl_api_control_ping_t *mp_ping;
18874   int ret;
18875
18876   /* Parse args required to build the message */
18877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18878     {
18879       if (unformat (input, "l2"))
18880         {
18881           is_l2 = 1;
18882           mode_set = 1;
18883         }
18884       else if (unformat (input, "l3"))
18885         {
18886           is_l2 = 0;
18887           mode_set = 1;
18888         }
18889       else
18890         {
18891           errmsg ("parse error '%U'", format_unformat_error, input);
18892           return -99;
18893         }
18894     }
18895
18896   if (!mode_set)
18897     {
18898       errmsg ("expected one of 'l2' or 'l3' parameter!");
18899       return -99;
18900     }
18901
18902   if (!vam->json_output)
18903     {
18904       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18905     }
18906
18907   M (ONE_EID_TABLE_MAP_DUMP, mp);
18908   mp->is_l2 = is_l2;
18909
18910   /* send it... */
18911   S (mp);
18912
18913   /* Use a control ping for synchronization */
18914   MPING (CONTROL_PING, mp_ping);
18915   S (mp_ping);
18916
18917   /* Wait for a reply... */
18918   W (ret);
18919   return ret;
18920 }
18921
18922 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18923
18924 static int
18925 api_one_eid_table_vni_dump (vat_main_t * vam)
18926 {
18927   vl_api_one_eid_table_vni_dump_t *mp;
18928   vl_api_control_ping_t *mp_ping;
18929   int ret;
18930
18931   if (!vam->json_output)
18932     {
18933       print (vam->ofp, "VNI");
18934     }
18935
18936   M (ONE_EID_TABLE_VNI_DUMP, mp);
18937
18938   /* send it... */
18939   S (mp);
18940
18941   /* Use a control ping for synchronization */
18942   MPING (CONTROL_PING, mp_ping);
18943   S (mp_ping);
18944
18945   /* Wait for a reply... */
18946   W (ret);
18947   return ret;
18948 }
18949
18950 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18951
18952 static int
18953 api_one_eid_table_dump (vat_main_t * vam)
18954 {
18955   unformat_input_t *i = vam->input;
18956   vl_api_one_eid_table_dump_t *mp;
18957   vl_api_control_ping_t *mp_ping;
18958   struct in_addr ip4;
18959   struct in6_addr ip6;
18960   u8 mac[6];
18961   u8 eid_type = ~0, eid_set = 0;
18962   u32 prefix_length = ~0, t, vni = 0;
18963   u8 filter = 0;
18964   int ret;
18965   lisp_nsh_api_t nsh;
18966
18967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18968     {
18969       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18970         {
18971           eid_set = 1;
18972           eid_type = 0;
18973           prefix_length = t;
18974         }
18975       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18976         {
18977           eid_set = 1;
18978           eid_type = 1;
18979           prefix_length = t;
18980         }
18981       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18982         {
18983           eid_set = 1;
18984           eid_type = 2;
18985         }
18986       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18987         {
18988           eid_set = 1;
18989           eid_type = 3;
18990         }
18991       else if (unformat (i, "vni %d", &t))
18992         {
18993           vni = t;
18994         }
18995       else if (unformat (i, "local"))
18996         {
18997           filter = 1;
18998         }
18999       else if (unformat (i, "remote"))
19000         {
19001           filter = 2;
19002         }
19003       else
19004         {
19005           errmsg ("parse error '%U'", format_unformat_error, i);
19006           return -99;
19007         }
19008     }
19009
19010   if (!vam->json_output)
19011     {
19012       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19013              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19014     }
19015
19016   M (ONE_EID_TABLE_DUMP, mp);
19017
19018   mp->filter = filter;
19019   if (eid_set)
19020     {
19021       mp->eid_set = 1;
19022       mp->vni = htonl (vni);
19023       mp->eid_type = eid_type;
19024       switch (eid_type)
19025         {
19026         case 0:
19027           mp->prefix_length = prefix_length;
19028           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19029           break;
19030         case 1:
19031           mp->prefix_length = prefix_length;
19032           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19033           break;
19034         case 2:
19035           clib_memcpy (mp->eid, mac, sizeof (mac));
19036           break;
19037         case 3:
19038           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19039           break;
19040         default:
19041           errmsg ("unknown EID type %d!", eid_type);
19042           return -99;
19043         }
19044     }
19045
19046   /* send it... */
19047   S (mp);
19048
19049   /* Use a control ping for synchronization */
19050   MPING (CONTROL_PING, mp_ping);
19051   S (mp_ping);
19052
19053   /* Wait for a reply... */
19054   W (ret);
19055   return ret;
19056 }
19057
19058 #define api_lisp_eid_table_dump api_one_eid_table_dump
19059
19060 static int
19061 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19062 {
19063   unformat_input_t *i = vam->input;
19064   vl_api_gpe_fwd_entries_get_t *mp;
19065   u8 vni_set = 0;
19066   u32 vni = ~0;
19067   int ret;
19068
19069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19070     {
19071       if (unformat (i, "vni %d", &vni))
19072         {
19073           vni_set = 1;
19074         }
19075       else
19076         {
19077           errmsg ("parse error '%U'", format_unformat_error, i);
19078           return -99;
19079         }
19080     }
19081
19082   if (!vni_set)
19083     {
19084       errmsg ("vni not set!");
19085       return -99;
19086     }
19087
19088   if (!vam->json_output)
19089     {
19090       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19091              "leid", "reid");
19092     }
19093
19094   M (GPE_FWD_ENTRIES_GET, mp);
19095   mp->vni = clib_host_to_net_u32 (vni);
19096
19097   /* send it... */
19098   S (mp);
19099
19100   /* Wait for a reply... */
19101   W (ret);
19102   return ret;
19103 }
19104
19105 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19106 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19107 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19108 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19109 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19110 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19111 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19112 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19113
19114 static int
19115 api_one_adjacencies_get (vat_main_t * vam)
19116 {
19117   unformat_input_t *i = vam->input;
19118   vl_api_one_adjacencies_get_t *mp;
19119   u8 vni_set = 0;
19120   u32 vni = ~0;
19121   int ret;
19122
19123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19124     {
19125       if (unformat (i, "vni %d", &vni))
19126         {
19127           vni_set = 1;
19128         }
19129       else
19130         {
19131           errmsg ("parse error '%U'", format_unformat_error, i);
19132           return -99;
19133         }
19134     }
19135
19136   if (!vni_set)
19137     {
19138       errmsg ("vni not set!");
19139       return -99;
19140     }
19141
19142   if (!vam->json_output)
19143     {
19144       print (vam->ofp, "%s %40s", "leid", "reid");
19145     }
19146
19147   M (ONE_ADJACENCIES_GET, mp);
19148   mp->vni = clib_host_to_net_u32 (vni);
19149
19150   /* send it... */
19151   S (mp);
19152
19153   /* Wait for a reply... */
19154   W (ret);
19155   return ret;
19156 }
19157
19158 #define api_lisp_adjacencies_get api_one_adjacencies_get
19159
19160 static int
19161 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19162 {
19163   unformat_input_t *i = vam->input;
19164   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19165   int ret;
19166   u8 ip_family_set = 0, is_ip4 = 1;
19167
19168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19169     {
19170       if (unformat (i, "ip4"))
19171         {
19172           ip_family_set = 1;
19173           is_ip4 = 1;
19174         }
19175       else if (unformat (i, "ip6"))
19176         {
19177           ip_family_set = 1;
19178           is_ip4 = 0;
19179         }
19180       else
19181         {
19182           errmsg ("parse error '%U'", format_unformat_error, i);
19183           return -99;
19184         }
19185     }
19186
19187   if (!ip_family_set)
19188     {
19189       errmsg ("ip family not set!");
19190       return -99;
19191     }
19192
19193   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19194   mp->is_ip4 = is_ip4;
19195
19196   /* send it... */
19197   S (mp);
19198
19199   /* Wait for a reply... */
19200   W (ret);
19201   return ret;
19202 }
19203
19204 static int
19205 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19206 {
19207   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19208   int ret;
19209
19210   if (!vam->json_output)
19211     {
19212       print (vam->ofp, "VNIs");
19213     }
19214
19215   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19216
19217   /* send it... */
19218   S (mp);
19219
19220   /* Wait for a reply... */
19221   W (ret);
19222   return ret;
19223 }
19224
19225 static int
19226 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19227 {
19228   unformat_input_t *i = vam->input;
19229   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19230   int ret = 0;
19231   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19232   struct in_addr ip4;
19233   struct in6_addr ip6;
19234   u32 table_id = 0, nh_sw_if_index = ~0;
19235
19236   memset (&ip4, 0, sizeof (ip4));
19237   memset (&ip6, 0, sizeof (ip6));
19238
19239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19240     {
19241       if (unformat (i, "del"))
19242         is_add = 0;
19243       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19244                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19245         {
19246           ip_set = 1;
19247           is_ip4 = 1;
19248         }
19249       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19250                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19251         {
19252           ip_set = 1;
19253           is_ip4 = 0;
19254         }
19255       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19256         {
19257           ip_set = 1;
19258           is_ip4 = 1;
19259           nh_sw_if_index = ~0;
19260         }
19261       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19262         {
19263           ip_set = 1;
19264           is_ip4 = 0;
19265           nh_sw_if_index = ~0;
19266         }
19267       else if (unformat (i, "table %d", &table_id))
19268         ;
19269       else
19270         {
19271           errmsg ("parse error '%U'", format_unformat_error, i);
19272           return -99;
19273         }
19274     }
19275
19276   if (!ip_set)
19277     {
19278       errmsg ("nh addr not set!");
19279       return -99;
19280     }
19281
19282   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19283   mp->is_add = is_add;
19284   mp->table_id = clib_host_to_net_u32 (table_id);
19285   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19286   mp->is_ip4 = is_ip4;
19287   if (is_ip4)
19288     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19289   else
19290     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19291
19292   /* send it... */
19293   S (mp);
19294
19295   /* Wait for a reply... */
19296   W (ret);
19297   return ret;
19298 }
19299
19300 static int
19301 api_one_map_server_dump (vat_main_t * vam)
19302 {
19303   vl_api_one_map_server_dump_t *mp;
19304   vl_api_control_ping_t *mp_ping;
19305   int ret;
19306
19307   if (!vam->json_output)
19308     {
19309       print (vam->ofp, "%=20s", "Map server");
19310     }
19311
19312   M (ONE_MAP_SERVER_DUMP, mp);
19313   /* send it... */
19314   S (mp);
19315
19316   /* Use a control ping for synchronization */
19317   MPING (CONTROL_PING, mp_ping);
19318   S (mp_ping);
19319
19320   /* Wait for a reply... */
19321   W (ret);
19322   return ret;
19323 }
19324
19325 #define api_lisp_map_server_dump api_one_map_server_dump
19326
19327 static int
19328 api_one_map_resolver_dump (vat_main_t * vam)
19329 {
19330   vl_api_one_map_resolver_dump_t *mp;
19331   vl_api_control_ping_t *mp_ping;
19332   int ret;
19333
19334   if (!vam->json_output)
19335     {
19336       print (vam->ofp, "%=20s", "Map resolver");
19337     }
19338
19339   M (ONE_MAP_RESOLVER_DUMP, mp);
19340   /* send it... */
19341   S (mp);
19342
19343   /* Use a control ping for synchronization */
19344   MPING (CONTROL_PING, mp_ping);
19345   S (mp_ping);
19346
19347   /* Wait for a reply... */
19348   W (ret);
19349   return ret;
19350 }
19351
19352 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19353
19354 static int
19355 api_one_stats_flush (vat_main_t * vam)
19356 {
19357   vl_api_one_stats_flush_t *mp;
19358   int ret = 0;
19359
19360   M (ONE_STATS_FLUSH, mp);
19361   S (mp);
19362   W (ret);
19363   return ret;
19364 }
19365
19366 static int
19367 api_one_stats_dump (vat_main_t * vam)
19368 {
19369   vl_api_one_stats_dump_t *mp;
19370   vl_api_control_ping_t *mp_ping;
19371   int ret;
19372
19373   M (ONE_STATS_DUMP, mp);
19374   /* send it... */
19375   S (mp);
19376
19377   /* Use a control ping for synchronization */
19378   MPING (CONTROL_PING, mp_ping);
19379   S (mp_ping);
19380
19381   /* Wait for a reply... */
19382   W (ret);
19383   return ret;
19384 }
19385
19386 static int
19387 api_show_one_status (vat_main_t * vam)
19388 {
19389   vl_api_show_one_status_t *mp;
19390   int ret;
19391
19392   if (!vam->json_output)
19393     {
19394       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19395     }
19396
19397   M (SHOW_ONE_STATUS, mp);
19398   /* send it... */
19399   S (mp);
19400   /* Wait for a reply... */
19401   W (ret);
19402   return ret;
19403 }
19404
19405 #define api_show_lisp_status api_show_one_status
19406
19407 static int
19408 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19409 {
19410   vl_api_gpe_fwd_entry_path_dump_t *mp;
19411   vl_api_control_ping_t *mp_ping;
19412   unformat_input_t *i = vam->input;
19413   u32 fwd_entry_index = ~0;
19414   int ret;
19415
19416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19417     {
19418       if (unformat (i, "index %d", &fwd_entry_index))
19419         ;
19420       else
19421         break;
19422     }
19423
19424   if (~0 == fwd_entry_index)
19425     {
19426       errmsg ("no index specified!");
19427       return -99;
19428     }
19429
19430   if (!vam->json_output)
19431     {
19432       print (vam->ofp, "first line");
19433     }
19434
19435   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19436
19437   /* send it... */
19438   S (mp);
19439   /* Use a control ping for synchronization */
19440   MPING (CONTROL_PING, mp_ping);
19441   S (mp_ping);
19442
19443   /* Wait for a reply... */
19444   W (ret);
19445   return ret;
19446 }
19447
19448 static int
19449 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19450 {
19451   vl_api_one_get_map_request_itr_rlocs_t *mp;
19452   int ret;
19453
19454   if (!vam->json_output)
19455     {
19456       print (vam->ofp, "%=20s", "itr-rlocs:");
19457     }
19458
19459   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19460   /* send it... */
19461   S (mp);
19462   /* Wait for a reply... */
19463   W (ret);
19464   return ret;
19465 }
19466
19467 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19468
19469 static int
19470 api_af_packet_create (vat_main_t * vam)
19471 {
19472   unformat_input_t *i = vam->input;
19473   vl_api_af_packet_create_t *mp;
19474   u8 *host_if_name = 0;
19475   u8 hw_addr[6];
19476   u8 random_hw_addr = 1;
19477   int ret;
19478
19479   memset (hw_addr, 0, sizeof (hw_addr));
19480
19481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19482     {
19483       if (unformat (i, "name %s", &host_if_name))
19484         vec_add1 (host_if_name, 0);
19485       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19486         random_hw_addr = 0;
19487       else
19488         break;
19489     }
19490
19491   if (!vec_len (host_if_name))
19492     {
19493       errmsg ("host-interface name must be specified");
19494       return -99;
19495     }
19496
19497   if (vec_len (host_if_name) > 64)
19498     {
19499       errmsg ("host-interface name too long");
19500       return -99;
19501     }
19502
19503   M (AF_PACKET_CREATE, mp);
19504
19505   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19506   clib_memcpy (mp->hw_addr, hw_addr, 6);
19507   mp->use_random_hw_addr = random_hw_addr;
19508   vec_free (host_if_name);
19509
19510   S (mp);
19511
19512   /* *INDENT-OFF* */
19513   W2 (ret,
19514       ({
19515         if (ret == 0)
19516           fprintf (vam->ofp ? vam->ofp : stderr,
19517                    " new sw_if_index = %d\n", vam->sw_if_index);
19518       }));
19519   /* *INDENT-ON* */
19520   return ret;
19521 }
19522
19523 static int
19524 api_af_packet_delete (vat_main_t * vam)
19525 {
19526   unformat_input_t *i = vam->input;
19527   vl_api_af_packet_delete_t *mp;
19528   u8 *host_if_name = 0;
19529   int ret;
19530
19531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19532     {
19533       if (unformat (i, "name %s", &host_if_name))
19534         vec_add1 (host_if_name, 0);
19535       else
19536         break;
19537     }
19538
19539   if (!vec_len (host_if_name))
19540     {
19541       errmsg ("host-interface name must be specified");
19542       return -99;
19543     }
19544
19545   if (vec_len (host_if_name) > 64)
19546     {
19547       errmsg ("host-interface name too long");
19548       return -99;
19549     }
19550
19551   M (AF_PACKET_DELETE, mp);
19552
19553   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19554   vec_free (host_if_name);
19555
19556   S (mp);
19557   W (ret);
19558   return ret;
19559 }
19560
19561 static void vl_api_af_packet_details_t_handler
19562   (vl_api_af_packet_details_t * mp)
19563 {
19564   vat_main_t *vam = &vat_main;
19565
19566   print (vam->ofp, "%-16s %d",
19567          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19568 }
19569
19570 static void vl_api_af_packet_details_t_handler_json
19571   (vl_api_af_packet_details_t * mp)
19572 {
19573   vat_main_t *vam = &vat_main;
19574   vat_json_node_t *node = NULL;
19575
19576   if (VAT_JSON_ARRAY != vam->json_tree.type)
19577     {
19578       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19579       vat_json_init_array (&vam->json_tree);
19580     }
19581   node = vat_json_array_add (&vam->json_tree);
19582
19583   vat_json_init_object (node);
19584   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19585   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19586 }
19587
19588 static int
19589 api_af_packet_dump (vat_main_t * vam)
19590 {
19591   vl_api_af_packet_dump_t *mp;
19592   vl_api_control_ping_t *mp_ping;
19593   int ret;
19594
19595   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19596   /* Get list of tap interfaces */
19597   M (AF_PACKET_DUMP, mp);
19598   S (mp);
19599
19600   /* Use a control ping for synchronization */
19601   MPING (CONTROL_PING, mp_ping);
19602   S (mp_ping);
19603
19604   W (ret);
19605   return ret;
19606 }
19607
19608 static int
19609 api_policer_add_del (vat_main_t * vam)
19610 {
19611   unformat_input_t *i = vam->input;
19612   vl_api_policer_add_del_t *mp;
19613   u8 is_add = 1;
19614   u8 *name = 0;
19615   u32 cir = 0;
19616   u32 eir = 0;
19617   u64 cb = 0;
19618   u64 eb = 0;
19619   u8 rate_type = 0;
19620   u8 round_type = 0;
19621   u8 type = 0;
19622   u8 color_aware = 0;
19623   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19624   int ret;
19625
19626   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19627   conform_action.dscp = 0;
19628   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19629   exceed_action.dscp = 0;
19630   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19631   violate_action.dscp = 0;
19632
19633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19634     {
19635       if (unformat (i, "del"))
19636         is_add = 0;
19637       else if (unformat (i, "name %s", &name))
19638         vec_add1 (name, 0);
19639       else if (unformat (i, "cir %u", &cir))
19640         ;
19641       else if (unformat (i, "eir %u", &eir))
19642         ;
19643       else if (unformat (i, "cb %u", &cb))
19644         ;
19645       else if (unformat (i, "eb %u", &eb))
19646         ;
19647       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19648                          &rate_type))
19649         ;
19650       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19651                          &round_type))
19652         ;
19653       else if (unformat (i, "type %U", unformat_policer_type, &type))
19654         ;
19655       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19656                          &conform_action))
19657         ;
19658       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19659                          &exceed_action))
19660         ;
19661       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19662                          &violate_action))
19663         ;
19664       else if (unformat (i, "color-aware"))
19665         color_aware = 1;
19666       else
19667         break;
19668     }
19669
19670   if (!vec_len (name))
19671     {
19672       errmsg ("policer name must be specified");
19673       return -99;
19674     }
19675
19676   if (vec_len (name) > 64)
19677     {
19678       errmsg ("policer name too long");
19679       return -99;
19680     }
19681
19682   M (POLICER_ADD_DEL, mp);
19683
19684   clib_memcpy (mp->name, name, vec_len (name));
19685   vec_free (name);
19686   mp->is_add = is_add;
19687   mp->cir = ntohl (cir);
19688   mp->eir = ntohl (eir);
19689   mp->cb = clib_net_to_host_u64 (cb);
19690   mp->eb = clib_net_to_host_u64 (eb);
19691   mp->rate_type = rate_type;
19692   mp->round_type = round_type;
19693   mp->type = type;
19694   mp->conform_action_type = conform_action.action_type;
19695   mp->conform_dscp = conform_action.dscp;
19696   mp->exceed_action_type = exceed_action.action_type;
19697   mp->exceed_dscp = exceed_action.dscp;
19698   mp->violate_action_type = violate_action.action_type;
19699   mp->violate_dscp = violate_action.dscp;
19700   mp->color_aware = color_aware;
19701
19702   S (mp);
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static int
19708 api_policer_dump (vat_main_t * vam)
19709 {
19710   unformat_input_t *i = vam->input;
19711   vl_api_policer_dump_t *mp;
19712   vl_api_control_ping_t *mp_ping;
19713   u8 *match_name = 0;
19714   u8 match_name_valid = 0;
19715   int ret;
19716
19717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19718     {
19719       if (unformat (i, "name %s", &match_name))
19720         {
19721           vec_add1 (match_name, 0);
19722           match_name_valid = 1;
19723         }
19724       else
19725         break;
19726     }
19727
19728   M (POLICER_DUMP, mp);
19729   mp->match_name_valid = match_name_valid;
19730   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19731   vec_free (match_name);
19732   /* send it... */
19733   S (mp);
19734
19735   /* Use a control ping for synchronization */
19736   MPING (CONTROL_PING, mp_ping);
19737   S (mp_ping);
19738
19739   /* Wait for a reply... */
19740   W (ret);
19741   return ret;
19742 }
19743
19744 static int
19745 api_policer_classify_set_interface (vat_main_t * vam)
19746 {
19747   unformat_input_t *i = vam->input;
19748   vl_api_policer_classify_set_interface_t *mp;
19749   u32 sw_if_index;
19750   int sw_if_index_set;
19751   u32 ip4_table_index = ~0;
19752   u32 ip6_table_index = ~0;
19753   u32 l2_table_index = ~0;
19754   u8 is_add = 1;
19755   int ret;
19756
19757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19758     {
19759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19760         sw_if_index_set = 1;
19761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19762         sw_if_index_set = 1;
19763       else if (unformat (i, "del"))
19764         is_add = 0;
19765       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19766         ;
19767       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19768         ;
19769       else if (unformat (i, "l2-table %d", &l2_table_index))
19770         ;
19771       else
19772         {
19773           clib_warning ("parse error '%U'", format_unformat_error, i);
19774           return -99;
19775         }
19776     }
19777
19778   if (sw_if_index_set == 0)
19779     {
19780       errmsg ("missing interface name or sw_if_index");
19781       return -99;
19782     }
19783
19784   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19785
19786   mp->sw_if_index = ntohl (sw_if_index);
19787   mp->ip4_table_index = ntohl (ip4_table_index);
19788   mp->ip6_table_index = ntohl (ip6_table_index);
19789   mp->l2_table_index = ntohl (l2_table_index);
19790   mp->is_add = is_add;
19791
19792   S (mp);
19793   W (ret);
19794   return ret;
19795 }
19796
19797 static int
19798 api_policer_classify_dump (vat_main_t * vam)
19799 {
19800   unformat_input_t *i = vam->input;
19801   vl_api_policer_classify_dump_t *mp;
19802   vl_api_control_ping_t *mp_ping;
19803   u8 type = POLICER_CLASSIFY_N_TABLES;
19804   int ret;
19805
19806   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19807     ;
19808   else
19809     {
19810       errmsg ("classify table type must be specified");
19811       return -99;
19812     }
19813
19814   if (!vam->json_output)
19815     {
19816       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19817     }
19818
19819   M (POLICER_CLASSIFY_DUMP, mp);
19820   mp->type = type;
19821   /* send it... */
19822   S (mp);
19823
19824   /* Use a control ping for synchronization */
19825   MPING (CONTROL_PING, mp_ping);
19826   S (mp_ping);
19827
19828   /* Wait for a reply... */
19829   W (ret);
19830   return ret;
19831 }
19832
19833 static int
19834 api_netmap_create (vat_main_t * vam)
19835 {
19836   unformat_input_t *i = vam->input;
19837   vl_api_netmap_create_t *mp;
19838   u8 *if_name = 0;
19839   u8 hw_addr[6];
19840   u8 random_hw_addr = 1;
19841   u8 is_pipe = 0;
19842   u8 is_master = 0;
19843   int ret;
19844
19845   memset (hw_addr, 0, sizeof (hw_addr));
19846
19847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19848     {
19849       if (unformat (i, "name %s", &if_name))
19850         vec_add1 (if_name, 0);
19851       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19852         random_hw_addr = 0;
19853       else if (unformat (i, "pipe"))
19854         is_pipe = 1;
19855       else if (unformat (i, "master"))
19856         is_master = 1;
19857       else if (unformat (i, "slave"))
19858         is_master = 0;
19859       else
19860         break;
19861     }
19862
19863   if (!vec_len (if_name))
19864     {
19865       errmsg ("interface name must be specified");
19866       return -99;
19867     }
19868
19869   if (vec_len (if_name) > 64)
19870     {
19871       errmsg ("interface name too long");
19872       return -99;
19873     }
19874
19875   M (NETMAP_CREATE, mp);
19876
19877   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19878   clib_memcpy (mp->hw_addr, hw_addr, 6);
19879   mp->use_random_hw_addr = random_hw_addr;
19880   mp->is_pipe = is_pipe;
19881   mp->is_master = is_master;
19882   vec_free (if_name);
19883
19884   S (mp);
19885   W (ret);
19886   return ret;
19887 }
19888
19889 static int
19890 api_netmap_delete (vat_main_t * vam)
19891 {
19892   unformat_input_t *i = vam->input;
19893   vl_api_netmap_delete_t *mp;
19894   u8 *if_name = 0;
19895   int ret;
19896
19897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19898     {
19899       if (unformat (i, "name %s", &if_name))
19900         vec_add1 (if_name, 0);
19901       else
19902         break;
19903     }
19904
19905   if (!vec_len (if_name))
19906     {
19907       errmsg ("interface name must be specified");
19908       return -99;
19909     }
19910
19911   if (vec_len (if_name) > 64)
19912     {
19913       errmsg ("interface name too long");
19914       return -99;
19915     }
19916
19917   M (NETMAP_DELETE, mp);
19918
19919   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19920   vec_free (if_name);
19921
19922   S (mp);
19923   W (ret);
19924   return ret;
19925 }
19926
19927 static void
19928 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19929 {
19930   if (fp->afi == IP46_TYPE_IP6)
19931     print (vam->ofp,
19932            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19933            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19934            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19935            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19936            format_ip6_address, fp->next_hop);
19937   else if (fp->afi == IP46_TYPE_IP4)
19938     print (vam->ofp,
19939            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19940            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19941            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19942            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19943            format_ip4_address, fp->next_hop);
19944 }
19945
19946 static void
19947 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19948                                  vl_api_fib_path_t * fp)
19949 {
19950   struct in_addr ip4;
19951   struct in6_addr ip6;
19952
19953   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19954   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19955   vat_json_object_add_uint (node, "is_local", fp->is_local);
19956   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19957   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19958   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19959   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19960   if (fp->afi == IP46_TYPE_IP4)
19961     {
19962       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19963       vat_json_object_add_ip4 (node, "next_hop", ip4);
19964     }
19965   else if (fp->afi == IP46_TYPE_IP6)
19966     {
19967       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19968       vat_json_object_add_ip6 (node, "next_hop", ip6);
19969     }
19970 }
19971
19972 static void
19973 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19974 {
19975   vat_main_t *vam = &vat_main;
19976   int count = ntohl (mp->mt_count);
19977   vl_api_fib_path_t *fp;
19978   i32 i;
19979
19980   print (vam->ofp, "[%d]: sw_if_index %d via:",
19981          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19982   fp = mp->mt_paths;
19983   for (i = 0; i < count; i++)
19984     {
19985       vl_api_mpls_fib_path_print (vam, fp);
19986       fp++;
19987     }
19988
19989   print (vam->ofp, "");
19990 }
19991
19992 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19993 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19994
19995 static void
19996 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19997 {
19998   vat_main_t *vam = &vat_main;
19999   vat_json_node_t *node = NULL;
20000   int count = ntohl (mp->mt_count);
20001   vl_api_fib_path_t *fp;
20002   i32 i;
20003
20004   if (VAT_JSON_ARRAY != vam->json_tree.type)
20005     {
20006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20007       vat_json_init_array (&vam->json_tree);
20008     }
20009   node = vat_json_array_add (&vam->json_tree);
20010
20011   vat_json_init_object (node);
20012   vat_json_object_add_uint (node, "tunnel_index",
20013                             ntohl (mp->mt_tunnel_index));
20014   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20015
20016   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20017
20018   fp = mp->mt_paths;
20019   for (i = 0; i < count; i++)
20020     {
20021       vl_api_mpls_fib_path_json_print (node, fp);
20022       fp++;
20023     }
20024 }
20025
20026 static int
20027 api_mpls_tunnel_dump (vat_main_t * vam)
20028 {
20029   vl_api_mpls_tunnel_dump_t *mp;
20030   vl_api_control_ping_t *mp_ping;
20031   i32 index = -1;
20032   int ret;
20033
20034   /* Parse args required to build the message */
20035   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20036     {
20037       if (!unformat (vam->input, "tunnel_index %d", &index))
20038         {
20039           index = -1;
20040           break;
20041         }
20042     }
20043
20044   print (vam->ofp, "  tunnel_index %d", index);
20045
20046   M (MPLS_TUNNEL_DUMP, mp);
20047   mp->tunnel_index = htonl (index);
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   W (ret);
20055   return ret;
20056 }
20057
20058 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20059 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20060
20061
20062 static void
20063 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20064 {
20065   vat_main_t *vam = &vat_main;
20066   int count = ntohl (mp->count);
20067   vl_api_fib_path_t *fp;
20068   int i;
20069
20070   print (vam->ofp,
20071          "table-id %d, label %u, ess_bit %u",
20072          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20073   fp = mp->path;
20074   for (i = 0; i < count; i++)
20075     {
20076       vl_api_mpls_fib_path_print (vam, fp);
20077       fp++;
20078     }
20079 }
20080
20081 static void vl_api_mpls_fib_details_t_handler_json
20082   (vl_api_mpls_fib_details_t * mp)
20083 {
20084   vat_main_t *vam = &vat_main;
20085   int count = ntohl (mp->count);
20086   vat_json_node_t *node = NULL;
20087   vl_api_fib_path_t *fp;
20088   int i;
20089
20090   if (VAT_JSON_ARRAY != vam->json_tree.type)
20091     {
20092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20093       vat_json_init_array (&vam->json_tree);
20094     }
20095   node = vat_json_array_add (&vam->json_tree);
20096
20097   vat_json_init_object (node);
20098   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20099   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20100   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20101   vat_json_object_add_uint (node, "path_count", count);
20102   fp = mp->path;
20103   for (i = 0; i < count; i++)
20104     {
20105       vl_api_mpls_fib_path_json_print (node, fp);
20106       fp++;
20107     }
20108 }
20109
20110 static int
20111 api_mpls_fib_dump (vat_main_t * vam)
20112 {
20113   vl_api_mpls_fib_dump_t *mp;
20114   vl_api_control_ping_t *mp_ping;
20115   int ret;
20116
20117   M (MPLS_FIB_DUMP, mp);
20118   S (mp);
20119
20120   /* Use a control ping for synchronization */
20121   MPING (CONTROL_PING, mp_ping);
20122   S (mp_ping);
20123
20124   W (ret);
20125   return ret;
20126 }
20127
20128 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20129 #define vl_api_ip_fib_details_t_print vl_noop_handler
20130
20131 static void
20132 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20133 {
20134   vat_main_t *vam = &vat_main;
20135   int count = ntohl (mp->count);
20136   vl_api_fib_path_t *fp;
20137   int i;
20138
20139   print (vam->ofp,
20140          "table-id %d, prefix %U/%d",
20141          ntohl (mp->table_id), format_ip4_address, mp->address,
20142          mp->address_length);
20143   fp = mp->path;
20144   for (i = 0; i < count; i++)
20145     {
20146       if (fp->afi == IP46_TYPE_IP6)
20147         print (vam->ofp,
20148                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20149                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20150                "next_hop_table %d",
20151                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20152                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20153                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20154       else if (fp->afi == IP46_TYPE_IP4)
20155         print (vam->ofp,
20156                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20157                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20158                "next_hop_table %d",
20159                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20160                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20161                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20162       fp++;
20163     }
20164 }
20165
20166 static void vl_api_ip_fib_details_t_handler_json
20167   (vl_api_ip_fib_details_t * mp)
20168 {
20169   vat_main_t *vam = &vat_main;
20170   int count = ntohl (mp->count);
20171   vat_json_node_t *node = NULL;
20172   struct in_addr ip4;
20173   struct in6_addr ip6;
20174   vl_api_fib_path_t *fp;
20175   int i;
20176
20177   if (VAT_JSON_ARRAY != vam->json_tree.type)
20178     {
20179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20180       vat_json_init_array (&vam->json_tree);
20181     }
20182   node = vat_json_array_add (&vam->json_tree);
20183
20184   vat_json_init_object (node);
20185   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20186   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20187   vat_json_object_add_ip4 (node, "prefix", ip4);
20188   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20189   vat_json_object_add_uint (node, "path_count", count);
20190   fp = mp->path;
20191   for (i = 0; i < count; i++)
20192     {
20193       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20194       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20195       vat_json_object_add_uint (node, "is_local", fp->is_local);
20196       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20197       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20198       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20199       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20200       if (fp->afi == IP46_TYPE_IP4)
20201         {
20202           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20203           vat_json_object_add_ip4 (node, "next_hop", ip4);
20204         }
20205       else if (fp->afi == IP46_TYPE_IP6)
20206         {
20207           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20208           vat_json_object_add_ip6 (node, "next_hop", ip6);
20209         }
20210     }
20211 }
20212
20213 static int
20214 api_ip_fib_dump (vat_main_t * vam)
20215 {
20216   vl_api_ip_fib_dump_t *mp;
20217   vl_api_control_ping_t *mp_ping;
20218   int ret;
20219
20220   M (IP_FIB_DUMP, mp);
20221   S (mp);
20222
20223   /* Use a control ping for synchronization */
20224   MPING (CONTROL_PING, mp_ping);
20225   S (mp_ping);
20226
20227   W (ret);
20228   return ret;
20229 }
20230
20231 static int
20232 api_ip_mfib_dump (vat_main_t * vam)
20233 {
20234   vl_api_ip_mfib_dump_t *mp;
20235   vl_api_control_ping_t *mp_ping;
20236   int ret;
20237
20238   M (IP_MFIB_DUMP, mp);
20239   S (mp);
20240
20241   /* Use a control ping for synchronization */
20242   MPING (CONTROL_PING, mp_ping);
20243   S (mp_ping);
20244
20245   W (ret);
20246   return ret;
20247 }
20248
20249 static void vl_api_ip_neighbor_details_t_handler
20250   (vl_api_ip_neighbor_details_t * mp)
20251 {
20252   vat_main_t *vam = &vat_main;
20253
20254   print (vam->ofp, "%c %U %U",
20255          (mp->is_static) ? 'S' : 'D',
20256          format_ethernet_address, &mp->mac_address,
20257          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20258          &mp->ip_address);
20259 }
20260
20261 static void vl_api_ip_neighbor_details_t_handler_json
20262   (vl_api_ip_neighbor_details_t * mp)
20263 {
20264
20265   vat_main_t *vam = &vat_main;
20266   vat_json_node_t *node;
20267   struct in_addr ip4;
20268   struct in6_addr ip6;
20269
20270   if (VAT_JSON_ARRAY != vam->json_tree.type)
20271     {
20272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20273       vat_json_init_array (&vam->json_tree);
20274     }
20275   node = vat_json_array_add (&vam->json_tree);
20276
20277   vat_json_init_object (node);
20278   vat_json_object_add_string_copy (node, "flag",
20279                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20280                                    "dynamic");
20281
20282   vat_json_object_add_string_copy (node, "link_layer",
20283                                    format (0, "%U", format_ethernet_address,
20284                                            &mp->mac_address));
20285
20286   if (mp->is_ipv6)
20287     {
20288       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20289       vat_json_object_add_ip6 (node, "ip_address", ip6);
20290     }
20291   else
20292     {
20293       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20294       vat_json_object_add_ip4 (node, "ip_address", ip4);
20295     }
20296 }
20297
20298 static int
20299 api_ip_neighbor_dump (vat_main_t * vam)
20300 {
20301   unformat_input_t *i = vam->input;
20302   vl_api_ip_neighbor_dump_t *mp;
20303   vl_api_control_ping_t *mp_ping;
20304   u8 is_ipv6 = 0;
20305   u32 sw_if_index = ~0;
20306   int ret;
20307
20308   /* Parse args required to build the message */
20309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20310     {
20311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20312         ;
20313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20314         ;
20315       else if (unformat (i, "ip6"))
20316         is_ipv6 = 1;
20317       else
20318         break;
20319     }
20320
20321   if (sw_if_index == ~0)
20322     {
20323       errmsg ("missing interface name or sw_if_index");
20324       return -99;
20325     }
20326
20327   M (IP_NEIGHBOR_DUMP, mp);
20328   mp->is_ipv6 = (u8) is_ipv6;
20329   mp->sw_if_index = ntohl (sw_if_index);
20330   S (mp);
20331
20332   /* Use a control ping for synchronization */
20333   MPING (CONTROL_PING, mp_ping);
20334   S (mp_ping);
20335
20336   W (ret);
20337   return ret;
20338 }
20339
20340 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20341 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20342
20343 static void
20344 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20345 {
20346   vat_main_t *vam = &vat_main;
20347   int count = ntohl (mp->count);
20348   vl_api_fib_path_t *fp;
20349   int i;
20350
20351   print (vam->ofp,
20352          "table-id %d, prefix %U/%d",
20353          ntohl (mp->table_id), format_ip6_address, mp->address,
20354          mp->address_length);
20355   fp = mp->path;
20356   for (i = 0; i < count; i++)
20357     {
20358       if (fp->afi == IP46_TYPE_IP6)
20359         print (vam->ofp,
20360                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20361                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20362                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20363                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20364                format_ip6_address, fp->next_hop);
20365       else if (fp->afi == IP46_TYPE_IP4)
20366         print (vam->ofp,
20367                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20368                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20369                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20370                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20371                format_ip4_address, fp->next_hop);
20372       fp++;
20373     }
20374 }
20375
20376 static void vl_api_ip6_fib_details_t_handler_json
20377   (vl_api_ip6_fib_details_t * mp)
20378 {
20379   vat_main_t *vam = &vat_main;
20380   int count = ntohl (mp->count);
20381   vat_json_node_t *node = NULL;
20382   struct in_addr ip4;
20383   struct in6_addr ip6;
20384   vl_api_fib_path_t *fp;
20385   int i;
20386
20387   if (VAT_JSON_ARRAY != vam->json_tree.type)
20388     {
20389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20390       vat_json_init_array (&vam->json_tree);
20391     }
20392   node = vat_json_array_add (&vam->json_tree);
20393
20394   vat_json_init_object (node);
20395   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20396   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20397   vat_json_object_add_ip6 (node, "prefix", ip6);
20398   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20399   vat_json_object_add_uint (node, "path_count", count);
20400   fp = mp->path;
20401   for (i = 0; i < count; i++)
20402     {
20403       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20404       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20405       vat_json_object_add_uint (node, "is_local", fp->is_local);
20406       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20407       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20408       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20409       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20410       if (fp->afi == IP46_TYPE_IP4)
20411         {
20412           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20413           vat_json_object_add_ip4 (node, "next_hop", ip4);
20414         }
20415       else if (fp->afi == IP46_TYPE_IP6)
20416         {
20417           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20418           vat_json_object_add_ip6 (node, "next_hop", ip6);
20419         }
20420     }
20421 }
20422
20423 static int
20424 api_ip6_fib_dump (vat_main_t * vam)
20425 {
20426   vl_api_ip6_fib_dump_t *mp;
20427   vl_api_control_ping_t *mp_ping;
20428   int ret;
20429
20430   M (IP6_FIB_DUMP, mp);
20431   S (mp);
20432
20433   /* Use a control ping for synchronization */
20434   MPING (CONTROL_PING, mp_ping);
20435   S (mp_ping);
20436
20437   W (ret);
20438   return ret;
20439 }
20440
20441 static int
20442 api_ip6_mfib_dump (vat_main_t * vam)
20443 {
20444   vl_api_ip6_mfib_dump_t *mp;
20445   vl_api_control_ping_t *mp_ping;
20446   int ret;
20447
20448   M (IP6_MFIB_DUMP, mp);
20449   S (mp);
20450
20451   /* Use a control ping for synchronization */
20452   MPING (CONTROL_PING, mp_ping);
20453   S (mp_ping);
20454
20455   W (ret);
20456   return ret;
20457 }
20458
20459 int
20460 api_classify_table_ids (vat_main_t * vam)
20461 {
20462   vl_api_classify_table_ids_t *mp;
20463   int ret;
20464
20465   /* Construct the API message */
20466   M (CLASSIFY_TABLE_IDS, mp);
20467   mp->context = 0;
20468
20469   S (mp);
20470   W (ret);
20471   return ret;
20472 }
20473
20474 int
20475 api_classify_table_by_interface (vat_main_t * vam)
20476 {
20477   unformat_input_t *input = vam->input;
20478   vl_api_classify_table_by_interface_t *mp;
20479
20480   u32 sw_if_index = ~0;
20481   int ret;
20482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20483     {
20484       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20485         ;
20486       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20487         ;
20488       else
20489         break;
20490     }
20491   if (sw_if_index == ~0)
20492     {
20493       errmsg ("missing interface name or sw_if_index");
20494       return -99;
20495     }
20496
20497   /* Construct the API message */
20498   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20499   mp->context = 0;
20500   mp->sw_if_index = ntohl (sw_if_index);
20501
20502   S (mp);
20503   W (ret);
20504   return ret;
20505 }
20506
20507 int
20508 api_classify_table_info (vat_main_t * vam)
20509 {
20510   unformat_input_t *input = vam->input;
20511   vl_api_classify_table_info_t *mp;
20512
20513   u32 table_id = ~0;
20514   int ret;
20515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20516     {
20517       if (unformat (input, "table_id %d", &table_id))
20518         ;
20519       else
20520         break;
20521     }
20522   if (table_id == ~0)
20523     {
20524       errmsg ("missing table id");
20525       return -99;
20526     }
20527
20528   /* Construct the API message */
20529   M (CLASSIFY_TABLE_INFO, mp);
20530   mp->context = 0;
20531   mp->table_id = ntohl (table_id);
20532
20533   S (mp);
20534   W (ret);
20535   return ret;
20536 }
20537
20538 int
20539 api_classify_session_dump (vat_main_t * vam)
20540 {
20541   unformat_input_t *input = vam->input;
20542   vl_api_classify_session_dump_t *mp;
20543   vl_api_control_ping_t *mp_ping;
20544
20545   u32 table_id = ~0;
20546   int ret;
20547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20548     {
20549       if (unformat (input, "table_id %d", &table_id))
20550         ;
20551       else
20552         break;
20553     }
20554   if (table_id == ~0)
20555     {
20556       errmsg ("missing table id");
20557       return -99;
20558     }
20559
20560   /* Construct the API message */
20561   M (CLASSIFY_SESSION_DUMP, mp);
20562   mp->context = 0;
20563   mp->table_id = ntohl (table_id);
20564   S (mp);
20565
20566   /* Use a control ping for synchronization */
20567   MPING (CONTROL_PING, mp_ping);
20568   S (mp_ping);
20569
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static void
20575 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20576 {
20577   vat_main_t *vam = &vat_main;
20578
20579   print (vam->ofp, "collector_address %U, collector_port %d, "
20580          "src_address %U, vrf_id %d, path_mtu %u, "
20581          "template_interval %u, udp_checksum %d",
20582          format_ip4_address, mp->collector_address,
20583          ntohs (mp->collector_port),
20584          format_ip4_address, mp->src_address,
20585          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20586          ntohl (mp->template_interval), mp->udp_checksum);
20587
20588   vam->retval = 0;
20589   vam->result_ready = 1;
20590 }
20591
20592 static void
20593   vl_api_ipfix_exporter_details_t_handler_json
20594   (vl_api_ipfix_exporter_details_t * mp)
20595 {
20596   vat_main_t *vam = &vat_main;
20597   vat_json_node_t node;
20598   struct in_addr collector_address;
20599   struct in_addr src_address;
20600
20601   vat_json_init_object (&node);
20602   clib_memcpy (&collector_address, &mp->collector_address,
20603                sizeof (collector_address));
20604   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20605   vat_json_object_add_uint (&node, "collector_port",
20606                             ntohs (mp->collector_port));
20607   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20608   vat_json_object_add_ip4 (&node, "src_address", src_address);
20609   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20610   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20611   vat_json_object_add_uint (&node, "template_interval",
20612                             ntohl (mp->template_interval));
20613   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20614
20615   vat_json_print (vam->ofp, &node);
20616   vat_json_free (&node);
20617   vam->retval = 0;
20618   vam->result_ready = 1;
20619 }
20620
20621 int
20622 api_ipfix_exporter_dump (vat_main_t * vam)
20623 {
20624   vl_api_ipfix_exporter_dump_t *mp;
20625   int ret;
20626
20627   /* Construct the API message */
20628   M (IPFIX_EXPORTER_DUMP, mp);
20629   mp->context = 0;
20630
20631   S (mp);
20632   W (ret);
20633   return ret;
20634 }
20635
20636 static int
20637 api_ipfix_classify_stream_dump (vat_main_t * vam)
20638 {
20639   vl_api_ipfix_classify_stream_dump_t *mp;
20640   int ret;
20641
20642   /* Construct the API message */
20643   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20644   mp->context = 0;
20645
20646   S (mp);
20647   W (ret);
20648   return ret;
20649   /* NOTREACHED */
20650   return 0;
20651 }
20652
20653 static void
20654   vl_api_ipfix_classify_stream_details_t_handler
20655   (vl_api_ipfix_classify_stream_details_t * mp)
20656 {
20657   vat_main_t *vam = &vat_main;
20658   print (vam->ofp, "domain_id %d, src_port %d",
20659          ntohl (mp->domain_id), ntohs (mp->src_port));
20660   vam->retval = 0;
20661   vam->result_ready = 1;
20662 }
20663
20664 static void
20665   vl_api_ipfix_classify_stream_details_t_handler_json
20666   (vl_api_ipfix_classify_stream_details_t * mp)
20667 {
20668   vat_main_t *vam = &vat_main;
20669   vat_json_node_t node;
20670
20671   vat_json_init_object (&node);
20672   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20673   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20674
20675   vat_json_print (vam->ofp, &node);
20676   vat_json_free (&node);
20677   vam->retval = 0;
20678   vam->result_ready = 1;
20679 }
20680
20681 static int
20682 api_ipfix_classify_table_dump (vat_main_t * vam)
20683 {
20684   vl_api_ipfix_classify_table_dump_t *mp;
20685   vl_api_control_ping_t *mp_ping;
20686   int ret;
20687
20688   if (!vam->json_output)
20689     {
20690       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20691              "transport_protocol");
20692     }
20693
20694   /* Construct the API message */
20695   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20696
20697   /* send it... */
20698   S (mp);
20699
20700   /* Use a control ping for synchronization */
20701   MPING (CONTROL_PING, mp_ping);
20702   S (mp_ping);
20703
20704   W (ret);
20705   return ret;
20706 }
20707
20708 static void
20709   vl_api_ipfix_classify_table_details_t_handler
20710   (vl_api_ipfix_classify_table_details_t * mp)
20711 {
20712   vat_main_t *vam = &vat_main;
20713   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20714          mp->transport_protocol);
20715 }
20716
20717 static void
20718   vl_api_ipfix_classify_table_details_t_handler_json
20719   (vl_api_ipfix_classify_table_details_t * mp)
20720 {
20721   vat_json_node_t *node = NULL;
20722   vat_main_t *vam = &vat_main;
20723
20724   if (VAT_JSON_ARRAY != vam->json_tree.type)
20725     {
20726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20727       vat_json_init_array (&vam->json_tree);
20728     }
20729
20730   node = vat_json_array_add (&vam->json_tree);
20731   vat_json_init_object (node);
20732
20733   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20734   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20735   vat_json_object_add_uint (node, "transport_protocol",
20736                             mp->transport_protocol);
20737 }
20738
20739 static int
20740 api_sw_interface_span_enable_disable (vat_main_t * vam)
20741 {
20742   unformat_input_t *i = vam->input;
20743   vl_api_sw_interface_span_enable_disable_t *mp;
20744   u32 src_sw_if_index = ~0;
20745   u32 dst_sw_if_index = ~0;
20746   u8 state = 3;
20747   int ret;
20748   u8 is_l2 = 0;
20749
20750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20751     {
20752       if (unformat
20753           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20754         ;
20755       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20756         ;
20757       else
20758         if (unformat
20759             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20760         ;
20761       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20762         ;
20763       else if (unformat (i, "disable"))
20764         state = 0;
20765       else if (unformat (i, "rx"))
20766         state = 1;
20767       else if (unformat (i, "tx"))
20768         state = 2;
20769       else if (unformat (i, "both"))
20770         state = 3;
20771       else if (unformat (i, "l2"))
20772         is_l2 = 1;
20773       else
20774         break;
20775     }
20776
20777   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20778
20779   mp->sw_if_index_from = htonl (src_sw_if_index);
20780   mp->sw_if_index_to = htonl (dst_sw_if_index);
20781   mp->state = state;
20782   mp->is_l2 = is_l2;
20783
20784   S (mp);
20785   W (ret);
20786   return ret;
20787 }
20788
20789 static void
20790 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20791                                             * mp)
20792 {
20793   vat_main_t *vam = &vat_main;
20794   u8 *sw_if_from_name = 0;
20795   u8 *sw_if_to_name = 0;
20796   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20797   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20798   char *states[] = { "none", "rx", "tx", "both" };
20799   hash_pair_t *p;
20800
20801   /* *INDENT-OFF* */
20802   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20803   ({
20804     if ((u32) p->value[0] == sw_if_index_from)
20805       {
20806         sw_if_from_name = (u8 *)(p->key);
20807         if (sw_if_to_name)
20808           break;
20809       }
20810     if ((u32) p->value[0] == sw_if_index_to)
20811       {
20812         sw_if_to_name = (u8 *)(p->key);
20813         if (sw_if_from_name)
20814           break;
20815       }
20816   }));
20817   /* *INDENT-ON* */
20818   print (vam->ofp, "%20s => %20s (%s) %s",
20819          sw_if_from_name, sw_if_to_name, states[mp->state],
20820          mp->is_l2 ? "l2" : "device");
20821 }
20822
20823 static void
20824   vl_api_sw_interface_span_details_t_handler_json
20825   (vl_api_sw_interface_span_details_t * mp)
20826 {
20827   vat_main_t *vam = &vat_main;
20828   vat_json_node_t *node = NULL;
20829   u8 *sw_if_from_name = 0;
20830   u8 *sw_if_to_name = 0;
20831   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20832   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20833   hash_pair_t *p;
20834
20835   /* *INDENT-OFF* */
20836   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20837   ({
20838     if ((u32) p->value[0] == sw_if_index_from)
20839       {
20840         sw_if_from_name = (u8 *)(p->key);
20841         if (sw_if_to_name)
20842           break;
20843       }
20844     if ((u32) p->value[0] == sw_if_index_to)
20845       {
20846         sw_if_to_name = (u8 *)(p->key);
20847         if (sw_if_from_name)
20848           break;
20849       }
20850   }));
20851   /* *INDENT-ON* */
20852
20853   if (VAT_JSON_ARRAY != vam->json_tree.type)
20854     {
20855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20856       vat_json_init_array (&vam->json_tree);
20857     }
20858   node = vat_json_array_add (&vam->json_tree);
20859
20860   vat_json_init_object (node);
20861   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20862   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20863   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20864   if (0 != sw_if_to_name)
20865     {
20866       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20867     }
20868   vat_json_object_add_uint (node, "state", mp->state);
20869   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20870 }
20871
20872 static int
20873 api_sw_interface_span_dump (vat_main_t * vam)
20874 {
20875   unformat_input_t *input = vam->input;
20876   vl_api_sw_interface_span_dump_t *mp;
20877   vl_api_control_ping_t *mp_ping;
20878   u8 is_l2 = 0;
20879   int ret;
20880
20881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20882     {
20883       if (unformat (input, "l2"))
20884         is_l2 = 1;
20885       else
20886         break;
20887     }
20888
20889   M (SW_INTERFACE_SPAN_DUMP, mp);
20890   mp->is_l2 = is_l2;
20891   S (mp);
20892
20893   /* Use a control ping for synchronization */
20894   MPING (CONTROL_PING, mp_ping);
20895   S (mp_ping);
20896
20897   W (ret);
20898   return ret;
20899 }
20900
20901 int
20902 api_pg_create_interface (vat_main_t * vam)
20903 {
20904   unformat_input_t *input = vam->input;
20905   vl_api_pg_create_interface_t *mp;
20906
20907   u32 if_id = ~0;
20908   int ret;
20909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20910     {
20911       if (unformat (input, "if_id %d", &if_id))
20912         ;
20913       else
20914         break;
20915     }
20916   if (if_id == ~0)
20917     {
20918       errmsg ("missing pg interface index");
20919       return -99;
20920     }
20921
20922   /* Construct the API message */
20923   M (PG_CREATE_INTERFACE, mp);
20924   mp->context = 0;
20925   mp->interface_id = ntohl (if_id);
20926
20927   S (mp);
20928   W (ret);
20929   return ret;
20930 }
20931
20932 int
20933 api_pg_capture (vat_main_t * vam)
20934 {
20935   unformat_input_t *input = vam->input;
20936   vl_api_pg_capture_t *mp;
20937
20938   u32 if_id = ~0;
20939   u8 enable = 1;
20940   u32 count = 1;
20941   u8 pcap_file_set = 0;
20942   u8 *pcap_file = 0;
20943   int ret;
20944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20945     {
20946       if (unformat (input, "if_id %d", &if_id))
20947         ;
20948       else if (unformat (input, "pcap %s", &pcap_file))
20949         pcap_file_set = 1;
20950       else if (unformat (input, "count %d", &count))
20951         ;
20952       else if (unformat (input, "disable"))
20953         enable = 0;
20954       else
20955         break;
20956     }
20957   if (if_id == ~0)
20958     {
20959       errmsg ("missing pg interface index");
20960       return -99;
20961     }
20962   if (pcap_file_set > 0)
20963     {
20964       if (vec_len (pcap_file) > 255)
20965         {
20966           errmsg ("pcap file name is too long");
20967           return -99;
20968         }
20969     }
20970
20971   u32 name_len = vec_len (pcap_file);
20972   /* Construct the API message */
20973   M (PG_CAPTURE, mp);
20974   mp->context = 0;
20975   mp->interface_id = ntohl (if_id);
20976   mp->is_enabled = enable;
20977   mp->count = ntohl (count);
20978   mp->pcap_name_length = ntohl (name_len);
20979   if (pcap_file_set != 0)
20980     {
20981       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20982     }
20983   vec_free (pcap_file);
20984
20985   S (mp);
20986   W (ret);
20987   return ret;
20988 }
20989
20990 int
20991 api_pg_enable_disable (vat_main_t * vam)
20992 {
20993   unformat_input_t *input = vam->input;
20994   vl_api_pg_enable_disable_t *mp;
20995
20996   u8 enable = 1;
20997   u8 stream_name_set = 0;
20998   u8 *stream_name = 0;
20999   int ret;
21000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21001     {
21002       if (unformat (input, "stream %s", &stream_name))
21003         stream_name_set = 1;
21004       else if (unformat (input, "disable"))
21005         enable = 0;
21006       else
21007         break;
21008     }
21009
21010   if (stream_name_set > 0)
21011     {
21012       if (vec_len (stream_name) > 255)
21013         {
21014           errmsg ("stream name too long");
21015           return -99;
21016         }
21017     }
21018
21019   u32 name_len = vec_len (stream_name);
21020   /* Construct the API message */
21021   M (PG_ENABLE_DISABLE, mp);
21022   mp->context = 0;
21023   mp->is_enabled = enable;
21024   if (stream_name_set != 0)
21025     {
21026       mp->stream_name_length = ntohl (name_len);
21027       clib_memcpy (mp->stream_name, stream_name, name_len);
21028     }
21029   vec_free (stream_name);
21030
21031   S (mp);
21032   W (ret);
21033   return ret;
21034 }
21035
21036 int
21037 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21038 {
21039   unformat_input_t *input = vam->input;
21040   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21041
21042   u16 *low_ports = 0;
21043   u16 *high_ports = 0;
21044   u16 this_low;
21045   u16 this_hi;
21046   ip4_address_t ip4_addr;
21047   ip6_address_t ip6_addr;
21048   u32 length;
21049   u32 tmp, tmp2;
21050   u8 prefix_set = 0;
21051   u32 vrf_id = ~0;
21052   u8 is_add = 1;
21053   u8 is_ipv6 = 0;
21054   int ret;
21055
21056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21057     {
21058       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21059         {
21060           prefix_set = 1;
21061         }
21062       else
21063         if (unformat
21064             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21065         {
21066           prefix_set = 1;
21067           is_ipv6 = 1;
21068         }
21069       else if (unformat (input, "vrf %d", &vrf_id))
21070         ;
21071       else if (unformat (input, "del"))
21072         is_add = 0;
21073       else if (unformat (input, "port %d", &tmp))
21074         {
21075           if (tmp == 0 || tmp > 65535)
21076             {
21077               errmsg ("port %d out of range", tmp);
21078               return -99;
21079             }
21080           this_low = tmp;
21081           this_hi = this_low + 1;
21082           vec_add1 (low_ports, this_low);
21083           vec_add1 (high_ports, this_hi);
21084         }
21085       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21086         {
21087           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21088             {
21089               errmsg ("incorrect range parameters");
21090               return -99;
21091             }
21092           this_low = tmp;
21093           /* Note: in debug CLI +1 is added to high before
21094              passing to real fn that does "the work"
21095              (ip_source_and_port_range_check_add_del).
21096              This fn is a wrapper around the binary API fn a
21097              control plane will call, which expects this increment
21098              to have occurred. Hence letting the binary API control
21099              plane fn do the increment for consistency between VAT
21100              and other control planes.
21101            */
21102           this_hi = tmp2;
21103           vec_add1 (low_ports, this_low);
21104           vec_add1 (high_ports, this_hi);
21105         }
21106       else
21107         break;
21108     }
21109
21110   if (prefix_set == 0)
21111     {
21112       errmsg ("<address>/<mask> not specified");
21113       return -99;
21114     }
21115
21116   if (vrf_id == ~0)
21117     {
21118       errmsg ("VRF ID required, not specified");
21119       return -99;
21120     }
21121
21122   if (vrf_id == 0)
21123     {
21124       errmsg
21125         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21126       return -99;
21127     }
21128
21129   if (vec_len (low_ports) == 0)
21130     {
21131       errmsg ("At least one port or port range required");
21132       return -99;
21133     }
21134
21135   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21136
21137   mp->is_add = is_add;
21138
21139   if (is_ipv6)
21140     {
21141       mp->is_ipv6 = 1;
21142       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21143     }
21144   else
21145     {
21146       mp->is_ipv6 = 0;
21147       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21148     }
21149
21150   mp->mask_length = length;
21151   mp->number_of_ranges = vec_len (low_ports);
21152
21153   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21154   vec_free (low_ports);
21155
21156   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21157   vec_free (high_ports);
21158
21159   mp->vrf_id = ntohl (vrf_id);
21160
21161   S (mp);
21162   W (ret);
21163   return ret;
21164 }
21165
21166 int
21167 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21168 {
21169   unformat_input_t *input = vam->input;
21170   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21171   u32 sw_if_index = ~0;
21172   int vrf_set = 0;
21173   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21174   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21175   u8 is_add = 1;
21176   int ret;
21177
21178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21179     {
21180       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21181         ;
21182       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21183         ;
21184       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21185         vrf_set = 1;
21186       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21187         vrf_set = 1;
21188       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21189         vrf_set = 1;
21190       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21191         vrf_set = 1;
21192       else if (unformat (input, "del"))
21193         is_add = 0;
21194       else
21195         break;
21196     }
21197
21198   if (sw_if_index == ~0)
21199     {
21200       errmsg ("Interface required but not specified");
21201       return -99;
21202     }
21203
21204   if (vrf_set == 0)
21205     {
21206       errmsg ("VRF ID required but not specified");
21207       return -99;
21208     }
21209
21210   if (tcp_out_vrf_id == 0
21211       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21212     {
21213       errmsg
21214         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21215       return -99;
21216     }
21217
21218   /* Construct the API message */
21219   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21220
21221   mp->sw_if_index = ntohl (sw_if_index);
21222   mp->is_add = is_add;
21223   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21224   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21225   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21226   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21227
21228   /* send it... */
21229   S (mp);
21230
21231   /* Wait for a reply... */
21232   W (ret);
21233   return ret;
21234 }
21235
21236 static int
21237 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21238 {
21239   unformat_input_t *i = vam->input;
21240   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21241   u32 local_sa_id = 0;
21242   u32 remote_sa_id = 0;
21243   ip4_address_t src_address;
21244   ip4_address_t dst_address;
21245   u8 is_add = 1;
21246   int ret;
21247
21248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21249     {
21250       if (unformat (i, "local_sa %d", &local_sa_id))
21251         ;
21252       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21253         ;
21254       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21255         ;
21256       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21257         ;
21258       else if (unformat (i, "del"))
21259         is_add = 0;
21260       else
21261         {
21262           clib_warning ("parse error '%U'", format_unformat_error, i);
21263           return -99;
21264         }
21265     }
21266
21267   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21268
21269   mp->local_sa_id = ntohl (local_sa_id);
21270   mp->remote_sa_id = ntohl (remote_sa_id);
21271   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21272   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21273   mp->is_add = is_add;
21274
21275   S (mp);
21276   W (ret);
21277   return ret;
21278 }
21279
21280 static int
21281 api_punt (vat_main_t * vam)
21282 {
21283   unformat_input_t *i = vam->input;
21284   vl_api_punt_t *mp;
21285   u32 ipv = ~0;
21286   u32 protocol = ~0;
21287   u32 port = ~0;
21288   int is_add = 1;
21289   int ret;
21290
21291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21292     {
21293       if (unformat (i, "ip %d", &ipv))
21294         ;
21295       else if (unformat (i, "protocol %d", &protocol))
21296         ;
21297       else if (unformat (i, "port %d", &port))
21298         ;
21299       else if (unformat (i, "del"))
21300         is_add = 0;
21301       else
21302         {
21303           clib_warning ("parse error '%U'", format_unformat_error, i);
21304           return -99;
21305         }
21306     }
21307
21308   M (PUNT, mp);
21309
21310   mp->is_add = (u8) is_add;
21311   mp->ipv = (u8) ipv;
21312   mp->l4_protocol = (u8) protocol;
21313   mp->l4_port = htons ((u16) port);
21314
21315   S (mp);
21316   W (ret);
21317   return ret;
21318 }
21319
21320 static void vl_api_ipsec_gre_tunnel_details_t_handler
21321   (vl_api_ipsec_gre_tunnel_details_t * mp)
21322 {
21323   vat_main_t *vam = &vat_main;
21324
21325   print (vam->ofp, "%11d%15U%15U%14d%14d",
21326          ntohl (mp->sw_if_index),
21327          format_ip4_address, &mp->src_address,
21328          format_ip4_address, &mp->dst_address,
21329          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21330 }
21331
21332 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21333   (vl_api_ipsec_gre_tunnel_details_t * mp)
21334 {
21335   vat_main_t *vam = &vat_main;
21336   vat_json_node_t *node = NULL;
21337   struct in_addr ip4;
21338
21339   if (VAT_JSON_ARRAY != vam->json_tree.type)
21340     {
21341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21342       vat_json_init_array (&vam->json_tree);
21343     }
21344   node = vat_json_array_add (&vam->json_tree);
21345
21346   vat_json_init_object (node);
21347   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21348   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21349   vat_json_object_add_ip4 (node, "src_address", ip4);
21350   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21351   vat_json_object_add_ip4 (node, "dst_address", ip4);
21352   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21353   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21354 }
21355
21356 static int
21357 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21358 {
21359   unformat_input_t *i = vam->input;
21360   vl_api_ipsec_gre_tunnel_dump_t *mp;
21361   vl_api_control_ping_t *mp_ping;
21362   u32 sw_if_index;
21363   u8 sw_if_index_set = 0;
21364   int ret;
21365
21366   /* Parse args required to build the message */
21367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21368     {
21369       if (unformat (i, "sw_if_index %d", &sw_if_index))
21370         sw_if_index_set = 1;
21371       else
21372         break;
21373     }
21374
21375   if (sw_if_index_set == 0)
21376     {
21377       sw_if_index = ~0;
21378     }
21379
21380   if (!vam->json_output)
21381     {
21382       print (vam->ofp, "%11s%15s%15s%14s%14s",
21383              "sw_if_index", "src_address", "dst_address",
21384              "local_sa_id", "remote_sa_id");
21385     }
21386
21387   /* Get list of gre-tunnel interfaces */
21388   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21389
21390   mp->sw_if_index = htonl (sw_if_index);
21391
21392   S (mp);
21393
21394   /* Use a control ping for synchronization */
21395   MPING (CONTROL_PING, mp_ping);
21396   S (mp_ping);
21397
21398   W (ret);
21399   return ret;
21400 }
21401
21402 static int
21403 api_delete_subif (vat_main_t * vam)
21404 {
21405   unformat_input_t *i = vam->input;
21406   vl_api_delete_subif_t *mp;
21407   u32 sw_if_index = ~0;
21408   int ret;
21409
21410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21411     {
21412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21413         ;
21414       if (unformat (i, "sw_if_index %d", &sw_if_index))
21415         ;
21416       else
21417         break;
21418     }
21419
21420   if (sw_if_index == ~0)
21421     {
21422       errmsg ("missing sw_if_index");
21423       return -99;
21424     }
21425
21426   /* Construct the API message */
21427   M (DELETE_SUBIF, mp);
21428   mp->sw_if_index = ntohl (sw_if_index);
21429
21430   S (mp);
21431   W (ret);
21432   return ret;
21433 }
21434
21435 #define foreach_pbb_vtr_op      \
21436 _("disable",  L2_VTR_DISABLED)  \
21437 _("pop",  L2_VTR_POP_2)         \
21438 _("push",  L2_VTR_PUSH_2)
21439
21440 static int
21441 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21442 {
21443   unformat_input_t *i = vam->input;
21444   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21445   u32 sw_if_index = ~0, vtr_op = ~0;
21446   u16 outer_tag = ~0;
21447   u8 dmac[6], smac[6];
21448   u8 dmac_set = 0, smac_set = 0;
21449   u16 vlanid = 0;
21450   u32 sid = ~0;
21451   u32 tmp;
21452   int ret;
21453
21454   /* Shut up coverity */
21455   memset (dmac, 0, sizeof (dmac));
21456   memset (smac, 0, sizeof (smac));
21457
21458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21459     {
21460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21461         ;
21462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21463         ;
21464       else if (unformat (i, "vtr_op %d", &vtr_op))
21465         ;
21466 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21467       foreach_pbb_vtr_op
21468 #undef _
21469         else if (unformat (i, "translate_pbb_stag"))
21470         {
21471           if (unformat (i, "%d", &tmp))
21472             {
21473               vtr_op = L2_VTR_TRANSLATE_2_1;
21474               outer_tag = tmp;
21475             }
21476           else
21477             {
21478               errmsg
21479                 ("translate_pbb_stag operation requires outer tag definition");
21480               return -99;
21481             }
21482         }
21483       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21484         dmac_set++;
21485       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21486         smac_set++;
21487       else if (unformat (i, "sid %d", &sid))
21488         ;
21489       else if (unformat (i, "vlanid %d", &tmp))
21490         vlanid = tmp;
21491       else
21492         {
21493           clib_warning ("parse error '%U'", format_unformat_error, i);
21494           return -99;
21495         }
21496     }
21497
21498   if ((sw_if_index == ~0) || (vtr_op == ~0))
21499     {
21500       errmsg ("missing sw_if_index or vtr operation");
21501       return -99;
21502     }
21503   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21504       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21505     {
21506       errmsg
21507         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21508       return -99;
21509     }
21510
21511   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21512   mp->sw_if_index = ntohl (sw_if_index);
21513   mp->vtr_op = ntohl (vtr_op);
21514   mp->outer_tag = ntohs (outer_tag);
21515   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21516   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21517   mp->b_vlanid = ntohs (vlanid);
21518   mp->i_sid = ntohl (sid);
21519
21520   S (mp);
21521   W (ret);
21522   return ret;
21523 }
21524
21525 static int
21526 api_flow_classify_set_interface (vat_main_t * vam)
21527 {
21528   unformat_input_t *i = vam->input;
21529   vl_api_flow_classify_set_interface_t *mp;
21530   u32 sw_if_index;
21531   int sw_if_index_set;
21532   u32 ip4_table_index = ~0;
21533   u32 ip6_table_index = ~0;
21534   u8 is_add = 1;
21535   int ret;
21536
21537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21538     {
21539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21540         sw_if_index_set = 1;
21541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21542         sw_if_index_set = 1;
21543       else if (unformat (i, "del"))
21544         is_add = 0;
21545       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21546         ;
21547       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21548         ;
21549       else
21550         {
21551           clib_warning ("parse error '%U'", format_unformat_error, i);
21552           return -99;
21553         }
21554     }
21555
21556   if (sw_if_index_set == 0)
21557     {
21558       errmsg ("missing interface name or sw_if_index");
21559       return -99;
21560     }
21561
21562   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21563
21564   mp->sw_if_index = ntohl (sw_if_index);
21565   mp->ip4_table_index = ntohl (ip4_table_index);
21566   mp->ip6_table_index = ntohl (ip6_table_index);
21567   mp->is_add = is_add;
21568
21569   S (mp);
21570   W (ret);
21571   return ret;
21572 }
21573
21574 static int
21575 api_flow_classify_dump (vat_main_t * vam)
21576 {
21577   unformat_input_t *i = vam->input;
21578   vl_api_flow_classify_dump_t *mp;
21579   vl_api_control_ping_t *mp_ping;
21580   u8 type = FLOW_CLASSIFY_N_TABLES;
21581   int ret;
21582
21583   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21584     ;
21585   else
21586     {
21587       errmsg ("classify table type must be specified");
21588       return -99;
21589     }
21590
21591   if (!vam->json_output)
21592     {
21593       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21594     }
21595
21596   M (FLOW_CLASSIFY_DUMP, mp);
21597   mp->type = type;
21598   /* send it... */
21599   S (mp);
21600
21601   /* Use a control ping for synchronization */
21602   MPING (CONTROL_PING, mp_ping);
21603   S (mp_ping);
21604
21605   /* Wait for a reply... */
21606   W (ret);
21607   return ret;
21608 }
21609
21610 static int
21611 api_feature_enable_disable (vat_main_t * vam)
21612 {
21613   unformat_input_t *i = vam->input;
21614   vl_api_feature_enable_disable_t *mp;
21615   u8 *arc_name = 0;
21616   u8 *feature_name = 0;
21617   u32 sw_if_index = ~0;
21618   u8 enable = 1;
21619   int ret;
21620
21621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21622     {
21623       if (unformat (i, "arc_name %s", &arc_name))
21624         ;
21625       else if (unformat (i, "feature_name %s", &feature_name))
21626         ;
21627       else
21628         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21629         ;
21630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21631         ;
21632       else if (unformat (i, "disable"))
21633         enable = 0;
21634       else
21635         break;
21636     }
21637
21638   if (arc_name == 0)
21639     {
21640       errmsg ("missing arc name");
21641       return -99;
21642     }
21643   if (vec_len (arc_name) > 63)
21644     {
21645       errmsg ("arc name too long");
21646     }
21647
21648   if (feature_name == 0)
21649     {
21650       errmsg ("missing feature name");
21651       return -99;
21652     }
21653   if (vec_len (feature_name) > 63)
21654     {
21655       errmsg ("feature name too long");
21656     }
21657
21658   if (sw_if_index == ~0)
21659     {
21660       errmsg ("missing interface name or sw_if_index");
21661       return -99;
21662     }
21663
21664   /* Construct the API message */
21665   M (FEATURE_ENABLE_DISABLE, mp);
21666   mp->sw_if_index = ntohl (sw_if_index);
21667   mp->enable = enable;
21668   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21669   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21670   vec_free (arc_name);
21671   vec_free (feature_name);
21672
21673   S (mp);
21674   W (ret);
21675   return ret;
21676 }
21677
21678 static int
21679 api_sw_interface_tag_add_del (vat_main_t * vam)
21680 {
21681   unformat_input_t *i = vam->input;
21682   vl_api_sw_interface_tag_add_del_t *mp;
21683   u32 sw_if_index = ~0;
21684   u8 *tag = 0;
21685   u8 enable = 1;
21686   int ret;
21687
21688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21689     {
21690       if (unformat (i, "tag %s", &tag))
21691         ;
21692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21693         ;
21694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21695         ;
21696       else if (unformat (i, "del"))
21697         enable = 0;
21698       else
21699         break;
21700     }
21701
21702   if (sw_if_index == ~0)
21703     {
21704       errmsg ("missing interface name or sw_if_index");
21705       return -99;
21706     }
21707
21708   if (enable && (tag == 0))
21709     {
21710       errmsg ("no tag specified");
21711       return -99;
21712     }
21713
21714   /* Construct the API message */
21715   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21716   mp->sw_if_index = ntohl (sw_if_index);
21717   mp->is_add = enable;
21718   if (enable)
21719     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21720   vec_free (tag);
21721
21722   S (mp);
21723   W (ret);
21724   return ret;
21725 }
21726
21727 static void vl_api_l2_xconnect_details_t_handler
21728   (vl_api_l2_xconnect_details_t * mp)
21729 {
21730   vat_main_t *vam = &vat_main;
21731
21732   print (vam->ofp, "%15d%15d",
21733          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21734 }
21735
21736 static void vl_api_l2_xconnect_details_t_handler_json
21737   (vl_api_l2_xconnect_details_t * mp)
21738 {
21739   vat_main_t *vam = &vat_main;
21740   vat_json_node_t *node = NULL;
21741
21742   if (VAT_JSON_ARRAY != vam->json_tree.type)
21743     {
21744       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21745       vat_json_init_array (&vam->json_tree);
21746     }
21747   node = vat_json_array_add (&vam->json_tree);
21748
21749   vat_json_init_object (node);
21750   vat_json_object_add_uint (node, "rx_sw_if_index",
21751                             ntohl (mp->rx_sw_if_index));
21752   vat_json_object_add_uint (node, "tx_sw_if_index",
21753                             ntohl (mp->tx_sw_if_index));
21754 }
21755
21756 static int
21757 api_l2_xconnect_dump (vat_main_t * vam)
21758 {
21759   vl_api_l2_xconnect_dump_t *mp;
21760   vl_api_control_ping_t *mp_ping;
21761   int ret;
21762
21763   if (!vam->json_output)
21764     {
21765       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21766     }
21767
21768   M (L2_XCONNECT_DUMP, mp);
21769
21770   S (mp);
21771
21772   /* Use a control ping for synchronization */
21773   MPING (CONTROL_PING, mp_ping);
21774   S (mp_ping);
21775
21776   W (ret);
21777   return ret;
21778 }
21779
21780 static int
21781 api_hw_interface_set_mtu (vat_main_t * vam)
21782 {
21783   unformat_input_t *i = vam->input;
21784   vl_api_hw_interface_set_mtu_t *mp;
21785   u32 sw_if_index = ~0;
21786   u32 mtu = 0;
21787   int ret;
21788
21789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21790     {
21791       if (unformat (i, "mtu %d", &mtu))
21792         ;
21793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21794         ;
21795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21796         ;
21797       else
21798         break;
21799     }
21800
21801   if (sw_if_index == ~0)
21802     {
21803       errmsg ("missing interface name or sw_if_index");
21804       return -99;
21805     }
21806
21807   if (mtu == 0)
21808     {
21809       errmsg ("no mtu specified");
21810       return -99;
21811     }
21812
21813   /* Construct the API message */
21814   M (HW_INTERFACE_SET_MTU, mp);
21815   mp->sw_if_index = ntohl (sw_if_index);
21816   mp->mtu = ntohs ((u16) mtu);
21817
21818   S (mp);
21819   W (ret);
21820   return ret;
21821 }
21822
21823 static int
21824 api_p2p_ethernet_add (vat_main_t * vam)
21825 {
21826   unformat_input_t *i = vam->input;
21827   vl_api_p2p_ethernet_add_t *mp;
21828   u32 parent_if_index = ~0;
21829   u32 sub_id = ~0;
21830   u8 remote_mac[6];
21831   u8 mac_set = 0;
21832   int ret;
21833
21834   memset (remote_mac, 0, sizeof (remote_mac));
21835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21836     {
21837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21838         ;
21839       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21840         ;
21841       else
21842         if (unformat
21843             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21844         mac_set++;
21845       else if (unformat (i, "sub_id %d", &sub_id))
21846         ;
21847       else
21848         {
21849           clib_warning ("parse error '%U'", format_unformat_error, i);
21850           return -99;
21851         }
21852     }
21853
21854   if (parent_if_index == ~0)
21855     {
21856       errmsg ("missing interface name or sw_if_index");
21857       return -99;
21858     }
21859   if (mac_set == 0)
21860     {
21861       errmsg ("missing remote mac address");
21862       return -99;
21863     }
21864   if (sub_id == ~0)
21865     {
21866       errmsg ("missing sub-interface id");
21867       return -99;
21868     }
21869
21870   M (P2P_ETHERNET_ADD, mp);
21871   mp->parent_if_index = ntohl (parent_if_index);
21872   mp->subif_id = ntohl (sub_id);
21873   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21874
21875   S (mp);
21876   W (ret);
21877   return ret;
21878 }
21879
21880 static int
21881 api_p2p_ethernet_del (vat_main_t * vam)
21882 {
21883   unformat_input_t *i = vam->input;
21884   vl_api_p2p_ethernet_del_t *mp;
21885   u32 parent_if_index = ~0;
21886   u8 remote_mac[6];
21887   u8 mac_set = 0;
21888   int ret;
21889
21890   memset (remote_mac, 0, sizeof (remote_mac));
21891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21892     {
21893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21894         ;
21895       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21896         ;
21897       else
21898         if (unformat
21899             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21900         mac_set++;
21901       else
21902         {
21903           clib_warning ("parse error '%U'", format_unformat_error, i);
21904           return -99;
21905         }
21906     }
21907
21908   if (parent_if_index == ~0)
21909     {
21910       errmsg ("missing interface name or sw_if_index");
21911       return -99;
21912     }
21913   if (mac_set == 0)
21914     {
21915       errmsg ("missing remote mac address");
21916       return -99;
21917     }
21918
21919   M (P2P_ETHERNET_DEL, mp);
21920   mp->parent_if_index = ntohl (parent_if_index);
21921   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21922
21923   S (mp);
21924   W (ret);
21925   return ret;
21926 }
21927
21928 static int
21929 api_lldp_config (vat_main_t * vam)
21930 {
21931   unformat_input_t *i = vam->input;
21932   vl_api_lldp_config_t *mp;
21933   int tx_hold = 0;
21934   int tx_interval = 0;
21935   u8 *sys_name = NULL;
21936   int ret;
21937
21938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21939     {
21940       if (unformat (i, "system-name %s", &sys_name))
21941         ;
21942       else if (unformat (i, "tx-hold %d", &tx_hold))
21943         ;
21944       else if (unformat (i, "tx-interval %d", &tx_interval))
21945         ;
21946       else
21947         {
21948           clib_warning ("parse error '%U'", format_unformat_error, i);
21949           return -99;
21950         }
21951     }
21952
21953   vec_add1 (sys_name, 0);
21954
21955   M (LLDP_CONFIG, mp);
21956   mp->tx_hold = htonl (tx_hold);
21957   mp->tx_interval = htonl (tx_interval);
21958   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21959   vec_free (sys_name);
21960
21961   S (mp);
21962   W (ret);
21963   return ret;
21964 }
21965
21966 static int
21967 api_sw_interface_set_lldp (vat_main_t * vam)
21968 {
21969   unformat_input_t *i = vam->input;
21970   vl_api_sw_interface_set_lldp_t *mp;
21971   u32 sw_if_index = ~0;
21972   u32 enable = 1;
21973   u8 *port_desc = NULL, *mgmt_oid = NULL;
21974   ip4_address_t ip4_addr;
21975   ip6_address_t ip6_addr;
21976   int ret;
21977
21978   memset (&ip4_addr, 0, sizeof (ip4_addr));
21979   memset (&ip6_addr, 0, sizeof (ip6_addr));
21980
21981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21982     {
21983       if (unformat (i, "disable"))
21984         enable = 0;
21985       else
21986         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21987         ;
21988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21989         ;
21990       else if (unformat (i, "port-desc %s", &port_desc))
21991         ;
21992       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21993         ;
21994       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21995         ;
21996       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21997         ;
21998       else
21999         break;
22000     }
22001
22002   if (sw_if_index == ~0)
22003     {
22004       errmsg ("missing interface name or sw_if_index");
22005       return -99;
22006     }
22007
22008   /* Construct the API message */
22009   vec_add1 (port_desc, 0);
22010   vec_add1 (mgmt_oid, 0);
22011   M (SW_INTERFACE_SET_LLDP, mp);
22012   mp->sw_if_index = ntohl (sw_if_index);
22013   mp->enable = enable;
22014   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22015   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22016   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22017   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22018   vec_free (port_desc);
22019   vec_free (mgmt_oid);
22020
22021   S (mp);
22022   W (ret);
22023   return ret;
22024 }
22025
22026 static int
22027 api_tcp_configure_src_addresses (vat_main_t * vam)
22028 {
22029   vl_api_tcp_configure_src_addresses_t *mp;
22030   unformat_input_t *i = vam->input;
22031   ip4_address_t v4first, v4last;
22032   ip6_address_t v6first, v6last;
22033   u8 range_set = 0;
22034   u32 vrf_id = 0;
22035   int ret;
22036
22037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22038     {
22039       if (unformat (i, "%U - %U",
22040                     unformat_ip4_address, &v4first,
22041                     unformat_ip4_address, &v4last))
22042         {
22043           if (range_set)
22044             {
22045               errmsg ("one range per message (range already set)");
22046               return -99;
22047             }
22048           range_set = 1;
22049         }
22050       else if (unformat (i, "%U - %U",
22051                          unformat_ip6_address, &v6first,
22052                          unformat_ip6_address, &v6last))
22053         {
22054           if (range_set)
22055             {
22056               errmsg ("one range per message (range already set)");
22057               return -99;
22058             }
22059           range_set = 2;
22060         }
22061       else if (unformat (i, "vrf %d", &vrf_id))
22062         ;
22063       else
22064         break;
22065     }
22066
22067   if (range_set == 0)
22068     {
22069       errmsg ("address range not set");
22070       return -99;
22071     }
22072
22073   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22074   mp->vrf_id = ntohl (vrf_id);
22075   /* ipv6? */
22076   if (range_set == 2)
22077     {
22078       mp->is_ipv6 = 1;
22079       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22080       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22081     }
22082   else
22083     {
22084       mp->is_ipv6 = 0;
22085       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22086       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22087     }
22088   S (mp);
22089   W (ret);
22090   return ret;
22091 }
22092
22093 static void vl_api_app_namespace_add_del_reply_t_handler
22094   (vl_api_app_namespace_add_del_reply_t * mp)
22095 {
22096   vat_main_t *vam = &vat_main;
22097   i32 retval = ntohl (mp->retval);
22098   if (vam->async_mode)
22099     {
22100       vam->async_errors += (retval < 0);
22101     }
22102   else
22103     {
22104       vam->retval = retval;
22105       if (retval == 0)
22106         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22107       vam->result_ready = 1;
22108     }
22109 }
22110
22111 static void vl_api_app_namespace_add_del_reply_t_handler_json
22112   (vl_api_app_namespace_add_del_reply_t * mp)
22113 {
22114   vat_main_t *vam = &vat_main;
22115   vat_json_node_t node;
22116
22117   vat_json_init_object (&node);
22118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22119   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22120
22121   vat_json_print (vam->ofp, &node);
22122   vat_json_free (&node);
22123
22124   vam->retval = ntohl (mp->retval);
22125   vam->result_ready = 1;
22126 }
22127
22128 static int
22129 api_app_namespace_add_del (vat_main_t * vam)
22130 {
22131   vl_api_app_namespace_add_del_t *mp;
22132   unformat_input_t *i = vam->input;
22133   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22134   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22135   u64 secret;
22136   int ret;
22137
22138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22139     {
22140       if (unformat (i, "id %_%v%_", &ns_id))
22141         ;
22142       else if (unformat (i, "secret %lu", &secret))
22143         secret_set = 1;
22144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22145         sw_if_index_set = 1;
22146       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22147         ;
22148       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22149         ;
22150       else
22151         break;
22152     }
22153   if (!ns_id || !secret_set || !sw_if_index_set)
22154     {
22155       errmsg ("namespace id, secret and sw_if_index must be set");
22156       return -99;
22157     }
22158   if (vec_len (ns_id) > 64)
22159     {
22160       errmsg ("namespace id too long");
22161       return -99;
22162     }
22163   M (APP_NAMESPACE_ADD_DEL, mp);
22164
22165   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22166   mp->namespace_id_len = vec_len (ns_id);
22167   mp->secret = clib_host_to_net_u64 (secret);
22168   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22169   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22170   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22171   vec_free (ns_id);
22172   S (mp);
22173   W (ret);
22174   return ret;
22175 }
22176
22177 static int
22178 api_sock_init_shm (vat_main_t * vam)
22179 {
22180 #if VPP_API_TEST_BUILTIN == 0
22181   unformat_input_t *i = vam->input;
22182   vl_api_shm_elem_config_t *config = 0;
22183   u64 size = 64 << 20;
22184   int rv;
22185
22186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22187     {
22188       if (unformat (i, "size %U", unformat_memory_size, &size))
22189         ;
22190       else
22191         break;
22192     }
22193
22194   /*
22195    * Canned custom ring allocator config.
22196    * Should probably parse all of this
22197    */
22198   vec_validate (config, 6);
22199   config[0].type = VL_API_VLIB_RING;
22200   config[0].size = 256;
22201   config[0].count = 32;
22202
22203   config[1].type = VL_API_VLIB_RING;
22204   config[1].size = 1024;
22205   config[1].count = 16;
22206
22207   config[2].type = VL_API_VLIB_RING;
22208   config[2].size = 4096;
22209   config[2].count = 2;
22210
22211   config[3].type = VL_API_CLIENT_RING;
22212   config[3].size = 256;
22213   config[3].count = 32;
22214
22215   config[4].type = VL_API_CLIENT_RING;
22216   config[4].size = 1024;
22217   config[4].count = 16;
22218
22219   config[5].type = VL_API_CLIENT_RING;
22220   config[5].size = 4096;
22221   config[5].count = 2;
22222
22223   config[6].type = VL_API_QUEUE;
22224   config[6].count = 128;
22225   config[6].size = sizeof (uword);
22226
22227   rv = vl_socket_client_init_shm (config);
22228   if (!rv)
22229     vam->client_index_invalid = 1;
22230   return rv;
22231 #else
22232   return -99;
22233 #endif
22234 }
22235
22236 static int
22237 api_dns_enable_disable (vat_main_t * vam)
22238 {
22239   unformat_input_t *line_input = vam->input;
22240   vl_api_dns_enable_disable_t *mp;
22241   u8 enable_disable = 1;
22242   int ret;
22243
22244   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22245     {
22246       if (unformat (line_input, "disable"))
22247         enable_disable = 0;
22248       if (unformat (line_input, "enable"))
22249         enable_disable = 1;
22250       else
22251         break;
22252     }
22253
22254   /* Construct the API message */
22255   M (DNS_ENABLE_DISABLE, mp);
22256   mp->enable = enable_disable;
22257
22258   /* send it... */
22259   S (mp);
22260   /* Wait for the reply */
22261   W (ret);
22262   return ret;
22263 }
22264
22265 static int
22266 api_dns_resolve_name (vat_main_t * vam)
22267 {
22268   unformat_input_t *line_input = vam->input;
22269   vl_api_dns_resolve_name_t *mp;
22270   u8 *name = 0;
22271   int ret;
22272
22273   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22274     {
22275       if (unformat (line_input, "%s", &name))
22276         ;
22277       else
22278         break;
22279     }
22280
22281   if (vec_len (name) > 127)
22282     {
22283       errmsg ("name too long");
22284       return -99;
22285     }
22286
22287   /* Construct the API message */
22288   M (DNS_RESOLVE_NAME, mp);
22289   memcpy (mp->name, name, vec_len (name));
22290   vec_free (name);
22291
22292   /* send it... */
22293   S (mp);
22294   /* Wait for the reply */
22295   W (ret);
22296   return ret;
22297 }
22298
22299 static int
22300 api_dns_resolve_ip (vat_main_t * vam)
22301 {
22302   unformat_input_t *line_input = vam->input;
22303   vl_api_dns_resolve_ip_t *mp;
22304   int is_ip6 = -1;
22305   ip4_address_t addr4;
22306   ip6_address_t addr6;
22307   int ret;
22308
22309   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22310     {
22311       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22312         is_ip6 = 1;
22313       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22314         is_ip6 = 0;
22315       else
22316         break;
22317     }
22318
22319   if (is_ip6 == -1)
22320     {
22321       errmsg ("missing address");
22322       return -99;
22323     }
22324
22325   /* Construct the API message */
22326   M (DNS_RESOLVE_IP, mp);
22327   mp->is_ip6 = is_ip6;
22328   if (is_ip6)
22329     memcpy (mp->address, &addr6, sizeof (addr6));
22330   else
22331     memcpy (mp->address, &addr4, sizeof (addr4));
22332
22333   /* send it... */
22334   S (mp);
22335   /* Wait for the reply */
22336   W (ret);
22337   return ret;
22338 }
22339
22340 static int
22341 api_dns_name_server_add_del (vat_main_t * vam)
22342 {
22343   unformat_input_t *i = vam->input;
22344   vl_api_dns_name_server_add_del_t *mp;
22345   u8 is_add = 1;
22346   ip6_address_t ip6_server;
22347   ip4_address_t ip4_server;
22348   int ip6_set = 0;
22349   int ip4_set = 0;
22350   int ret = 0;
22351
22352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22353     {
22354       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22355         ip6_set = 1;
22356       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22357         ip4_set = 1;
22358       else if (unformat (i, "del"))
22359         is_add = 0;
22360       else
22361         {
22362           clib_warning ("parse error '%U'", format_unformat_error, i);
22363           return -99;
22364         }
22365     }
22366
22367   if (ip4_set && ip6_set)
22368     {
22369       errmsg ("Only one server address allowed per message");
22370       return -99;
22371     }
22372   if ((ip4_set + ip6_set) == 0)
22373     {
22374       errmsg ("Server address required");
22375       return -99;
22376     }
22377
22378   /* Construct the API message */
22379   M (DNS_NAME_SERVER_ADD_DEL, mp);
22380
22381   if (ip6_set)
22382     {
22383       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22384       mp->is_ip6 = 1;
22385     }
22386   else
22387     {
22388       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22389       mp->is_ip6 = 0;
22390     }
22391
22392   mp->is_add = is_add;
22393
22394   /* send it... */
22395   S (mp);
22396
22397   /* Wait for a reply, return good/bad news  */
22398   W (ret);
22399   return ret;
22400 }
22401
22402 static void
22403 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22404 {
22405   vat_main_t *vam = &vat_main;
22406
22407   if (mp->is_ip4)
22408     {
22409       print (vam->ofp,
22410              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22411              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22412              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22413              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22414              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22415              clib_net_to_host_u32 (mp->action_index), mp->tag);
22416     }
22417   else
22418     {
22419       print (vam->ofp,
22420              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22421              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22422              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22423              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22424              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22425              clib_net_to_host_u32 (mp->action_index), mp->tag);
22426     }
22427 }
22428
22429 static void
22430 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22431                                              mp)
22432 {
22433   vat_main_t *vam = &vat_main;
22434   vat_json_node_t *node = NULL;
22435   struct in6_addr ip6;
22436   struct in_addr ip4;
22437
22438   if (VAT_JSON_ARRAY != vam->json_tree.type)
22439     {
22440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22441       vat_json_init_array (&vam->json_tree);
22442     }
22443   node = vat_json_array_add (&vam->json_tree);
22444   vat_json_init_object (node);
22445
22446   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22447   vat_json_object_add_uint (node, "appns_index",
22448                             clib_net_to_host_u32 (mp->appns_index));
22449   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22450   vat_json_object_add_uint (node, "scope", mp->scope);
22451   vat_json_object_add_uint (node, "action_index",
22452                             clib_net_to_host_u32 (mp->action_index));
22453   vat_json_object_add_uint (node, "lcl_port",
22454                             clib_net_to_host_u16 (mp->lcl_port));
22455   vat_json_object_add_uint (node, "rmt_port",
22456                             clib_net_to_host_u16 (mp->rmt_port));
22457   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22458   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22459   vat_json_object_add_string_copy (node, "tag", mp->tag);
22460   if (mp->is_ip4)
22461     {
22462       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22463       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22464       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22465       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22466     }
22467   else
22468     {
22469       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22470       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22471       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22472       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22473     }
22474 }
22475
22476 static int
22477 api_session_rule_add_del (vat_main_t * vam)
22478 {
22479   vl_api_session_rule_add_del_t *mp;
22480   unformat_input_t *i = vam->input;
22481   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22482   u32 appns_index = 0, scope = 0;
22483   ip4_address_t lcl_ip4, rmt_ip4;
22484   ip6_address_t lcl_ip6, rmt_ip6;
22485   u8 is_ip4 = 1, conn_set = 0;
22486   u8 is_add = 1, *tag = 0;
22487   int ret;
22488
22489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22490     {
22491       if (unformat (i, "del"))
22492         is_add = 0;
22493       else if (unformat (i, "add"))
22494         ;
22495       else if (unformat (i, "proto tcp"))
22496         proto = 0;
22497       else if (unformat (i, "proto udp"))
22498         proto = 1;
22499       else if (unformat (i, "appns %d", &appns_index))
22500         ;
22501       else if (unformat (i, "scope %d", &scope))
22502         ;
22503       else if (unformat (i, "tag %_%v%_", &tag))
22504         ;
22505       else
22506         if (unformat
22507             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22508              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22509              &rmt_port))
22510         {
22511           is_ip4 = 1;
22512           conn_set = 1;
22513         }
22514       else
22515         if (unformat
22516             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22517              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22518              &rmt_port))
22519         {
22520           is_ip4 = 0;
22521           conn_set = 1;
22522         }
22523       else if (unformat (i, "action %d", &action))
22524         ;
22525       else
22526         break;
22527     }
22528   if (proto == ~0 || !conn_set || action == ~0)
22529     {
22530       errmsg ("transport proto, connection and action must be set");
22531       return -99;
22532     }
22533
22534   if (scope > 3)
22535     {
22536       errmsg ("scope should be 0-3");
22537       return -99;
22538     }
22539
22540   M (SESSION_RULE_ADD_DEL, mp);
22541
22542   mp->is_ip4 = is_ip4;
22543   mp->transport_proto = proto;
22544   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22545   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22546   mp->lcl_plen = lcl_plen;
22547   mp->rmt_plen = rmt_plen;
22548   mp->action_index = clib_host_to_net_u32 (action);
22549   mp->appns_index = clib_host_to_net_u32 (appns_index);
22550   mp->scope = scope;
22551   mp->is_add = is_add;
22552   if (is_ip4)
22553     {
22554       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22555       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22556     }
22557   else
22558     {
22559       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22560       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22561     }
22562   if (tag)
22563     {
22564       clib_memcpy (mp->tag, tag, vec_len (tag));
22565       vec_free (tag);
22566     }
22567
22568   S (mp);
22569   W (ret);
22570   return ret;
22571 }
22572
22573 static int
22574 api_session_rules_dump (vat_main_t * vam)
22575 {
22576   vl_api_session_rules_dump_t *mp;
22577   vl_api_control_ping_t *mp_ping;
22578   int ret;
22579
22580   if (!vam->json_output)
22581     {
22582       print (vam->ofp, "%=20s", "Session Rules");
22583     }
22584
22585   M (SESSION_RULES_DUMP, mp);
22586   /* send it... */
22587   S (mp);
22588
22589   /* Use a control ping for synchronization */
22590   MPING (CONTROL_PING, mp_ping);
22591   S (mp_ping);
22592
22593   /* Wait for a reply... */
22594   W (ret);
22595   return ret;
22596 }
22597
22598 static int
22599 api_ip_container_proxy_add_del (vat_main_t * vam)
22600 {
22601   vl_api_ip_container_proxy_add_del_t *mp;
22602   unformat_input_t *i = vam->input;
22603   u32 plen = ~0, sw_if_index = ~0;
22604   ip4_address_t ip4;
22605   ip6_address_t ip6;
22606   u8 is_ip4 = 1;
22607   u8 is_add = 1;
22608   int ret;
22609
22610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22611     {
22612       if (unformat (i, "del"))
22613         is_add = 0;
22614       else if (unformat (i, "add"))
22615         ;
22616       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22617         {
22618           is_ip4 = 1;
22619           plen = 32;
22620         }
22621       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22622         {
22623           is_ip4 = 0;
22624           plen = 128;
22625         }
22626       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22627         ;
22628       else
22629         break;
22630     }
22631   if (sw_if_index == ~0 || plen == ~0)
22632     {
22633       errmsg ("address and sw_if_index must be set");
22634       return -99;
22635     }
22636
22637   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22638
22639   mp->is_ip4 = is_ip4;
22640   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22641   mp->plen = plen;
22642   mp->is_add = is_add;
22643   if (is_ip4)
22644     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22645   else
22646     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22647
22648   S (mp);
22649   W (ret);
22650   return ret;
22651 }
22652
22653 static int
22654 api_qos_record_enable_disable (vat_main_t * vam)
22655 {
22656   unformat_input_t *i = vam->input;
22657   vl_api_qos_record_enable_disable_t *mp;
22658   u32 sw_if_index, qs = 0xff;
22659   u8 sw_if_index_set = 0;
22660   u8 enable = 1;
22661   int ret;
22662
22663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22664     {
22665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22666         sw_if_index_set = 1;
22667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22668         sw_if_index_set = 1;
22669       else if (unformat (i, "%U", unformat_qos_source, &qs))
22670         ;
22671       else if (unformat (i, "disable"))
22672         enable = 0;
22673       else
22674         {
22675           clib_warning ("parse error '%U'", format_unformat_error, i);
22676           return -99;
22677         }
22678     }
22679
22680   if (sw_if_index_set == 0)
22681     {
22682       errmsg ("missing interface name or sw_if_index");
22683       return -99;
22684     }
22685   if (qs == 0xff)
22686     {
22687       errmsg ("input location must be specified");
22688       return -99;
22689     }
22690
22691   M (QOS_RECORD_ENABLE_DISABLE, mp);
22692
22693   mp->sw_if_index = ntohl (sw_if_index);
22694   mp->input_source = qs;
22695   mp->enable = enable;
22696
22697   S (mp);
22698   W (ret);
22699   return ret;
22700 }
22701
22702
22703 static int
22704 q_or_quit (vat_main_t * vam)
22705 {
22706 #if VPP_API_TEST_BUILTIN == 0
22707   longjmp (vam->jump_buf, 1);
22708 #endif
22709   return 0;                     /* not so much */
22710 }
22711
22712 static int
22713 q (vat_main_t * vam)
22714 {
22715   return q_or_quit (vam);
22716 }
22717
22718 static int
22719 quit (vat_main_t * vam)
22720 {
22721   return q_or_quit (vam);
22722 }
22723
22724 static int
22725 comment (vat_main_t * vam)
22726 {
22727   return 0;
22728 }
22729
22730 static int
22731 statseg (vat_main_t * vam)
22732 {
22733   ssvm_private_t *ssvmp = &vam->stat_segment;
22734   ssvm_shared_header_t *shared_header = ssvmp->sh;
22735   vlib_counter_t **counters;
22736   u64 thread0_index1_packets;
22737   u64 thread0_index1_bytes;
22738   f64 vector_rate, input_rate;
22739   uword *p;
22740
22741   uword *counter_vector_by_name;
22742   if (vam->stat_segment_lockp == 0)
22743     {
22744       errmsg ("Stat segment not mapped...");
22745       return -99;
22746     }
22747
22748   /* look up "/if/rx for sw_if_index 1 as a test */
22749
22750   clib_spinlock_lock (vam->stat_segment_lockp);
22751
22752   counter_vector_by_name = (uword *) shared_header->opaque[1];
22753
22754   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22755   if (p == 0)
22756     {
22757       clib_spinlock_unlock (vam->stat_segment_lockp);
22758       errmsg ("/if/tx not found?");
22759       return -99;
22760     }
22761
22762   /* Fish per-thread vector of combined counters from shared memory */
22763   counters = (vlib_counter_t **) p[0];
22764
22765   if (vec_len (counters[0]) < 2)
22766     {
22767       clib_spinlock_unlock (vam->stat_segment_lockp);
22768       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22769       return -99;
22770     }
22771
22772   /* Read thread 0 sw_if_index 1 counter */
22773   thread0_index1_packets = counters[0][1].packets;
22774   thread0_index1_bytes = counters[0][1].bytes;
22775
22776   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22777   if (p == 0)
22778     {
22779       clib_spinlock_unlock (vam->stat_segment_lockp);
22780       errmsg ("vector_rate not found?");
22781       return -99;
22782     }
22783
22784   vector_rate = *(f64 *) (p[0]);
22785   p = hash_get_mem (counter_vector_by_name, "input_rate");
22786   if (p == 0)
22787     {
22788       clib_spinlock_unlock (vam->stat_segment_lockp);
22789       errmsg ("input_rate not found?");
22790       return -99;
22791     }
22792   input_rate = *(f64 *) (p[0]);
22793
22794   clib_spinlock_unlock (vam->stat_segment_lockp);
22795
22796   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22797          vector_rate, input_rate);
22798   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22799          thread0_index1_packets, thread0_index1_bytes);
22800
22801   return 0;
22802 }
22803
22804 static int
22805 cmd_cmp (void *a1, void *a2)
22806 {
22807   u8 **c1 = a1;
22808   u8 **c2 = a2;
22809
22810   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22811 }
22812
22813 static int
22814 help (vat_main_t * vam)
22815 {
22816   u8 **cmds = 0;
22817   u8 *name = 0;
22818   hash_pair_t *p;
22819   unformat_input_t *i = vam->input;
22820   int j;
22821
22822   if (unformat (i, "%s", &name))
22823     {
22824       uword *hs;
22825
22826       vec_add1 (name, 0);
22827
22828       hs = hash_get_mem (vam->help_by_name, name);
22829       if (hs)
22830         print (vam->ofp, "usage: %s %s", name, hs[0]);
22831       else
22832         print (vam->ofp, "No such msg / command '%s'", name);
22833       vec_free (name);
22834       return 0;
22835     }
22836
22837   print (vam->ofp, "Help is available for the following:");
22838
22839     /* *INDENT-OFF* */
22840     hash_foreach_pair (p, vam->function_by_name,
22841     ({
22842       vec_add1 (cmds, (u8 *)(p->key));
22843     }));
22844     /* *INDENT-ON* */
22845
22846   vec_sort_with_function (cmds, cmd_cmp);
22847
22848   for (j = 0; j < vec_len (cmds); j++)
22849     print (vam->ofp, "%s", cmds[j]);
22850
22851   vec_free (cmds);
22852   return 0;
22853 }
22854
22855 static int
22856 set (vat_main_t * vam)
22857 {
22858   u8 *name = 0, *value = 0;
22859   unformat_input_t *i = vam->input;
22860
22861   if (unformat (i, "%s", &name))
22862     {
22863       /* The input buffer is a vector, not a string. */
22864       value = vec_dup (i->buffer);
22865       vec_delete (value, i->index, 0);
22866       /* Almost certainly has a trailing newline */
22867       if (value[vec_len (value) - 1] == '\n')
22868         value[vec_len (value) - 1] = 0;
22869       /* Make sure it's a proper string, one way or the other */
22870       vec_add1 (value, 0);
22871       (void) clib_macro_set_value (&vam->macro_main,
22872                                    (char *) name, (char *) value);
22873     }
22874   else
22875     errmsg ("usage: set <name> <value>");
22876
22877   vec_free (name);
22878   vec_free (value);
22879   return 0;
22880 }
22881
22882 static int
22883 unset (vat_main_t * vam)
22884 {
22885   u8 *name = 0;
22886
22887   if (unformat (vam->input, "%s", &name))
22888     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22889       errmsg ("unset: %s wasn't set", name);
22890   vec_free (name);
22891   return 0;
22892 }
22893
22894 typedef struct
22895 {
22896   u8 *name;
22897   u8 *value;
22898 } macro_sort_t;
22899
22900
22901 static int
22902 macro_sort_cmp (void *a1, void *a2)
22903 {
22904   macro_sort_t *s1 = a1;
22905   macro_sort_t *s2 = a2;
22906
22907   return strcmp ((char *) (s1->name), (char *) (s2->name));
22908 }
22909
22910 static int
22911 dump_macro_table (vat_main_t * vam)
22912 {
22913   macro_sort_t *sort_me = 0, *sm;
22914   int i;
22915   hash_pair_t *p;
22916
22917     /* *INDENT-OFF* */
22918     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22919     ({
22920       vec_add2 (sort_me, sm, 1);
22921       sm->name = (u8 *)(p->key);
22922       sm->value = (u8 *) (p->value[0]);
22923     }));
22924     /* *INDENT-ON* */
22925
22926   vec_sort_with_function (sort_me, macro_sort_cmp);
22927
22928   if (vec_len (sort_me))
22929     print (vam->ofp, "%-15s%s", "Name", "Value");
22930   else
22931     print (vam->ofp, "The macro table is empty...");
22932
22933   for (i = 0; i < vec_len (sort_me); i++)
22934     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22935   return 0;
22936 }
22937
22938 static int
22939 dump_node_table (vat_main_t * vam)
22940 {
22941   int i, j;
22942   vlib_node_t *node, *next_node;
22943
22944   if (vec_len (vam->graph_nodes) == 0)
22945     {
22946       print (vam->ofp, "Node table empty, issue get_node_graph...");
22947       return 0;
22948     }
22949
22950   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22951     {
22952       node = vam->graph_nodes[0][i];
22953       print (vam->ofp, "[%d] %s", i, node->name);
22954       for (j = 0; j < vec_len (node->next_nodes); j++)
22955         {
22956           if (node->next_nodes[j] != ~0)
22957             {
22958               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22959               print (vam->ofp, "  [%d] %s", j, next_node->name);
22960             }
22961         }
22962     }
22963   return 0;
22964 }
22965
22966 static int
22967 value_sort_cmp (void *a1, void *a2)
22968 {
22969   name_sort_t *n1 = a1;
22970   name_sort_t *n2 = a2;
22971
22972   if (n1->value < n2->value)
22973     return -1;
22974   if (n1->value > n2->value)
22975     return 1;
22976   return 0;
22977 }
22978
22979
22980 static int
22981 dump_msg_api_table (vat_main_t * vam)
22982 {
22983   api_main_t *am = &api_main;
22984   name_sort_t *nses = 0, *ns;
22985   hash_pair_t *hp;
22986   int i;
22987
22988   /* *INDENT-OFF* */
22989   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22990   ({
22991     vec_add2 (nses, ns, 1);
22992     ns->name = (u8 *)(hp->key);
22993     ns->value = (u32) hp->value[0];
22994   }));
22995   /* *INDENT-ON* */
22996
22997   vec_sort_with_function (nses, value_sort_cmp);
22998
22999   for (i = 0; i < vec_len (nses); i++)
23000     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23001   vec_free (nses);
23002   return 0;
23003 }
23004
23005 static int
23006 get_msg_id (vat_main_t * vam)
23007 {
23008   u8 *name_and_crc;
23009   u32 message_index;
23010
23011   if (unformat (vam->input, "%s", &name_and_crc))
23012     {
23013       message_index = vl_msg_api_get_msg_index (name_and_crc);
23014       if (message_index == ~0)
23015         {
23016           print (vam->ofp, " '%s' not found", name_and_crc);
23017           return 0;
23018         }
23019       print (vam->ofp, " '%s' has message index %d",
23020              name_and_crc, message_index);
23021       return 0;
23022     }
23023   errmsg ("name_and_crc required...");
23024   return 0;
23025 }
23026
23027 static int
23028 search_node_table (vat_main_t * vam)
23029 {
23030   unformat_input_t *line_input = vam->input;
23031   u8 *node_to_find;
23032   int j;
23033   vlib_node_t *node, *next_node;
23034   uword *p;
23035
23036   if (vam->graph_node_index_by_name == 0)
23037     {
23038       print (vam->ofp, "Node table empty, issue get_node_graph...");
23039       return 0;
23040     }
23041
23042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23043     {
23044       if (unformat (line_input, "%s", &node_to_find))
23045         {
23046           vec_add1 (node_to_find, 0);
23047           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23048           if (p == 0)
23049             {
23050               print (vam->ofp, "%s not found...", node_to_find);
23051               goto out;
23052             }
23053           node = vam->graph_nodes[0][p[0]];
23054           print (vam->ofp, "[%d] %s", p[0], node->name);
23055           for (j = 0; j < vec_len (node->next_nodes); j++)
23056             {
23057               if (node->next_nodes[j] != ~0)
23058                 {
23059                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23060                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23061                 }
23062             }
23063         }
23064
23065       else
23066         {
23067           clib_warning ("parse error '%U'", format_unformat_error,
23068                         line_input);
23069           return -99;
23070         }
23071
23072     out:
23073       vec_free (node_to_find);
23074
23075     }
23076
23077   return 0;
23078 }
23079
23080
23081 static int
23082 script (vat_main_t * vam)
23083 {
23084 #if (VPP_API_TEST_BUILTIN==0)
23085   u8 *s = 0;
23086   char *save_current_file;
23087   unformat_input_t save_input;
23088   jmp_buf save_jump_buf;
23089   u32 save_line_number;
23090
23091   FILE *new_fp, *save_ifp;
23092
23093   if (unformat (vam->input, "%s", &s))
23094     {
23095       new_fp = fopen ((char *) s, "r");
23096       if (new_fp == 0)
23097         {
23098           errmsg ("Couldn't open script file %s", s);
23099           vec_free (s);
23100           return -99;
23101         }
23102     }
23103   else
23104     {
23105       errmsg ("Missing script name");
23106       return -99;
23107     }
23108
23109   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23110   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23111   save_ifp = vam->ifp;
23112   save_line_number = vam->input_line_number;
23113   save_current_file = (char *) vam->current_file;
23114
23115   vam->input_line_number = 0;
23116   vam->ifp = new_fp;
23117   vam->current_file = s;
23118   do_one_file (vam);
23119
23120   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23121   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23122   vam->ifp = save_ifp;
23123   vam->input_line_number = save_line_number;
23124   vam->current_file = (u8 *) save_current_file;
23125   vec_free (s);
23126
23127   return 0;
23128 #else
23129   clib_warning ("use the exec command...");
23130   return -99;
23131 #endif
23132 }
23133
23134 static int
23135 echo (vat_main_t * vam)
23136 {
23137   print (vam->ofp, "%v", vam->input->buffer);
23138   return 0;
23139 }
23140
23141 /* List of API message constructors, CLI names map to api_xxx */
23142 #define foreach_vpe_api_msg                                             \
23143 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23144 _(sw_interface_dump,"")                                                 \
23145 _(sw_interface_set_flags,                                               \
23146   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23147 _(sw_interface_add_del_address,                                         \
23148   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23149 _(sw_interface_set_rx_mode,                                             \
23150   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23151 _(sw_interface_set_table,                                               \
23152   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23153 _(sw_interface_set_mpls_enable,                                         \
23154   "<intfc> | sw_if_index [disable | dis]")                              \
23155 _(sw_interface_set_vpath,                                               \
23156   "<intfc> | sw_if_index <id> enable | disable")                        \
23157 _(sw_interface_set_vxlan_bypass,                                        \
23158   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23159 _(sw_interface_set_geneve_bypass,                                       \
23160   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23161 _(sw_interface_set_l2_xconnect,                                         \
23162   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23163   "enable | disable")                                                   \
23164 _(sw_interface_set_l2_bridge,                                           \
23165   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23166   "[shg <split-horizon-group>] [bvi]\n"                                 \
23167   "enable | disable")                                                   \
23168 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23169 _(bridge_domain_add_del,                                                \
23170   "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") \
23171 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23172 _(l2fib_add_del,                                                        \
23173   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23174 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23175 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23176 _(l2_flags,                                                             \
23177   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23178 _(bridge_flags,                                                         \
23179   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23180 _(tap_connect,                                                          \
23181   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23182 _(tap_modify,                                                           \
23183   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23184 _(tap_delete,                                                           \
23185   "<vpp-if-name> | sw_if_index <id>")                                   \
23186 _(sw_interface_tap_dump, "")                                            \
23187 _(tap_create_v2,                                                        \
23188   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23189 _(tap_delete_v2,                                                        \
23190   "<vpp-if-name> | sw_if_index <id>")                                   \
23191 _(sw_interface_tap_v2_dump, "")                                         \
23192 _(bond_create,                                                          \
23193   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23194   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23195 _(bond_delete,                                                          \
23196   "<vpp-if-name> | sw_if_index <id>")                                   \
23197 _(bond_enslave,                                                         \
23198   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23199 _(bond_detach_slave,                                                    \
23200   "sw_if_index <n>")                                                    \
23201 _(sw_interface_bond_dump, "")                                           \
23202 _(sw_interface_slave_dump,                                              \
23203   "<vpp-if-name> | sw_if_index <id>")                                   \
23204 _(ip_table_add_del,                                                     \
23205   "table-id <n> [ipv6]\n")                                              \
23206 _(ip_add_del_route,                                                     \
23207   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23208   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23209   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23210   "[multipath] [count <n>]")                                            \
23211 _(ip_mroute_add_del,                                                    \
23212   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23213   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23214 _(mpls_table_add_del,                                                   \
23215   "table-id <n>\n")                                                     \
23216 _(mpls_route_add_del,                                                   \
23217   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23218   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23219   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23220   "[multipath] [count <n>]")                                            \
23221 _(mpls_ip_bind_unbind,                                                  \
23222   "<label> <addr/len>")                                                 \
23223 _(mpls_tunnel_add_del,                                                  \
23224   " via <addr> [table-id <n>]\n"                                        \
23225   "sw_if_index <id>] [l2]  [del]")                                      \
23226 _(bier_table_add_del,                                                   \
23227   "<label> <sub-domain> <set> <bsl> [del]")                             \
23228 _(bier_route_add_del,                                                   \
23229   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23230   "[<intfc> | sw_if_index <id>]"                                        \
23231   "[weight <n>] [del] [multipath]")                                     \
23232 _(proxy_arp_add_del,                                                    \
23233   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23234 _(proxy_arp_intfc_enable_disable,                                       \
23235   "<intfc> | sw_if_index <id> enable | disable")                        \
23236 _(sw_interface_set_unnumbered,                                          \
23237   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23238 _(ip_neighbor_add_del,                                                  \
23239   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23240   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23241 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23242 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23243   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23244   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23245   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23246 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23247 _(reset_fib, "vrf <n> [ipv6]")                                          \
23248 _(dhcp_proxy_config,                                                    \
23249   "svr <v46-address> src <v46-address>\n"                               \
23250    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23251 _(dhcp_proxy_set_vss,                                                   \
23252   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23253 _(dhcp_proxy_dump, "ip6")                                               \
23254 _(dhcp_client_config,                                                   \
23255   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23256 _(set_ip_flow_hash,                                                     \
23257   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23258 _(sw_interface_ip6_enable_disable,                                      \
23259   "<intfc> | sw_if_index <id> enable | disable")                        \
23260 _(sw_interface_ip6_set_link_local_address,                              \
23261   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23262 _(ip6nd_proxy_add_del,                                                  \
23263   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23264 _(ip6nd_proxy_dump, "")                                                 \
23265 _(sw_interface_ip6nd_ra_prefix,                                         \
23266   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23267   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23268   "[nolink] [isno]")                                                    \
23269 _(sw_interface_ip6nd_ra_config,                                         \
23270   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23271   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23272   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23273 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23274 _(l2_patch_add_del,                                                     \
23275   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23276   "enable | disable")                                                   \
23277 _(sr_localsid_add_del,                                                  \
23278   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23279   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23280 _(classify_add_del_table,                                               \
23281   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23282   " [del] [del-chain] mask <mask-value>\n"                              \
23283   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23284   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23285 _(classify_add_del_session,                                             \
23286   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23287   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23288   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23289   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23290 _(classify_set_interface_ip_table,                                      \
23291   "<intfc> | sw_if_index <nn> table <nn>")                              \
23292 _(classify_set_interface_l2_tables,                                     \
23293   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23294   "  [other-table <nn>]")                                               \
23295 _(get_node_index, "node <node-name")                                    \
23296 _(add_node_next, "node <node-name> next <next-node-name>")              \
23297 _(l2tpv3_create_tunnel,                                                 \
23298   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23299   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23300   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23301 _(l2tpv3_set_tunnel_cookies,                                            \
23302   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23303   "[new_remote_cookie <nn>]\n")                                         \
23304 _(l2tpv3_interface_enable_disable,                                      \
23305   "<intfc> | sw_if_index <nn> enable | disable")                        \
23306 _(l2tpv3_set_lookup_key,                                                \
23307   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23308 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23309 _(vxlan_offload_rx,                                                     \
23310   "hw { <interface name> | hw_if_index <nn>} "                          \
23311   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23312 _(vxlan_add_del_tunnel,                                                 \
23313   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23314   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23315   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23316 _(geneve_add_del_tunnel,                                                \
23317   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23318   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23319   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23320 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23321 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23322 _(gre_add_del_tunnel,                                                   \
23323   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23324   "[teb | erspan <session-id>] [del]")                                  \
23325 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23326 _(l2_fib_clear_table, "")                                               \
23327 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23328 _(l2_interface_vlan_tag_rewrite,                                        \
23329   "<intfc> | sw_if_index <nn> \n"                                       \
23330   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23331   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23332 _(create_vhost_user_if,                                                 \
23333         "socket <filename> [server] [renumber <dev_instance>] "         \
23334         "[mac <mac_address>]")                                          \
23335 _(modify_vhost_user_if,                                                 \
23336         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23337         "[server] [renumber <dev_instance>]")                           \
23338 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23339 _(sw_interface_vhost_user_dump, "")                                     \
23340 _(show_version, "")                                                     \
23341 _(vxlan_gpe_add_del_tunnel,                                             \
23342   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23343   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23344   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23345   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23346 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23347 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23348 _(interface_name_renumber,                                              \
23349   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23350 _(input_acl_set_interface,                                              \
23351   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23352   "  [l2-table <nn>] [del]")                                            \
23353 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23354 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23355   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23356 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23357 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23358 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23359 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23360 _(ip_dump, "ipv4 | ipv6")                                               \
23361 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23362 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23363   "  spid_id <n> ")                                                     \
23364 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23365   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23366   "  integ_alg <alg> integ_key <hex>")                                  \
23367 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23368   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23369   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23370   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23371 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23372 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23373   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23374   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23375   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23376   "  [instance <n>]")     \
23377 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23378 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23379   "  <alg> <hex>\n")                                                    \
23380 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23381 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23382 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23383   "(auth_data 0x<data> | auth_data <data>)")                            \
23384 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23385   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23386 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23387   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23388   "(local|remote)")                                                     \
23389 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23390 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23391 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23392 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23393 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23394 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23395 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23396 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23397 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23398 _(delete_loopback,"sw_if_index <nn>")                                   \
23399 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23400 _(want_interface_events,  "enable|disable")                             \
23401 _(want_stats,"enable|disable")                                          \
23402 _(get_first_msg_id, "client <name>")                                    \
23403 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23404 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23405   "fib-id <nn> [ip4][ip6][default]")                                    \
23406 _(get_node_graph, " ")                                                  \
23407 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23408 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23409 _(ioam_disable, "")                                                     \
23410 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23411                             " sw_if_index <sw_if_index> p <priority> "  \
23412                             "w <weight>] [del]")                        \
23413 _(one_add_del_locator, "locator-set <locator_name> "                    \
23414                         "iface <intf> | sw_if_index <sw_if_index> "     \
23415                         "p <priority> w <weight> [del]")                \
23416 _(one_add_del_local_eid,"vni <vni> eid "                                \
23417                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23418                          "locator-set <locator_name> [del]"             \
23419                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23420 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23421 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23422 _(one_enable_disable, "enable|disable")                                 \
23423 _(one_map_register_enable_disable, "enable|disable")                    \
23424 _(one_map_register_fallback_threshold, "<value>")                       \
23425 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23426 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23427                                "[seid <seid>] "                         \
23428                                "rloc <locator> p <prio> "               \
23429                                "w <weight> [rloc <loc> ... ] "          \
23430                                "action <action> [del-all]")             \
23431 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23432                           "<local-eid>")                                \
23433 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23434 _(one_use_petr, "ip-address> | disable")                                \
23435 _(one_map_request_mode, "src-dst|dst-only")                             \
23436 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23437 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23438 _(one_locator_set_dump, "[local | remote]")                             \
23439 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23440 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23441                        "[local] | [remote]")                            \
23442 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23443 _(one_ndp_bd_get, "")                                                   \
23444 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23445 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23446 _(one_l2_arp_bd_get, "")                                                \
23447 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23448 _(one_stats_enable_disable, "enable|disalbe")                           \
23449 _(show_one_stats_enable_disable, "")                                    \
23450 _(one_eid_table_vni_dump, "")                                           \
23451 _(one_eid_table_map_dump, "l2|l3")                                      \
23452 _(one_map_resolver_dump, "")                                            \
23453 _(one_map_server_dump, "")                                              \
23454 _(one_adjacencies_get, "vni <vni>")                                     \
23455 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23456 _(show_one_rloc_probe_state, "")                                        \
23457 _(show_one_map_register_state, "")                                      \
23458 _(show_one_status, "")                                                  \
23459 _(one_stats_dump, "")                                                   \
23460 _(one_stats_flush, "")                                                  \
23461 _(one_get_map_request_itr_rlocs, "")                                    \
23462 _(one_map_register_set_ttl, "<ttl>")                                    \
23463 _(one_set_transport_protocol, "udp|api")                                \
23464 _(one_get_transport_protocol, "")                                       \
23465 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23466 _(one_show_xtr_mode, "")                                                \
23467 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23468 _(one_show_pitr_mode, "")                                               \
23469 _(one_enable_disable_petr_mode, "enable|disable")                       \
23470 _(one_show_petr_mode, "")                                               \
23471 _(show_one_nsh_mapping, "")                                             \
23472 _(show_one_pitr, "")                                                    \
23473 _(show_one_use_petr, "")                                                \
23474 _(show_one_map_request_mode, "")                                        \
23475 _(show_one_map_register_ttl, "")                                        \
23476 _(show_one_map_register_fallback_threshold, "")                         \
23477 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23478                             " sw_if_index <sw_if_index> p <priority> "  \
23479                             "w <weight>] [del]")                        \
23480 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23481                         "iface <intf> | sw_if_index <sw_if_index> "     \
23482                         "p <priority> w <weight> [del]")                \
23483 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23484                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23485                          "locator-set <locator_name> [del]"             \
23486                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23487 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23488 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23489 _(lisp_enable_disable, "enable|disable")                                \
23490 _(lisp_map_register_enable_disable, "enable|disable")                   \
23491 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23492 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23493                                "[seid <seid>] "                         \
23494                                "rloc <locator> p <prio> "               \
23495                                "w <weight> [rloc <loc> ... ] "          \
23496                                "action <action> [del-all]")             \
23497 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23498                           "<local-eid>")                                \
23499 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23500 _(lisp_use_petr, "<ip-address> | disable")                              \
23501 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23502 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23503 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23504 _(lisp_locator_set_dump, "[local | remote]")                            \
23505 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23506 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23507                        "[local] | [remote]")                            \
23508 _(lisp_eid_table_vni_dump, "")                                          \
23509 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23510 _(lisp_map_resolver_dump, "")                                           \
23511 _(lisp_map_server_dump, "")                                             \
23512 _(lisp_adjacencies_get, "vni <vni>")                                    \
23513 _(gpe_fwd_entry_vnis_get, "")                                           \
23514 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23515 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23516                                 "[table <table-id>]")                   \
23517 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23518 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23519 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23520 _(gpe_get_encap_mode, "")                                               \
23521 _(lisp_gpe_add_del_iface, "up|down")                                    \
23522 _(lisp_gpe_enable_disable, "enable|disable")                            \
23523 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23524   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23525 _(show_lisp_rloc_probe_state, "")                                       \
23526 _(show_lisp_map_register_state, "")                                     \
23527 _(show_lisp_status, "")                                                 \
23528 _(lisp_get_map_request_itr_rlocs, "")                                   \
23529 _(show_lisp_pitr, "")                                                   \
23530 _(show_lisp_use_petr, "")                                               \
23531 _(show_lisp_map_request_mode, "")                                       \
23532 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23533 _(af_packet_delete, "name <host interface name>")                       \
23534 _(af_packet_dump, "")                                                   \
23535 _(policer_add_del, "name <policer name> <params> [del]")                \
23536 _(policer_dump, "[name <policer name>]")                                \
23537 _(policer_classify_set_interface,                                       \
23538   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23539   "  [l2-table <nn>] [del]")                                            \
23540 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23541 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23542     "[master|slave]")                                                   \
23543 _(netmap_delete, "name <interface name>")                               \
23544 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23545 _(mpls_fib_dump, "")                                                    \
23546 _(classify_table_ids, "")                                               \
23547 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23548 _(classify_table_info, "table_id <nn>")                                 \
23549 _(classify_session_dump, "table_id <nn>")                               \
23550 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23551     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23552     "[template_interval <nn>] [udp_checksum]")                          \
23553 _(ipfix_exporter_dump, "")                                              \
23554 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23555 _(ipfix_classify_stream_dump, "")                                       \
23556 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23557 _(ipfix_classify_table_dump, "")                                        \
23558 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23559 _(sw_interface_span_dump, "[l2]")                                           \
23560 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23561 _(pg_create_interface, "if_id <nn>")                                    \
23562 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23563 _(pg_enable_disable, "[stream <id>] disable")                           \
23564 _(ip_source_and_port_range_check_add_del,                               \
23565   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23566 _(ip_source_and_port_range_check_interface_add_del,                     \
23567   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23568   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23569 _(ipsec_gre_add_del_tunnel,                                             \
23570   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23571 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23572 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23573 _(l2_interface_pbb_tag_rewrite,                                         \
23574   "<intfc> | sw_if_index <nn> \n"                                       \
23575   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23576   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23577 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23578 _(flow_classify_set_interface,                                          \
23579   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23580 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23581 _(ip_fib_dump, "")                                                      \
23582 _(ip_mfib_dump, "")                                                     \
23583 _(ip6_fib_dump, "")                                                     \
23584 _(ip6_mfib_dump, "")                                                    \
23585 _(feature_enable_disable, "arc_name <arc_name> "                        \
23586   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23587 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23588 "[disable]")                                                            \
23589 _(l2_xconnect_dump, "")                                                 \
23590 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23591 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23592 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23593 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23594 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23595 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23596 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23597   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23598 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23599 _(sock_init_shm, "size <nnn>")                                          \
23600 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23601 _(dns_enable_disable, "[enable][disable]")                              \
23602 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23603 _(dns_resolve_name, "<hostname>")                                       \
23604 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23605 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23606 _(dns_resolve_name, "<hostname>")                                       \
23607 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23608   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23609 _(session_rules_dump, "")                                               \
23610 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23611 _(output_acl_set_interface,                                             \
23612   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23613   "  [l2-table <nn>] [del]")                                            \
23614 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23615
23616 /* List of command functions, CLI names map directly to functions */
23617 #define foreach_cli_function                                    \
23618 _(comment, "usage: comment <ignore-rest-of-line>")              \
23619 _(dump_interface_table, "usage: dump_interface_table")          \
23620 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23621 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23622 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23623 _(dump_stats_table, "usage: dump_stats_table")                  \
23624 _(dump_macro_table, "usage: dump_macro_table ")                 \
23625 _(dump_node_table, "usage: dump_node_table")                    \
23626 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23627 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23628 _(echo, "usage: echo <message>")                                \
23629 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23630 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23631 _(help, "usage: help")                                          \
23632 _(q, "usage: quit")                                             \
23633 _(quit, "usage: quit")                                          \
23634 _(search_node_table, "usage: search_node_table <name>...")      \
23635 _(set, "usage: set <variable-name> <value>")                    \
23636 _(script, "usage: script <file-name>")                          \
23637 _(statseg, "usage: statseg");                                   \
23638 _(unset, "usage: unset <variable-name>")
23639
23640 #define _(N,n)                                  \
23641     static void vl_api_##n##_t_handler_uni      \
23642     (vl_api_##n##_t * mp)                       \
23643     {                                           \
23644         vat_main_t * vam = &vat_main;           \
23645         if (vam->json_output) {                 \
23646             vl_api_##n##_t_handler_json(mp);    \
23647         } else {                                \
23648             vl_api_##n##_t_handler(mp);         \
23649         }                                       \
23650     }
23651 foreach_vpe_api_reply_msg;
23652 #if VPP_API_TEST_BUILTIN == 0
23653 foreach_standalone_reply_msg;
23654 #endif
23655 #undef _
23656
23657 void
23658 vat_api_hookup (vat_main_t * vam)
23659 {
23660 #define _(N,n)                                                  \
23661     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23662                            vl_api_##n##_t_handler_uni,          \
23663                            vl_noop_handler,                     \
23664                            vl_api_##n##_t_endian,               \
23665                            vl_api_##n##_t_print,                \
23666                            sizeof(vl_api_##n##_t), 1);
23667   foreach_vpe_api_reply_msg;
23668 #if VPP_API_TEST_BUILTIN == 0
23669   foreach_standalone_reply_msg;
23670 #endif
23671 #undef _
23672
23673 #if (VPP_API_TEST_BUILTIN==0)
23674   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23675
23676   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23677
23678   vam->function_by_name = hash_create_string (0, sizeof (uword));
23679
23680   vam->help_by_name = hash_create_string (0, sizeof (uword));
23681 #endif
23682
23683   /* API messages we can send */
23684 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23685   foreach_vpe_api_msg;
23686 #undef _
23687
23688   /* Help strings */
23689 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23690   foreach_vpe_api_msg;
23691 #undef _
23692
23693   /* CLI functions */
23694 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23695   foreach_cli_function;
23696 #undef _
23697
23698   /* Help strings */
23699 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23700   foreach_cli_function;
23701 #undef _
23702 }
23703
23704 #if VPP_API_TEST_BUILTIN
23705 static clib_error_t *
23706 vat_api_hookup_shim (vlib_main_t * vm)
23707 {
23708   vat_api_hookup (&vat_main);
23709   return 0;
23710 }
23711
23712 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23713 #endif
23714
23715 /*
23716  * fd.io coding-style-patch-verification: ON
23717  *
23718  * Local Variables:
23719  * eval: (c-set-style "gnu")
23720  * End:
23721  */