Trivial: Cleanup some typos.
[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 received with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_rx_placement_reply)                  \
5353 _(sw_interface_set_table_reply)                         \
5354 _(sw_interface_set_mpls_enable_reply)                   \
5355 _(sw_interface_set_vpath_reply)                         \
5356 _(sw_interface_set_vxlan_bypass_reply)                  \
5357 _(sw_interface_set_geneve_bypass_reply)                 \
5358 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5359 _(sw_interface_set_l2_bridge_reply)                     \
5360 _(bridge_domain_add_del_reply)                          \
5361 _(sw_interface_set_l2_xconnect_reply)                   \
5362 _(l2fib_add_del_reply)                                  \
5363 _(l2fib_flush_int_reply)                                \
5364 _(l2fib_flush_bd_reply)                                 \
5365 _(ip_add_del_route_reply)                               \
5366 _(ip_table_add_del_reply)                               \
5367 _(ip_mroute_add_del_reply)                              \
5368 _(mpls_route_add_del_reply)                             \
5369 _(mpls_table_add_del_reply)                             \
5370 _(mpls_ip_bind_unbind_reply)                            \
5371 _(bier_route_add_del_reply)                             \
5372 _(bier_table_add_del_reply)                             \
5373 _(proxy_arp_add_del_reply)                              \
5374 _(proxy_arp_intfc_enable_disable_reply)                 \
5375 _(sw_interface_set_unnumbered_reply)                    \
5376 _(ip_neighbor_add_del_reply)                            \
5377 _(oam_add_del_reply)                                    \
5378 _(reset_fib_reply)                                      \
5379 _(dhcp_proxy_config_reply)                              \
5380 _(dhcp_proxy_set_vss_reply)                             \
5381 _(dhcp_client_config_reply)                             \
5382 _(set_ip_flow_hash_reply)                               \
5383 _(sw_interface_ip6_enable_disable_reply)                \
5384 _(sw_interface_ip6_set_link_local_address_reply)        \
5385 _(ip6nd_proxy_add_del_reply)                            \
5386 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5387 _(sw_interface_ip6nd_ra_config_reply)                   \
5388 _(set_arp_neighbor_limit_reply)                         \
5389 _(l2_patch_add_del_reply)                               \
5390 _(sr_mpls_policy_add_reply)                             \
5391 _(sr_mpls_policy_mod_reply)                             \
5392 _(sr_mpls_policy_del_reply)                             \
5393 _(sr_policy_add_reply)                                  \
5394 _(sr_policy_mod_reply)                                  \
5395 _(sr_policy_del_reply)                                  \
5396 _(sr_localsid_add_del_reply)                            \
5397 _(sr_steering_add_del_reply)                            \
5398 _(classify_add_del_session_reply)                       \
5399 _(classify_set_interface_ip_table_reply)                \
5400 _(classify_set_interface_l2_tables_reply)               \
5401 _(l2tpv3_set_tunnel_cookies_reply)                      \
5402 _(l2tpv3_interface_enable_disable_reply)                \
5403 _(l2tpv3_set_lookup_key_reply)                          \
5404 _(l2_fib_clear_table_reply)                             \
5405 _(l2_interface_efp_filter_reply)                        \
5406 _(l2_interface_vlan_tag_rewrite_reply)                  \
5407 _(modify_vhost_user_if_reply)                           \
5408 _(delete_vhost_user_if_reply)                           \
5409 _(ip_probe_neighbor_reply)                              \
5410 _(ip_scan_neighbor_enable_disable_reply)                \
5411 _(want_ip4_arp_events_reply)                            \
5412 _(want_ip6_nd_events_reply)                             \
5413 _(want_l2_macs_events_reply)                            \
5414 _(input_acl_set_interface_reply)                        \
5415 _(ipsec_spd_add_del_reply)                              \
5416 _(ipsec_interface_add_del_spd_reply)                    \
5417 _(ipsec_spd_add_del_entry_reply)                        \
5418 _(ipsec_sad_add_del_entry_reply)                        \
5419 _(ipsec_sa_set_key_reply)                               \
5420 _(ipsec_tunnel_if_add_del_reply)                        \
5421 _(ipsec_tunnel_if_set_key_reply)                        \
5422 _(ipsec_tunnel_if_set_sa_reply)                         \
5423 _(ikev2_profile_add_del_reply)                          \
5424 _(ikev2_profile_set_auth_reply)                         \
5425 _(ikev2_profile_set_id_reply)                           \
5426 _(ikev2_profile_set_ts_reply)                           \
5427 _(ikev2_set_local_key_reply)                            \
5428 _(ikev2_set_responder_reply)                            \
5429 _(ikev2_set_ike_transforms_reply)                       \
5430 _(ikev2_set_esp_transforms_reply)                       \
5431 _(ikev2_set_sa_lifetime_reply)                          \
5432 _(ikev2_initiate_sa_init_reply)                         \
5433 _(ikev2_initiate_del_ike_sa_reply)                      \
5434 _(ikev2_initiate_del_child_sa_reply)                    \
5435 _(ikev2_initiate_rekey_child_sa_reply)                  \
5436 _(delete_loopback_reply)                                \
5437 _(bd_ip_mac_add_del_reply)                              \
5438 _(want_interface_events_reply)                          \
5439 _(want_stats_reply)                                     \
5440 _(cop_interface_enable_disable_reply)                   \
5441 _(cop_whitelist_enable_disable_reply)                   \
5442 _(sw_interface_clear_stats_reply)                       \
5443 _(ioam_enable_reply)                                    \
5444 _(ioam_disable_reply)                                   \
5445 _(one_add_del_locator_reply)                            \
5446 _(one_add_del_local_eid_reply)                          \
5447 _(one_add_del_remote_mapping_reply)                     \
5448 _(one_add_del_adjacency_reply)                          \
5449 _(one_add_del_map_resolver_reply)                       \
5450 _(one_add_del_map_server_reply)                         \
5451 _(one_enable_disable_reply)                             \
5452 _(one_rloc_probe_enable_disable_reply)                  \
5453 _(one_map_register_enable_disable_reply)                \
5454 _(one_map_register_set_ttl_reply)                       \
5455 _(one_set_transport_protocol_reply)                     \
5456 _(one_map_register_fallback_threshold_reply)            \
5457 _(one_pitr_set_locator_set_reply)                       \
5458 _(one_map_request_mode_reply)                           \
5459 _(one_add_del_map_request_itr_rlocs_reply)              \
5460 _(one_eid_table_add_del_map_reply)                      \
5461 _(one_use_petr_reply)                                   \
5462 _(one_stats_enable_disable_reply)                       \
5463 _(one_add_del_l2_arp_entry_reply)                       \
5464 _(one_add_del_ndp_entry_reply)                          \
5465 _(one_stats_flush_reply)                                \
5466 _(one_enable_disable_xtr_mode_reply)                    \
5467 _(one_enable_disable_pitr_mode_reply)                   \
5468 _(one_enable_disable_petr_mode_reply)                   \
5469 _(gpe_enable_disable_reply)                             \
5470 _(gpe_set_encap_mode_reply)                             \
5471 _(gpe_add_del_iface_reply)                              \
5472 _(gpe_add_del_native_fwd_rpath_reply)                   \
5473 _(af_packet_delete_reply)                               \
5474 _(policer_classify_set_interface_reply)                 \
5475 _(netmap_create_reply)                                  \
5476 _(netmap_delete_reply)                                  \
5477 _(set_ipfix_exporter_reply)                             \
5478 _(set_ipfix_classify_stream_reply)                      \
5479 _(ipfix_classify_table_add_del_reply)                   \
5480 _(flow_classify_set_interface_reply)                    \
5481 _(sw_interface_span_enable_disable_reply)               \
5482 _(pg_capture_reply)                                     \
5483 _(pg_enable_disable_reply)                              \
5484 _(ip_source_and_port_range_check_add_del_reply)         \
5485 _(ip_source_and_port_range_check_interface_add_del_reply)\
5486 _(delete_subif_reply)                                   \
5487 _(l2_interface_pbb_tag_rewrite_reply)                   \
5488 _(punt_reply)                                           \
5489 _(feature_enable_disable_reply)                         \
5490 _(sw_interface_tag_add_del_reply)                       \
5491 _(hw_interface_set_mtu_reply)                           \
5492 _(p2p_ethernet_add_reply)                               \
5493 _(p2p_ethernet_del_reply)                               \
5494 _(lldp_config_reply)                                    \
5495 _(sw_interface_set_lldp_reply)                          \
5496 _(tcp_configure_src_addresses_reply)                    \
5497 _(dns_enable_disable_reply)                             \
5498 _(dns_name_server_add_del_reply)                        \
5499 _(session_rule_add_del_reply)                           \
5500 _(ip_container_proxy_add_del_reply)                     \
5501 _(output_acl_set_interface_reply)                       \
5502 _(qos_record_enable_disable_reply)
5503
5504 #define _(n)                                    \
5505     static void vl_api_##n##_t_handler          \
5506     (vl_api_##n##_t * mp)                       \
5507     {                                           \
5508         vat_main_t * vam = &vat_main;           \
5509         i32 retval = ntohl(mp->retval);         \
5510         if (vam->async_mode) {                  \
5511             vam->async_errors += (retval < 0);  \
5512         } else {                                \
5513             vam->retval = retval;               \
5514             vam->result_ready = 1;              \
5515         }                                       \
5516     }
5517 foreach_standard_reply_retval_handler;
5518 #undef _
5519
5520 #define _(n)                                    \
5521     static void vl_api_##n##_t_handler_json     \
5522     (vl_api_##n##_t * mp)                       \
5523     {                                           \
5524         vat_main_t * vam = &vat_main;           \
5525         vat_json_node_t node;                   \
5526         vat_json_init_object(&node);            \
5527         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5528         vat_json_print(vam->ofp, &node);        \
5529         vam->retval = ntohl(mp->retval);        \
5530         vam->result_ready = 1;                  \
5531     }
5532 foreach_standard_reply_retval_handler;
5533 #undef _
5534
5535 /*
5536  * Table of message reply handlers, must include boilerplate handlers
5537  * we just generated
5538  */
5539
5540 #define foreach_vpe_api_reply_msg                                       \
5541 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5542 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5543 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5544 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5545 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5546 _(CLI_REPLY, cli_reply)                                                 \
5547 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5548 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5549   sw_interface_add_del_address_reply)                                   \
5550 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5551 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5552 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5553 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5554 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5555 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5556 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5557 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5558 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5559 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5560   sw_interface_set_l2_xconnect_reply)                                   \
5561 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5562   sw_interface_set_l2_bridge_reply)                                     \
5563 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5564 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5565 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5566 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5567 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5568 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5569 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5570 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5571 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5572 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5573 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5574 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5575 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5576 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5577 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5578 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5579 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5580 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5581 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5582 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5583 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5584 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5585 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5586 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5587 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5588 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5589 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5590 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5591 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5592 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5593 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5594   proxy_arp_intfc_enable_disable_reply)                                 \
5595 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5596 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5597   sw_interface_set_unnumbered_reply)                                    \
5598 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5599 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5600 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5601 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5602 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5603 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5604 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5605 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5606 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5607 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5608 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5609   sw_interface_ip6_enable_disable_reply)                                \
5610 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5611   sw_interface_ip6_set_link_local_address_reply)                        \
5612 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5613 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5614 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5615   sw_interface_ip6nd_ra_prefix_reply)                                   \
5616 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5617   sw_interface_ip6nd_ra_config_reply)                                   \
5618 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5619 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5620 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5621 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5622 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5623 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5624 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5625 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5626 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5627 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5628 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5629 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5630 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5631 classify_set_interface_ip_table_reply)                                  \
5632 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5633   classify_set_interface_l2_tables_reply)                               \
5634 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5635 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5636 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5637 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5638 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5639   l2tpv3_interface_enable_disable_reply)                                \
5640 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5641 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5642 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5643 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5644 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5645 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5646 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5647 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5648 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5649 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5650 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5651 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5652 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5653 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5654 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5655 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5656 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5657 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5658 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5659 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5660 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5661 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5662 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5663 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5664 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5665 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5666 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5667 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5668 _(L2_MACS_EVENT, l2_macs_event)                                         \
5669 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5670 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5671 _(IP_DETAILS, ip_details)                                               \
5672 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5673 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5674 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5675 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5676 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5677 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5678 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5679 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5680 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5681 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5682 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5683 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5684 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5685 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5686 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5687 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5688 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5689 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5690 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5691 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5692 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5693 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5694 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5695 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5696 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5697 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5698 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5699 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5700 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5701 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5702 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5703 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5704 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5705 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5706 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5707 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5708 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5709 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5710 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5711 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5712 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5713 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5714 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5715 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5716   one_map_register_enable_disable_reply)                                \
5717 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5718 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5719 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5720 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5721   one_map_register_fallback_threshold_reply)                            \
5722 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5723   one_rloc_probe_enable_disable_reply)                                  \
5724 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5725 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5726 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5727 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5728 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5729 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5730 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5731 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5732 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5733 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5734 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5735 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5736 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5737 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5738 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5739 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5740   show_one_stats_enable_disable_reply)                                  \
5741 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5742 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5743 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5744 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5745 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5746 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5747 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5748 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5749   one_enable_disable_pitr_mode_reply)                                   \
5750 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5751   one_enable_disable_petr_mode_reply)                                   \
5752 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5753 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5754 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5755 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5756 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5757 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5758 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5759 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5760 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5761 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5762 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5763 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5764   gpe_add_del_native_fwd_rpath_reply)                                   \
5765 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5766   gpe_fwd_entry_path_details)                                           \
5767 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5768 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5769   one_add_del_map_request_itr_rlocs_reply)                              \
5770 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5771   one_get_map_request_itr_rlocs_reply)                                  \
5772 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5773 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5774 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5775 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5776 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5777 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5778   show_one_map_register_state_reply)                                    \
5779 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5780 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5781   show_one_map_register_fallback_threshold_reply)                       \
5782 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5783 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5784 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5785 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5786 _(POLICER_DETAILS, policer_details)                                     \
5787 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5788 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5789 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5790 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5791 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5792 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5793 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5794 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5795 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5796 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5797 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5798 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5799 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5800 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5801 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5802 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5803 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5804 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5805 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5806 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5807 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5808 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5809 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5810 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5811 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5812  ip_source_and_port_range_check_add_del_reply)                          \
5813 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5814  ip_source_and_port_range_check_interface_add_del_reply)                \
5815 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5816 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5817 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5818 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5819 _(PUNT_REPLY, punt_reply)                                               \
5820 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5821 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5822 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5823 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5824 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5825 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5826 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5827 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5828 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5829 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5830 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5831 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5832 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5833 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5834 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5835 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5836 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5837 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5838 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5839 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5840 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5841 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5842 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5843
5844 #define foreach_standalone_reply_msg                                    \
5845 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5846 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5847 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5848 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5849 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5850 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5851 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5852
5853 typedef struct
5854 {
5855   u8 *name;
5856   u32 value;
5857 } name_sort_t;
5858
5859 #define STR_VTR_OP_CASE(op)     \
5860     case L2_VTR_ ## op:         \
5861         return "" # op;
5862
5863 static const char *
5864 str_vtr_op (u32 vtr_op)
5865 {
5866   switch (vtr_op)
5867     {
5868       STR_VTR_OP_CASE (DISABLED);
5869       STR_VTR_OP_CASE (PUSH_1);
5870       STR_VTR_OP_CASE (PUSH_2);
5871       STR_VTR_OP_CASE (POP_1);
5872       STR_VTR_OP_CASE (POP_2);
5873       STR_VTR_OP_CASE (TRANSLATE_1_1);
5874       STR_VTR_OP_CASE (TRANSLATE_1_2);
5875       STR_VTR_OP_CASE (TRANSLATE_2_1);
5876       STR_VTR_OP_CASE (TRANSLATE_2_2);
5877     }
5878
5879   return "UNKNOWN";
5880 }
5881
5882 static int
5883 dump_sub_interface_table (vat_main_t * vam)
5884 {
5885   const sw_interface_subif_t *sub = NULL;
5886
5887   if (vam->json_output)
5888     {
5889       clib_warning
5890         ("JSON output supported only for VPE API calls and dump_stats_table");
5891       return -99;
5892     }
5893
5894   print (vam->ofp,
5895          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5896          "Interface", "sw_if_index",
5897          "sub id", "dot1ad", "tags", "outer id",
5898          "inner id", "exact", "default", "outer any", "inner any");
5899
5900   vec_foreach (sub, vam->sw_if_subif_table)
5901   {
5902     print (vam->ofp,
5903            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5904            sub->interface_name,
5905            sub->sw_if_index,
5906            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5907            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5908            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5909            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5910     if (sub->vtr_op != L2_VTR_DISABLED)
5911       {
5912         print (vam->ofp,
5913                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5914                "tag1: %d tag2: %d ]",
5915                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5916                sub->vtr_tag1, sub->vtr_tag2);
5917       }
5918   }
5919
5920   return 0;
5921 }
5922
5923 static int
5924 name_sort_cmp (void *a1, void *a2)
5925 {
5926   name_sort_t *n1 = a1;
5927   name_sort_t *n2 = a2;
5928
5929   return strcmp ((char *) n1->name, (char *) n2->name);
5930 }
5931
5932 static int
5933 dump_interface_table (vat_main_t * vam)
5934 {
5935   hash_pair_t *p;
5936   name_sort_t *nses = 0, *ns;
5937
5938   if (vam->json_output)
5939     {
5940       clib_warning
5941         ("JSON output supported only for VPE API calls and dump_stats_table");
5942       return -99;
5943     }
5944
5945   /* *INDENT-OFF* */
5946   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5947   ({
5948     vec_add2 (nses, ns, 1);
5949     ns->name = (u8 *)(p->key);
5950     ns->value = (u32) p->value[0];
5951   }));
5952   /* *INDENT-ON* */
5953
5954   vec_sort_with_function (nses, name_sort_cmp);
5955
5956   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5957   vec_foreach (ns, nses)
5958   {
5959     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5960   }
5961   vec_free (nses);
5962   return 0;
5963 }
5964
5965 static int
5966 dump_ip_table (vat_main_t * vam, int is_ipv6)
5967 {
5968   const ip_details_t *det = NULL;
5969   const ip_address_details_t *address = NULL;
5970   u32 i = ~0;
5971
5972   print (vam->ofp, "%-12s", "sw_if_index");
5973
5974   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5975   {
5976     i++;
5977     if (!det->present)
5978       {
5979         continue;
5980       }
5981     print (vam->ofp, "%-12d", i);
5982     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5983     if (!det->addr)
5984       {
5985         continue;
5986       }
5987     vec_foreach (address, det->addr)
5988     {
5989       print (vam->ofp,
5990              "            %-30U%-13d",
5991              is_ipv6 ? format_ip6_address : format_ip4_address,
5992              address->ip, address->prefix_length);
5993     }
5994   }
5995
5996   return 0;
5997 }
5998
5999 static int
6000 dump_ipv4_table (vat_main_t * vam)
6001 {
6002   if (vam->json_output)
6003     {
6004       clib_warning
6005         ("JSON output supported only for VPE API calls and dump_stats_table");
6006       return -99;
6007     }
6008
6009   return dump_ip_table (vam, 0);
6010 }
6011
6012 static int
6013 dump_ipv6_table (vat_main_t * vam)
6014 {
6015   if (vam->json_output)
6016     {
6017       clib_warning
6018         ("JSON output supported only for VPE API calls and dump_stats_table");
6019       return -99;
6020     }
6021
6022   return dump_ip_table (vam, 1);
6023 }
6024
6025 static char *
6026 counter_type_to_str (u8 counter_type, u8 is_combined)
6027 {
6028   if (!is_combined)
6029     {
6030       switch (counter_type)
6031         {
6032         case VNET_INTERFACE_COUNTER_DROP:
6033           return "drop";
6034         case VNET_INTERFACE_COUNTER_PUNT:
6035           return "punt";
6036         case VNET_INTERFACE_COUNTER_IP4:
6037           return "ip4";
6038         case VNET_INTERFACE_COUNTER_IP6:
6039           return "ip6";
6040         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6041           return "rx-no-buf";
6042         case VNET_INTERFACE_COUNTER_RX_MISS:
6043           return "rx-miss";
6044         case VNET_INTERFACE_COUNTER_RX_ERROR:
6045           return "rx-error";
6046         case VNET_INTERFACE_COUNTER_TX_ERROR:
6047           return "tx-error";
6048         default:
6049           return "INVALID-COUNTER-TYPE";
6050         }
6051     }
6052   else
6053     {
6054       switch (counter_type)
6055         {
6056         case VNET_INTERFACE_COUNTER_RX:
6057           return "rx";
6058         case VNET_INTERFACE_COUNTER_TX:
6059           return "tx";
6060         default:
6061           return "INVALID-COUNTER-TYPE";
6062         }
6063     }
6064 }
6065
6066 static int
6067 dump_stats_table (vat_main_t * vam)
6068 {
6069   vat_json_node_t node;
6070   vat_json_node_t *msg_array;
6071   vat_json_node_t *msg;
6072   vat_json_node_t *counter_array;
6073   vat_json_node_t *counter;
6074   interface_counter_t c;
6075   u64 packets;
6076   ip4_fib_counter_t *c4;
6077   ip6_fib_counter_t *c6;
6078   ip4_nbr_counter_t *n4;
6079   ip6_nbr_counter_t *n6;
6080   int i, j;
6081
6082   if (!vam->json_output)
6083     {
6084       clib_warning ("dump_stats_table supported only in JSON format");
6085       return -99;
6086     }
6087
6088   vat_json_init_object (&node);
6089
6090   /* interface counters */
6091   msg_array = vat_json_object_add (&node, "interface_counters");
6092   vat_json_init_array (msg_array);
6093   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6094     {
6095       msg = vat_json_array_add (msg_array);
6096       vat_json_init_object (msg);
6097       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6098                                        (u8 *) counter_type_to_str (i, 0));
6099       vat_json_object_add_int (msg, "is_combined", 0);
6100       counter_array = vat_json_object_add (msg, "data");
6101       vat_json_init_array (counter_array);
6102       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6103         {
6104           packets = vam->simple_interface_counters[i][j];
6105           vat_json_array_add_uint (counter_array, packets);
6106         }
6107     }
6108   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6109     {
6110       msg = vat_json_array_add (msg_array);
6111       vat_json_init_object (msg);
6112       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6113                                        (u8 *) counter_type_to_str (i, 1));
6114       vat_json_object_add_int (msg, "is_combined", 1);
6115       counter_array = vat_json_object_add (msg, "data");
6116       vat_json_init_array (counter_array);
6117       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6118         {
6119           c = vam->combined_interface_counters[i][j];
6120           counter = vat_json_array_add (counter_array);
6121           vat_json_init_object (counter);
6122           vat_json_object_add_uint (counter, "packets", c.packets);
6123           vat_json_object_add_uint (counter, "bytes", c.bytes);
6124         }
6125     }
6126
6127   /* ip4 fib counters */
6128   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6129   vat_json_init_array (msg_array);
6130   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6131     {
6132       msg = vat_json_array_add (msg_array);
6133       vat_json_init_object (msg);
6134       vat_json_object_add_uint (msg, "vrf_id",
6135                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6136       counter_array = vat_json_object_add (msg, "c");
6137       vat_json_init_array (counter_array);
6138       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6139         {
6140           counter = vat_json_array_add (counter_array);
6141           vat_json_init_object (counter);
6142           c4 = &vam->ip4_fib_counters[i][j];
6143           vat_json_object_add_ip4 (counter, "address", c4->address);
6144           vat_json_object_add_uint (counter, "address_length",
6145                                     c4->address_length);
6146           vat_json_object_add_uint (counter, "packets", c4->packets);
6147           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6148         }
6149     }
6150
6151   /* ip6 fib counters */
6152   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6153   vat_json_init_array (msg_array);
6154   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6155     {
6156       msg = vat_json_array_add (msg_array);
6157       vat_json_init_object (msg);
6158       vat_json_object_add_uint (msg, "vrf_id",
6159                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6160       counter_array = vat_json_object_add (msg, "c");
6161       vat_json_init_array (counter_array);
6162       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6163         {
6164           counter = vat_json_array_add (counter_array);
6165           vat_json_init_object (counter);
6166           c6 = &vam->ip6_fib_counters[i][j];
6167           vat_json_object_add_ip6 (counter, "address", c6->address);
6168           vat_json_object_add_uint (counter, "address_length",
6169                                     c6->address_length);
6170           vat_json_object_add_uint (counter, "packets", c6->packets);
6171           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6172         }
6173     }
6174
6175   /* ip4 nbr counters */
6176   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6177   vat_json_init_array (msg_array);
6178   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6179     {
6180       msg = vat_json_array_add (msg_array);
6181       vat_json_init_object (msg);
6182       vat_json_object_add_uint (msg, "sw_if_index", i);
6183       counter_array = vat_json_object_add (msg, "c");
6184       vat_json_init_array (counter_array);
6185       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6186         {
6187           counter = vat_json_array_add (counter_array);
6188           vat_json_init_object (counter);
6189           n4 = &vam->ip4_nbr_counters[i][j];
6190           vat_json_object_add_ip4 (counter, "address", n4->address);
6191           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6192           vat_json_object_add_uint (counter, "packets", n4->packets);
6193           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6194         }
6195     }
6196
6197   /* ip6 nbr counters */
6198   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6199   vat_json_init_array (msg_array);
6200   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6201     {
6202       msg = vat_json_array_add (msg_array);
6203       vat_json_init_object (msg);
6204       vat_json_object_add_uint (msg, "sw_if_index", i);
6205       counter_array = vat_json_object_add (msg, "c");
6206       vat_json_init_array (counter_array);
6207       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6208         {
6209           counter = vat_json_array_add (counter_array);
6210           vat_json_init_object (counter);
6211           n6 = &vam->ip6_nbr_counters[i][j];
6212           vat_json_object_add_ip6 (counter, "address", n6->address);
6213           vat_json_object_add_uint (counter, "packets", n6->packets);
6214           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6215         }
6216     }
6217
6218   vat_json_print (vam->ofp, &node);
6219   vat_json_free (&node);
6220
6221   return 0;
6222 }
6223
6224 /*
6225  * Pass CLI buffers directly in the CLI_INBAND API message,
6226  * instead of an additional shared memory area.
6227  */
6228 static int
6229 exec_inband (vat_main_t * vam)
6230 {
6231   vl_api_cli_inband_t *mp;
6232   unformat_input_t *i = vam->input;
6233   int ret;
6234
6235   if (vec_len (i->buffer) == 0)
6236     return -1;
6237
6238   if (vam->exec_mode == 0 && unformat (i, "mode"))
6239     {
6240       vam->exec_mode = 1;
6241       return 0;
6242     }
6243   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6244     {
6245       vam->exec_mode = 0;
6246       return 0;
6247     }
6248
6249   /*
6250    * In order for the CLI command to work, it
6251    * must be a vector ending in \n, not a C-string ending
6252    * in \n\0.
6253    */
6254   u32 len = vec_len (vam->input->buffer);
6255   M2 (CLI_INBAND, mp, len);
6256   clib_memcpy (mp->cmd, vam->input->buffer, len);
6257   mp->length = htonl (len);
6258
6259   S (mp);
6260   W (ret);
6261   /* json responses may or may not include a useful reply... */
6262   if (vec_len (vam->cmd_reply))
6263     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6264   return ret;
6265 }
6266
6267 int
6268 exec (vat_main_t * vam)
6269 {
6270   return exec_inband (vam);
6271 }
6272
6273 static int
6274 api_create_loopback (vat_main_t * vam)
6275 {
6276   unformat_input_t *i = vam->input;
6277   vl_api_create_loopback_t *mp;
6278   vl_api_create_loopback_instance_t *mp_lbi;
6279   u8 mac_address[6];
6280   u8 mac_set = 0;
6281   u8 is_specified = 0;
6282   u32 user_instance = 0;
6283   int ret;
6284
6285   memset (mac_address, 0, sizeof (mac_address));
6286
6287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6288     {
6289       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6290         mac_set = 1;
6291       if (unformat (i, "instance %d", &user_instance))
6292         is_specified = 1;
6293       else
6294         break;
6295     }
6296
6297   if (is_specified)
6298     {
6299       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6300       mp_lbi->is_specified = is_specified;
6301       if (is_specified)
6302         mp_lbi->user_instance = htonl (user_instance);
6303       if (mac_set)
6304         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6305       S (mp_lbi);
6306     }
6307   else
6308     {
6309       /* Construct the API message */
6310       M (CREATE_LOOPBACK, mp);
6311       if (mac_set)
6312         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6313       S (mp);
6314     }
6315
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_delete_loopback (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_delete_loopback_t *mp;
6325   u32 sw_if_index = ~0;
6326   int ret;
6327
6328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6329     {
6330       if (unformat (i, "sw_if_index %d", &sw_if_index))
6331         ;
6332       else
6333         break;
6334     }
6335
6336   if (sw_if_index == ~0)
6337     {
6338       errmsg ("missing sw_if_index");
6339       return -99;
6340     }
6341
6342   /* Construct the API message */
6343   M (DELETE_LOOPBACK, mp);
6344   mp->sw_if_index = ntohl (sw_if_index);
6345
6346   S (mp);
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_want_stats (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_want_stats_t *mp;
6356   int enable = -1;
6357   int ret;
6358
6359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6360     {
6361       if (unformat (i, "enable"))
6362         enable = 1;
6363       else if (unformat (i, "disable"))
6364         enable = 0;
6365       else
6366         break;
6367     }
6368
6369   if (enable == -1)
6370     {
6371       errmsg ("missing enable|disable");
6372       return -99;
6373     }
6374
6375   M (WANT_STATS, mp);
6376   mp->enable_disable = enable;
6377
6378   S (mp);
6379   W (ret);
6380   return ret;
6381 }
6382
6383 static int
6384 api_want_interface_events (vat_main_t * vam)
6385 {
6386   unformat_input_t *i = vam->input;
6387   vl_api_want_interface_events_t *mp;
6388   int enable = -1;
6389   int ret;
6390
6391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6392     {
6393       if (unformat (i, "enable"))
6394         enable = 1;
6395       else if (unformat (i, "disable"))
6396         enable = 0;
6397       else
6398         break;
6399     }
6400
6401   if (enable == -1)
6402     {
6403       errmsg ("missing enable|disable");
6404       return -99;
6405     }
6406
6407   M (WANT_INTERFACE_EVENTS, mp);
6408   mp->enable_disable = enable;
6409
6410   vam->interface_event_display = enable;
6411
6412   S (mp);
6413   W (ret);
6414   return ret;
6415 }
6416
6417
6418 /* Note: non-static, called once to set up the initial intfc table */
6419 int
6420 api_sw_interface_dump (vat_main_t * vam)
6421 {
6422   vl_api_sw_interface_dump_t *mp;
6423   vl_api_control_ping_t *mp_ping;
6424   hash_pair_t *p;
6425   name_sort_t *nses = 0, *ns;
6426   sw_interface_subif_t *sub = NULL;
6427   int ret;
6428
6429   /* Toss the old name table */
6430   /* *INDENT-OFF* */
6431   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6432   ({
6433     vec_add2 (nses, ns, 1);
6434     ns->name = (u8 *)(p->key);
6435     ns->value = (u32) p->value[0];
6436   }));
6437   /* *INDENT-ON* */
6438
6439   hash_free (vam->sw_if_index_by_interface_name);
6440
6441   vec_foreach (ns, nses) vec_free (ns->name);
6442
6443   vec_free (nses);
6444
6445   vec_foreach (sub, vam->sw_if_subif_table)
6446   {
6447     vec_free (sub->interface_name);
6448   }
6449   vec_free (vam->sw_if_subif_table);
6450
6451   /* recreate the interface name hash table */
6452   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6453
6454   /*
6455    * Ask for all interface names. Otherwise, the epic catalog of
6456    * name filters becomes ridiculously long, and vat ends up needing
6457    * to be taught about new interface types.
6458    */
6459   M (SW_INTERFACE_DUMP, mp);
6460   S (mp);
6461
6462   /* Use a control ping for synchronization */
6463   MPING (CONTROL_PING, mp_ping);
6464   S (mp_ping);
6465
6466   W (ret);
6467   return ret;
6468 }
6469
6470 static int
6471 api_sw_interface_set_flags (vat_main_t * vam)
6472 {
6473   unformat_input_t *i = vam->input;
6474   vl_api_sw_interface_set_flags_t *mp;
6475   u32 sw_if_index;
6476   u8 sw_if_index_set = 0;
6477   u8 admin_up = 0;
6478   int ret;
6479
6480   /* Parse args required to build the message */
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "admin-up"))
6484         admin_up = 1;
6485       else if (unformat (i, "admin-down"))
6486         admin_up = 0;
6487       else
6488         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6489         sw_if_index_set = 1;
6490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6491         sw_if_index_set = 1;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index_set == 0)
6497     {
6498       errmsg ("missing interface name or sw_if_index");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (SW_INTERFACE_SET_FLAGS, mp);
6504   mp->sw_if_index = ntohl (sw_if_index);
6505   mp->admin_up_down = admin_up;
6506
6507   /* send it... */
6508   S (mp);
6509
6510   /* Wait for a reply, return the good/bad news... */
6511   W (ret);
6512   return ret;
6513 }
6514
6515 static int
6516 api_sw_interface_set_rx_mode (vat_main_t * vam)
6517 {
6518   unformat_input_t *i = vam->input;
6519   vl_api_sw_interface_set_rx_mode_t *mp;
6520   u32 sw_if_index;
6521   u8 sw_if_index_set = 0;
6522   int ret;
6523   u8 queue_id_valid = 0;
6524   u32 queue_id;
6525   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6526
6527   /* Parse args required to build the message */
6528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6529     {
6530       if (unformat (i, "queue %d", &queue_id))
6531         queue_id_valid = 1;
6532       else if (unformat (i, "polling"))
6533         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6534       else if (unformat (i, "interrupt"))
6535         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6536       else if (unformat (i, "adaptive"))
6537         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6538       else
6539         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6540         sw_if_index_set = 1;
6541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6542         sw_if_index_set = 1;
6543       else
6544         break;
6545     }
6546
6547   if (sw_if_index_set == 0)
6548     {
6549       errmsg ("missing interface name or sw_if_index");
6550       return -99;
6551     }
6552   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6553     {
6554       errmsg ("missing rx-mode");
6555       return -99;
6556     }
6557
6558   /* Construct the API message */
6559   M (SW_INTERFACE_SET_RX_MODE, mp);
6560   mp->sw_if_index = ntohl (sw_if_index);
6561   mp->mode = mode;
6562   mp->queue_id_valid = queue_id_valid;
6563   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6564
6565   /* send it... */
6566   S (mp);
6567
6568   /* Wait for a reply, return the good/bad news... */
6569   W (ret);
6570   return ret;
6571 }
6572
6573 static int
6574 api_sw_interface_set_rx_placement (vat_main_t * vam)
6575 {
6576   unformat_input_t *i = vam->input;
6577   vl_api_sw_interface_set_rx_placement_t *mp;
6578   u32 sw_if_index;
6579   u8 sw_if_index_set = 0;
6580   int ret;
6581   u8 is_main = 0;
6582   u32 queue_id, thread_index;
6583
6584   /* Parse args required to build the message */
6585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6586     {
6587       if (unformat (i, "queue %d", &queue_id))
6588         ;
6589       else if (unformat (i, "main"))
6590         is_main = 1;
6591       else if (unformat (i, "worker %d", &thread_index))
6592         ;
6593       else
6594         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6595         sw_if_index_set = 1;
6596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6597         sw_if_index_set = 1;
6598       else
6599         break;
6600     }
6601
6602   if (sw_if_index_set == 0)
6603     {
6604       errmsg ("missing interface name or sw_if_index");
6605       return -99;
6606     }
6607
6608   if (is_main)
6609     thread_index = 0;
6610   /* Construct the API message */
6611   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6612   mp->sw_if_index = ntohl (sw_if_index);
6613   mp->worker_id = ntohl (thread_index);
6614   mp->queue_id = ntohl (queue_id);
6615   mp->is_main = is_main;
6616
6617   /* send it... */
6618   S (mp);
6619   /* Wait for a reply, return the good/bad news... */
6620   W (ret);
6621   return ret;
6622 }
6623
6624 static void vl_api_sw_interface_rx_placement_details_t_handler
6625   (vl_api_sw_interface_rx_placement_details_t * mp)
6626 {
6627   vat_main_t *vam = &vat_main;
6628   u32 worker_id = ntohl (mp->worker_id);
6629
6630   print (vam->ofp,
6631          "\n%-11d %-11s %-6d %-5d %-9s",
6632          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6633          worker_id, ntohl (mp->queue_id),
6634          (mp->mode ==
6635           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6636 }
6637
6638 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6639   (vl_api_sw_interface_rx_placement_details_t * mp)
6640 {
6641   vat_main_t *vam = &vat_main;
6642   vat_json_node_t *node = NULL;
6643
6644   if (VAT_JSON_ARRAY != vam->json_tree.type)
6645     {
6646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6647       vat_json_init_array (&vam->json_tree);
6648     }
6649   node = vat_json_array_add (&vam->json_tree);
6650
6651   vat_json_init_object (node);
6652   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6653   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6654   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6655   vat_json_object_add_uint (node, "mode", mp->mode);
6656 }
6657
6658 static int
6659 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_rx_placement_dump_t *mp;
6663   vl_api_control_ping_t *mp_ping;
6664   int ret;
6665   u32 sw_if_index;
6666   u8 sw_if_index_set = 0;
6667
6668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6669     {
6670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6671         sw_if_index_set++;
6672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6673         sw_if_index_set++;
6674       else
6675         break;
6676     }
6677
6678   print (vam->ofp,
6679          "\n%-11s %-11s %-6s %-5s %-4s",
6680          "sw_if_index", "main/worker", "thread", "queue", "mode");
6681
6682   /* Dump Interface rx placement */
6683   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6684
6685   if (sw_if_index_set)
6686     mp->sw_if_index = htonl (sw_if_index);
6687   else
6688     mp->sw_if_index = ~0;
6689
6690   S (mp);
6691
6692   /* Use a control ping for synchronization */
6693   MPING (CONTROL_PING, mp_ping);
6694   S (mp_ping);
6695
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_sw_interface_clear_stats (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_clear_stats_t *mp;
6705   u32 sw_if_index;
6706   u8 sw_if_index_set = 0;
6707   int ret;
6708
6709   /* Parse args required to build the message */
6710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6711     {
6712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         sw_if_index_set = 1;
6716       else
6717         break;
6718     }
6719
6720   /* Construct the API message */
6721   M (SW_INTERFACE_CLEAR_STATS, mp);
6722
6723   if (sw_if_index_set == 1)
6724     mp->sw_if_index = ntohl (sw_if_index);
6725   else
6726     mp->sw_if_index = ~0;
6727
6728   /* send it... */
6729   S (mp);
6730
6731   /* Wait for a reply, return the good/bad news... */
6732   W (ret);
6733   return ret;
6734 }
6735
6736 static int
6737 api_sw_interface_add_del_address (vat_main_t * vam)
6738 {
6739   unformat_input_t *i = vam->input;
6740   vl_api_sw_interface_add_del_address_t *mp;
6741   u32 sw_if_index;
6742   u8 sw_if_index_set = 0;
6743   u8 is_add = 1, del_all = 0;
6744   u32 address_length = 0;
6745   u8 v4_address_set = 0;
6746   u8 v6_address_set = 0;
6747   ip4_address_t v4address;
6748   ip6_address_t v6address;
6749   int ret;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "del-all"))
6755         del_all = 1;
6756       else if (unformat (i, "del"))
6757         is_add = 0;
6758       else
6759         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6762         sw_if_index_set = 1;
6763       else if (unformat (i, "%U/%d",
6764                          unformat_ip4_address, &v4address, &address_length))
6765         v4_address_set = 1;
6766       else if (unformat (i, "%U/%d",
6767                          unformat_ip6_address, &v6address, &address_length))
6768         v6_address_set = 1;
6769       else
6770         break;
6771     }
6772
6773   if (sw_if_index_set == 0)
6774     {
6775       errmsg ("missing interface name or sw_if_index");
6776       return -99;
6777     }
6778   if (v4_address_set && v6_address_set)
6779     {
6780       errmsg ("both v4 and v6 addresses set");
6781       return -99;
6782     }
6783   if (!v4_address_set && !v6_address_set && !del_all)
6784     {
6785       errmsg ("no addresses set");
6786       return -99;
6787     }
6788
6789   /* Construct the API message */
6790   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6791
6792   mp->sw_if_index = ntohl (sw_if_index);
6793   mp->is_add = is_add;
6794   mp->del_all = del_all;
6795   if (v6_address_set)
6796     {
6797       mp->is_ipv6 = 1;
6798       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6799     }
6800   else
6801     {
6802       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6803     }
6804   mp->address_length = address_length;
6805
6806   /* send it... */
6807   S (mp);
6808
6809   /* Wait for a reply, return good/bad news  */
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_sw_interface_set_mpls_enable_t *mp;
6819   u32 sw_if_index;
6820   u8 sw_if_index_set = 0;
6821   u8 enable = 1;
6822   int ret;
6823
6824   /* Parse args required to build the message */
6825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6826     {
6827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6828         sw_if_index_set = 1;
6829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "disable"))
6832         enable = 0;
6833       else if (unformat (i, "dis"))
6834         enable = 0;
6835       else
6836         break;
6837     }
6838
6839   if (sw_if_index_set == 0)
6840     {
6841       errmsg ("missing interface name or sw_if_index");
6842       return -99;
6843     }
6844
6845   /* Construct the API message */
6846   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6847
6848   mp->sw_if_index = ntohl (sw_if_index);
6849   mp->enable = enable;
6850
6851   /* send it... */
6852   S (mp);
6853
6854   /* Wait for a reply... */
6855   W (ret);
6856   return ret;
6857 }
6858
6859 static int
6860 api_sw_interface_set_table (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_sw_interface_set_table_t *mp;
6864   u32 sw_if_index, vrf_id = 0;
6865   u8 sw_if_index_set = 0;
6866   u8 is_ipv6 = 0;
6867   int ret;
6868
6869   /* Parse args required to build the message */
6870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6871     {
6872       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6873         sw_if_index_set = 1;
6874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6875         sw_if_index_set = 1;
6876       else if (unformat (i, "vrf %d", &vrf_id))
6877         ;
6878       else if (unformat (i, "ipv6"))
6879         is_ipv6 = 1;
6880       else
6881         break;
6882     }
6883
6884   if (sw_if_index_set == 0)
6885     {
6886       errmsg ("missing interface name or sw_if_index");
6887       return -99;
6888     }
6889
6890   /* Construct the API message */
6891   M (SW_INTERFACE_SET_TABLE, mp);
6892
6893   mp->sw_if_index = ntohl (sw_if_index);
6894   mp->is_ipv6 = is_ipv6;
6895   mp->vrf_id = ntohl (vrf_id);
6896
6897   /* send it... */
6898   S (mp);
6899
6900   /* Wait for a reply... */
6901   W (ret);
6902   return ret;
6903 }
6904
6905 static void vl_api_sw_interface_get_table_reply_t_handler
6906   (vl_api_sw_interface_get_table_reply_t * mp)
6907 {
6908   vat_main_t *vam = &vat_main;
6909
6910   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6911
6912   vam->retval = ntohl (mp->retval);
6913   vam->result_ready = 1;
6914
6915 }
6916
6917 static void vl_api_sw_interface_get_table_reply_t_handler_json
6918   (vl_api_sw_interface_get_table_reply_t * mp)
6919 {
6920   vat_main_t *vam = &vat_main;
6921   vat_json_node_t node;
6922
6923   vat_json_init_object (&node);
6924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6925   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6926
6927   vat_json_print (vam->ofp, &node);
6928   vat_json_free (&node);
6929
6930   vam->retval = ntohl (mp->retval);
6931   vam->result_ready = 1;
6932 }
6933
6934 static int
6935 api_sw_interface_get_table (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_sw_interface_get_table_t *mp;
6939   u32 sw_if_index;
6940   u8 sw_if_index_set = 0;
6941   u8 is_ipv6 = 0;
6942   int ret;
6943
6944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6945     {
6946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "ipv6"))
6951         is_ipv6 = 1;
6952       else
6953         break;
6954     }
6955
6956   if (sw_if_index_set == 0)
6957     {
6958       errmsg ("missing interface name or sw_if_index");
6959       return -99;
6960     }
6961
6962   M (SW_INTERFACE_GET_TABLE, mp);
6963   mp->sw_if_index = htonl (sw_if_index);
6964   mp->is_ipv6 = is_ipv6;
6965
6966   S (mp);
6967   W (ret);
6968   return ret;
6969 }
6970
6971 static int
6972 api_sw_interface_set_vpath (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_sw_interface_set_vpath_t *mp;
6976   u32 sw_if_index = 0;
6977   u8 sw_if_index_set = 0;
6978   u8 is_enable = 0;
6979   int ret;
6980
6981   /* Parse args required to build the message */
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6985         sw_if_index_set = 1;
6986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6987         sw_if_index_set = 1;
6988       else if (unformat (i, "enable"))
6989         is_enable = 1;
6990       else if (unformat (i, "disable"))
6991         is_enable = 0;
6992       else
6993         break;
6994     }
6995
6996   if (sw_if_index_set == 0)
6997     {
6998       errmsg ("missing interface name or sw_if_index");
6999       return -99;
7000     }
7001
7002   /* Construct the API message */
7003   M (SW_INTERFACE_SET_VPATH, mp);
7004
7005   mp->sw_if_index = ntohl (sw_if_index);
7006   mp->enable = is_enable;
7007
7008   /* send it... */
7009   S (mp);
7010
7011   /* Wait for a reply... */
7012   W (ret);
7013   return ret;
7014 }
7015
7016 static int
7017 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7018 {
7019   unformat_input_t *i = vam->input;
7020   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7021   u32 sw_if_index = 0;
7022   u8 sw_if_index_set = 0;
7023   u8 is_enable = 1;
7024   u8 is_ipv6 = 0;
7025   int ret;
7026
7027   /* Parse args required to build the message */
7028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7029     {
7030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7031         sw_if_index_set = 1;
7032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7033         sw_if_index_set = 1;
7034       else if (unformat (i, "enable"))
7035         is_enable = 1;
7036       else if (unformat (i, "disable"))
7037         is_enable = 0;
7038       else if (unformat (i, "ip4"))
7039         is_ipv6 = 0;
7040       else if (unformat (i, "ip6"))
7041         is_ipv6 = 1;
7042       else
7043         break;
7044     }
7045
7046   if (sw_if_index_set == 0)
7047     {
7048       errmsg ("missing interface name or sw_if_index");
7049       return -99;
7050     }
7051
7052   /* Construct the API message */
7053   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7054
7055   mp->sw_if_index = ntohl (sw_if_index);
7056   mp->enable = is_enable;
7057   mp->is_ipv6 = is_ipv6;
7058
7059   /* send it... */
7060   S (mp);
7061
7062   /* Wait for a reply... */
7063   W (ret);
7064   return ret;
7065 }
7066
7067 static int
7068 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7069 {
7070   unformat_input_t *i = vam->input;
7071   vl_api_sw_interface_set_geneve_bypass_t *mp;
7072   u32 sw_if_index = 0;
7073   u8 sw_if_index_set = 0;
7074   u8 is_enable = 1;
7075   u8 is_ipv6 = 0;
7076   int ret;
7077
7078   /* Parse args required to build the message */
7079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7080     {
7081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7082         sw_if_index_set = 1;
7083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7084         sw_if_index_set = 1;
7085       else if (unformat (i, "enable"))
7086         is_enable = 1;
7087       else if (unformat (i, "disable"))
7088         is_enable = 0;
7089       else if (unformat (i, "ip4"))
7090         is_ipv6 = 0;
7091       else if (unformat (i, "ip6"))
7092         is_ipv6 = 1;
7093       else
7094         break;
7095     }
7096
7097   if (sw_if_index_set == 0)
7098     {
7099       errmsg ("missing interface name or sw_if_index");
7100       return -99;
7101     }
7102
7103   /* Construct the API message */
7104   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7105
7106   mp->sw_if_index = ntohl (sw_if_index);
7107   mp->enable = is_enable;
7108   mp->is_ipv6 = is_ipv6;
7109
7110   /* send it... */
7111   S (mp);
7112
7113   /* Wait for a reply... */
7114   W (ret);
7115   return ret;
7116 }
7117
7118 static int
7119 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7120 {
7121   unformat_input_t *i = vam->input;
7122   vl_api_sw_interface_set_l2_xconnect_t *mp;
7123   u32 rx_sw_if_index;
7124   u8 rx_sw_if_index_set = 0;
7125   u32 tx_sw_if_index;
7126   u8 tx_sw_if_index_set = 0;
7127   u8 enable = 1;
7128   int ret;
7129
7130   /* Parse args required to build the message */
7131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7132     {
7133       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7134         rx_sw_if_index_set = 1;
7135       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7136         tx_sw_if_index_set = 1;
7137       else if (unformat (i, "rx"))
7138         {
7139           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7140             {
7141               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7142                             &rx_sw_if_index))
7143                 rx_sw_if_index_set = 1;
7144             }
7145           else
7146             break;
7147         }
7148       else if (unformat (i, "tx"))
7149         {
7150           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7151             {
7152               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7153                             &tx_sw_if_index))
7154                 tx_sw_if_index_set = 1;
7155             }
7156           else
7157             break;
7158         }
7159       else if (unformat (i, "enable"))
7160         enable = 1;
7161       else if (unformat (i, "disable"))
7162         enable = 0;
7163       else
7164         break;
7165     }
7166
7167   if (rx_sw_if_index_set == 0)
7168     {
7169       errmsg ("missing rx interface name or rx_sw_if_index");
7170       return -99;
7171     }
7172
7173   if (enable && (tx_sw_if_index_set == 0))
7174     {
7175       errmsg ("missing tx interface name or tx_sw_if_index");
7176       return -99;
7177     }
7178
7179   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7180
7181   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7182   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7183   mp->enable = enable;
7184
7185   S (mp);
7186   W (ret);
7187   return ret;
7188 }
7189
7190 static int
7191 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7192 {
7193   unformat_input_t *i = vam->input;
7194   vl_api_sw_interface_set_l2_bridge_t *mp;
7195   vl_api_l2_port_type_t port_type;
7196   u32 rx_sw_if_index;
7197   u8 rx_sw_if_index_set = 0;
7198   u32 bd_id;
7199   u8 bd_id_set = 0;
7200   u32 shg = 0;
7201   u8 enable = 1;
7202   int ret;
7203
7204   port_type = L2_API_PORT_TYPE_NORMAL;
7205
7206   /* Parse args required to build the message */
7207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7208     {
7209       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7210         rx_sw_if_index_set = 1;
7211       else if (unformat (i, "bd_id %d", &bd_id))
7212         bd_id_set = 1;
7213       else
7214         if (unformat
7215             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7216         rx_sw_if_index_set = 1;
7217       else if (unformat (i, "shg %d", &shg))
7218         ;
7219       else if (unformat (i, "bvi"))
7220         port_type = L2_API_PORT_TYPE_BVI;
7221       else if (unformat (i, "uu-fwd"))
7222         port_type = L2_API_PORT_TYPE_UU_FWD;
7223       else if (unformat (i, "enable"))
7224         enable = 1;
7225       else if (unformat (i, "disable"))
7226         enable = 0;
7227       else
7228         break;
7229     }
7230
7231   if (rx_sw_if_index_set == 0)
7232     {
7233       errmsg ("missing rx interface name or sw_if_index");
7234       return -99;
7235     }
7236
7237   if (enable && (bd_id_set == 0))
7238     {
7239       errmsg ("missing bridge domain");
7240       return -99;
7241     }
7242
7243   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7244
7245   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7246   mp->bd_id = ntohl (bd_id);
7247   mp->shg = (u8) shg;
7248   mp->port_type = ntohl (port_type);
7249   mp->enable = enable;
7250
7251   S (mp);
7252   W (ret);
7253   return ret;
7254 }
7255
7256 static int
7257 api_bridge_domain_dump (vat_main_t * vam)
7258 {
7259   unformat_input_t *i = vam->input;
7260   vl_api_bridge_domain_dump_t *mp;
7261   vl_api_control_ping_t *mp_ping;
7262   u32 bd_id = ~0;
7263   int ret;
7264
7265   /* Parse args required to build the message */
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "bd_id %d", &bd_id))
7269         ;
7270       else
7271         break;
7272     }
7273
7274   M (BRIDGE_DOMAIN_DUMP, mp);
7275   mp->bd_id = ntohl (bd_id);
7276   S (mp);
7277
7278   /* Use a control ping for synchronization */
7279   MPING (CONTROL_PING, mp_ping);
7280   S (mp_ping);
7281
7282   W (ret);
7283   return ret;
7284 }
7285
7286 static int
7287 api_bridge_domain_add_del (vat_main_t * vam)
7288 {
7289   unformat_input_t *i = vam->input;
7290   vl_api_bridge_domain_add_del_t *mp;
7291   u32 bd_id = ~0;
7292   u8 is_add = 1;
7293   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7294   u8 *bd_tag = NULL;
7295   u32 mac_age = 0;
7296   int ret;
7297
7298   /* Parse args required to build the message */
7299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7300     {
7301       if (unformat (i, "bd_id %d", &bd_id))
7302         ;
7303       else if (unformat (i, "flood %d", &flood))
7304         ;
7305       else if (unformat (i, "uu-flood %d", &uu_flood))
7306         ;
7307       else if (unformat (i, "forward %d", &forward))
7308         ;
7309       else if (unformat (i, "learn %d", &learn))
7310         ;
7311       else if (unformat (i, "arp-term %d", &arp_term))
7312         ;
7313       else if (unformat (i, "mac-age %d", &mac_age))
7314         ;
7315       else if (unformat (i, "bd-tag %s", &bd_tag))
7316         ;
7317       else if (unformat (i, "del"))
7318         {
7319           is_add = 0;
7320           flood = uu_flood = forward = learn = 0;
7321         }
7322       else
7323         break;
7324     }
7325
7326   if (bd_id == ~0)
7327     {
7328       errmsg ("missing bridge domain");
7329       ret = -99;
7330       goto done;
7331     }
7332
7333   if (mac_age > 255)
7334     {
7335       errmsg ("mac age must be less than 256 ");
7336       ret = -99;
7337       goto done;
7338     }
7339
7340   if ((bd_tag) && (vec_len (bd_tag) > 63))
7341     {
7342       errmsg ("bd-tag cannot be longer than 63");
7343       ret = -99;
7344       goto done;
7345     }
7346
7347   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7348
7349   mp->bd_id = ntohl (bd_id);
7350   mp->flood = flood;
7351   mp->uu_flood = uu_flood;
7352   mp->forward = forward;
7353   mp->learn = learn;
7354   mp->arp_term = arp_term;
7355   mp->is_add = is_add;
7356   mp->mac_age = (u8) mac_age;
7357   if (bd_tag)
7358     {
7359       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7360       mp->bd_tag[vec_len (bd_tag)] = 0;
7361     }
7362   S (mp);
7363   W (ret);
7364
7365 done:
7366   vec_free (bd_tag);
7367   return ret;
7368 }
7369
7370 static int
7371 api_l2fib_flush_bd (vat_main_t * vam)
7372 {
7373   unformat_input_t *i = vam->input;
7374   vl_api_l2fib_flush_bd_t *mp;
7375   u32 bd_id = ~0;
7376   int ret;
7377
7378   /* Parse args required to build the message */
7379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7380     {
7381       if (unformat (i, "bd_id %d", &bd_id));
7382       else
7383         break;
7384     }
7385
7386   if (bd_id == ~0)
7387     {
7388       errmsg ("missing bridge domain");
7389       return -99;
7390     }
7391
7392   M (L2FIB_FLUSH_BD, mp);
7393
7394   mp->bd_id = htonl (bd_id);
7395
7396   S (mp);
7397   W (ret);
7398   return ret;
7399 }
7400
7401 static int
7402 api_l2fib_flush_int (vat_main_t * vam)
7403 {
7404   unformat_input_t *i = vam->input;
7405   vl_api_l2fib_flush_int_t *mp;
7406   u32 sw_if_index = ~0;
7407   int ret;
7408
7409   /* Parse args required to build the message */
7410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7411     {
7412       if (unformat (i, "sw_if_index %d", &sw_if_index));
7413       else
7414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7415       else
7416         break;
7417     }
7418
7419   if (sw_if_index == ~0)
7420     {
7421       errmsg ("missing interface name or sw_if_index");
7422       return -99;
7423     }
7424
7425   M (L2FIB_FLUSH_INT, mp);
7426
7427   mp->sw_if_index = ntohl (sw_if_index);
7428
7429   S (mp);
7430   W (ret);
7431   return ret;
7432 }
7433
7434 static int
7435 api_l2fib_add_del (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_l2fib_add_del_t *mp;
7439   f64 timeout;
7440   u8 mac[6] = { 0 };
7441   u8 mac_set = 0;
7442   u32 bd_id;
7443   u8 bd_id_set = 0;
7444   u32 sw_if_index = 0;
7445   u8 sw_if_index_set = 0;
7446   u8 is_add = 1;
7447   u8 static_mac = 0;
7448   u8 filter_mac = 0;
7449   u8 bvi_mac = 0;
7450   int count = 1;
7451   f64 before = 0;
7452   int j;
7453
7454   /* Parse args required to build the message */
7455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7456     {
7457       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7458         mac_set = 1;
7459       else if (unformat (i, "bd_id %d", &bd_id))
7460         bd_id_set = 1;
7461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7462         sw_if_index_set = 1;
7463       else if (unformat (i, "sw_if"))
7464         {
7465           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466             {
7467               if (unformat
7468                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7469                 sw_if_index_set = 1;
7470             }
7471           else
7472             break;
7473         }
7474       else if (unformat (i, "static"))
7475         static_mac = 1;
7476       else if (unformat (i, "filter"))
7477         {
7478           filter_mac = 1;
7479           static_mac = 1;
7480         }
7481       else if (unformat (i, "bvi"))
7482         {
7483           bvi_mac = 1;
7484           static_mac = 1;
7485         }
7486       else if (unformat (i, "del"))
7487         is_add = 0;
7488       else if (unformat (i, "count %d", &count))
7489         ;
7490       else
7491         break;
7492     }
7493
7494   if (mac_set == 0)
7495     {
7496       errmsg ("missing mac address");
7497       return -99;
7498     }
7499
7500   if (bd_id_set == 0)
7501     {
7502       errmsg ("missing bridge domain");
7503       return -99;
7504     }
7505
7506   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7507     {
7508       errmsg ("missing interface name or sw_if_index");
7509       return -99;
7510     }
7511
7512   if (count > 1)
7513     {
7514       /* Turn on async mode */
7515       vam->async_mode = 1;
7516       vam->async_errors = 0;
7517       before = vat_time_now (vam);
7518     }
7519
7520   for (j = 0; j < count; j++)
7521     {
7522       M (L2FIB_ADD_DEL, mp);
7523
7524       clib_memcpy (mp->mac, mac, 6);
7525       mp->bd_id = ntohl (bd_id);
7526       mp->is_add = is_add;
7527       mp->sw_if_index = ntohl (sw_if_index);
7528
7529       if (is_add)
7530         {
7531           mp->static_mac = static_mac;
7532           mp->filter_mac = filter_mac;
7533           mp->bvi_mac = bvi_mac;
7534         }
7535       increment_mac_address (mac);
7536       /* send it... */
7537       S (mp);
7538     }
7539
7540   if (count > 1)
7541     {
7542       vl_api_control_ping_t *mp_ping;
7543       f64 after;
7544
7545       /* Shut off async mode */
7546       vam->async_mode = 0;
7547
7548       MPING (CONTROL_PING, mp_ping);
7549       S (mp_ping);
7550
7551       timeout = vat_time_now (vam) + 1.0;
7552       while (vat_time_now (vam) < timeout)
7553         if (vam->result_ready == 1)
7554           goto out;
7555       vam->retval = -99;
7556
7557     out:
7558       if (vam->retval == -99)
7559         errmsg ("timeout");
7560
7561       if (vam->async_errors > 0)
7562         {
7563           errmsg ("%d asynchronous errors", vam->async_errors);
7564           vam->retval = -98;
7565         }
7566       vam->async_errors = 0;
7567       after = vat_time_now (vam);
7568
7569       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7570              count, after - before, count / (after - before));
7571     }
7572   else
7573     {
7574       int ret;
7575
7576       /* Wait for a reply... */
7577       W (ret);
7578       return ret;
7579     }
7580   /* Return the good/bad news */
7581   return (vam->retval);
7582 }
7583
7584 static int
7585 api_bridge_domain_set_mac_age (vat_main_t * vam)
7586 {
7587   unformat_input_t *i = vam->input;
7588   vl_api_bridge_domain_set_mac_age_t *mp;
7589   u32 bd_id = ~0;
7590   u32 mac_age = 0;
7591   int ret;
7592
7593   /* Parse args required to build the message */
7594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7595     {
7596       if (unformat (i, "bd_id %d", &bd_id));
7597       else if (unformat (i, "mac-age %d", &mac_age));
7598       else
7599         break;
7600     }
7601
7602   if (bd_id == ~0)
7603     {
7604       errmsg ("missing bridge domain");
7605       return -99;
7606     }
7607
7608   if (mac_age > 255)
7609     {
7610       errmsg ("mac age must be less than 256 ");
7611       return -99;
7612     }
7613
7614   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7615
7616   mp->bd_id = htonl (bd_id);
7617   mp->mac_age = (u8) mac_age;
7618
7619   S (mp);
7620   W (ret);
7621   return ret;
7622 }
7623
7624 static int
7625 api_l2_flags (vat_main_t * vam)
7626 {
7627   unformat_input_t *i = vam->input;
7628   vl_api_l2_flags_t *mp;
7629   u32 sw_if_index;
7630   u32 flags = 0;
7631   u8 sw_if_index_set = 0;
7632   u8 is_set = 0;
7633   int ret;
7634
7635   /* Parse args required to build the message */
7636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7637     {
7638       if (unformat (i, "sw_if_index %d", &sw_if_index))
7639         sw_if_index_set = 1;
7640       else if (unformat (i, "sw_if"))
7641         {
7642           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643             {
7644               if (unformat
7645                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7646                 sw_if_index_set = 1;
7647             }
7648           else
7649             break;
7650         }
7651       else if (unformat (i, "learn"))
7652         flags |= L2_LEARN;
7653       else if (unformat (i, "forward"))
7654         flags |= L2_FWD;
7655       else if (unformat (i, "flood"))
7656         flags |= L2_FLOOD;
7657       else if (unformat (i, "uu-flood"))
7658         flags |= L2_UU_FLOOD;
7659       else if (unformat (i, "arp-term"))
7660         flags |= L2_ARP_TERM;
7661       else if (unformat (i, "off"))
7662         is_set = 0;
7663       else if (unformat (i, "disable"))
7664         is_set = 0;
7665       else
7666         break;
7667     }
7668
7669   if (sw_if_index_set == 0)
7670     {
7671       errmsg ("missing interface name or sw_if_index");
7672       return -99;
7673     }
7674
7675   M (L2_FLAGS, mp);
7676
7677   mp->sw_if_index = ntohl (sw_if_index);
7678   mp->feature_bitmap = ntohl (flags);
7679   mp->is_set = is_set;
7680
7681   S (mp);
7682   W (ret);
7683   return ret;
7684 }
7685
7686 static int
7687 api_bridge_flags (vat_main_t * vam)
7688 {
7689   unformat_input_t *i = vam->input;
7690   vl_api_bridge_flags_t *mp;
7691   u32 bd_id;
7692   u8 bd_id_set = 0;
7693   u8 is_set = 1;
7694   bd_flags_t flags = 0;
7695   int ret;
7696
7697   /* Parse args required to build the message */
7698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7699     {
7700       if (unformat (i, "bd_id %d", &bd_id))
7701         bd_id_set = 1;
7702       else if (unformat (i, "learn"))
7703         flags |= BRIDGE_API_FLAG_LEARN;
7704       else if (unformat (i, "forward"))
7705         flags |= BRIDGE_API_FLAG_FWD;
7706       else if (unformat (i, "flood"))
7707         flags |= BRIDGE_API_FLAG_FLOOD;
7708       else if (unformat (i, "uu-flood"))
7709         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7710       else if (unformat (i, "arp-term"))
7711         flags |= BRIDGE_API_FLAG_ARP_TERM;
7712       else if (unformat (i, "off"))
7713         is_set = 0;
7714       else if (unformat (i, "disable"))
7715         is_set = 0;
7716       else
7717         break;
7718     }
7719
7720   if (bd_id_set == 0)
7721     {
7722       errmsg ("missing bridge domain");
7723       return -99;
7724     }
7725
7726   M (BRIDGE_FLAGS, mp);
7727
7728   mp->bd_id = ntohl (bd_id);
7729   mp->flags = ntohl (flags);
7730   mp->is_set = is_set;
7731
7732   S (mp);
7733   W (ret);
7734   return ret;
7735 }
7736
7737 static int
7738 api_bd_ip_mac_add_del (vat_main_t * vam)
7739 {
7740   unformat_input_t *i = vam->input;
7741   vl_api_bd_ip_mac_add_del_t *mp;
7742   u32 bd_id;
7743   u8 is_ipv6 = 0;
7744   u8 is_add = 1;
7745   u8 bd_id_set = 0;
7746   u8 ip_set = 0;
7747   u8 mac_set = 0;
7748   ip4_address_t v4addr;
7749   ip6_address_t v6addr;
7750   u8 macaddr[6];
7751   int ret;
7752
7753
7754   /* Parse args required to build the message */
7755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7756     {
7757       if (unformat (i, "bd_id %d", &bd_id))
7758         {
7759           bd_id_set++;
7760         }
7761       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7762         {
7763           ip_set++;
7764         }
7765       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7766         {
7767           ip_set++;
7768           is_ipv6++;
7769         }
7770       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7771         {
7772           mac_set++;
7773         }
7774       else if (unformat (i, "del"))
7775         is_add = 0;
7776       else
7777         break;
7778     }
7779
7780   if (bd_id_set == 0)
7781     {
7782       errmsg ("missing bridge domain");
7783       return -99;
7784     }
7785   else if (ip_set == 0)
7786     {
7787       errmsg ("missing IP address");
7788       return -99;
7789     }
7790   else if (mac_set == 0)
7791     {
7792       errmsg ("missing MAC address");
7793       return -99;
7794     }
7795
7796   M (BD_IP_MAC_ADD_DEL, mp);
7797
7798   mp->bd_id = ntohl (bd_id);
7799   mp->is_ipv6 = is_ipv6;
7800   mp->is_add = is_add;
7801   if (is_ipv6)
7802     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7803   else
7804     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7805   clib_memcpy (mp->mac_address, macaddr, 6);
7806   S (mp);
7807   W (ret);
7808   return ret;
7809 }
7810
7811 static void vl_api_bd_ip_mac_details_t_handler
7812   (vl_api_bd_ip_mac_details_t * mp)
7813 {
7814   vat_main_t *vam = &vat_main;
7815   u8 *ip = 0;
7816
7817   if (!mp->is_ipv6)
7818     ip =
7819       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7820   else
7821     ip =
7822       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7823
7824   print (vam->ofp,
7825          "\n%-5d %-7s %-20U %-30s",
7826          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7827          format_ethernet_address, mp->mac_address, ip);
7828
7829   vec_free (ip);
7830 }
7831
7832 static void vl_api_bd_ip_mac_details_t_handler_json
7833   (vl_api_bd_ip_mac_details_t * mp)
7834 {
7835   vat_main_t *vam = &vat_main;
7836   vat_json_node_t *node = NULL;
7837
7838   if (VAT_JSON_ARRAY != vam->json_tree.type)
7839     {
7840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7841       vat_json_init_array (&vam->json_tree);
7842     }
7843   node = vat_json_array_add (&vam->json_tree);
7844
7845   vat_json_init_object (node);
7846   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7847   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7848   vat_json_object_add_string_copy (node, "mac_address",
7849                                    format (0, "%U", format_ethernet_address,
7850                                            &mp->mac_address));
7851   u8 *ip = 0;
7852
7853   if (!mp->is_ipv6)
7854     ip =
7855       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7856   else
7857     ip =
7858       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7859   vat_json_object_add_string_copy (node, "ip_address", ip);
7860   vec_free (ip);
7861 }
7862
7863 static int
7864 api_bd_ip_mac_dump (vat_main_t * vam)
7865 {
7866   unformat_input_t *i = vam->input;
7867   vl_api_bd_ip_mac_dump_t *mp;
7868   vl_api_control_ping_t *mp_ping;
7869   int ret;
7870   u32 bd_id;
7871   u8 bd_id_set = 0;
7872
7873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7874     {
7875       if (unformat (i, "bd_id %d", &bd_id))
7876         {
7877           bd_id_set++;
7878         }
7879       else
7880         break;
7881     }
7882
7883   print (vam->ofp,
7884          "\n%-5s %-7s %-20s %-30s",
7885          "bd_id", "is_ipv6", "mac_address", "ip_address");
7886
7887   /* Dump Bridge Domain Ip to Mac entries */
7888   M (BD_IP_MAC_DUMP, mp);
7889
7890   if (bd_id_set)
7891     mp->bd_id = htonl (bd_id);
7892   else
7893     mp->bd_id = ~0;
7894
7895   S (mp);
7896
7897   /* Use a control ping for synchronization */
7898   MPING (CONTROL_PING, mp_ping);
7899   S (mp_ping);
7900
7901   W (ret);
7902   return ret;
7903 }
7904
7905 static int
7906 api_tap_connect (vat_main_t * vam)
7907 {
7908   unformat_input_t *i = vam->input;
7909   vl_api_tap_connect_t *mp;
7910   u8 mac_address[6];
7911   u8 random_mac = 1;
7912   u8 name_set = 0;
7913   u8 *tap_name;
7914   u8 *tag = 0;
7915   ip4_address_t ip4_address;
7916   u32 ip4_mask_width;
7917   int ip4_address_set = 0;
7918   ip6_address_t ip6_address;
7919   u32 ip6_mask_width;
7920   int ip6_address_set = 0;
7921   int ret;
7922
7923   memset (mac_address, 0, sizeof (mac_address));
7924
7925   /* Parse args required to build the message */
7926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7927     {
7928       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7929         {
7930           random_mac = 0;
7931         }
7932       else if (unformat (i, "random-mac"))
7933         random_mac = 1;
7934       else if (unformat (i, "tapname %s", &tap_name))
7935         name_set = 1;
7936       else if (unformat (i, "tag %s", &tag))
7937         ;
7938       else if (unformat (i, "address %U/%d",
7939                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7940         ip4_address_set = 1;
7941       else if (unformat (i, "address %U/%d",
7942                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7943         ip6_address_set = 1;
7944       else
7945         break;
7946     }
7947
7948   if (name_set == 0)
7949     {
7950       errmsg ("missing tap name");
7951       return -99;
7952     }
7953   if (vec_len (tap_name) > 63)
7954     {
7955       errmsg ("tap name too long");
7956       return -99;
7957     }
7958   vec_add1 (tap_name, 0);
7959
7960   if (vec_len (tag) > 63)
7961     {
7962       errmsg ("tag too long");
7963       return -99;
7964     }
7965
7966   /* Construct the API message */
7967   M (TAP_CONNECT, mp);
7968
7969   mp->use_random_mac = random_mac;
7970   clib_memcpy (mp->mac_address, mac_address, 6);
7971   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7972   if (tag)
7973     clib_memcpy (mp->tag, tag, vec_len (tag));
7974
7975   if (ip4_address_set)
7976     {
7977       mp->ip4_address_set = 1;
7978       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7979       mp->ip4_mask_width = ip4_mask_width;
7980     }
7981   if (ip6_address_set)
7982     {
7983       mp->ip6_address_set = 1;
7984       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7985       mp->ip6_mask_width = ip6_mask_width;
7986     }
7987
7988   vec_free (tap_name);
7989   vec_free (tag);
7990
7991   /* send it... */
7992   S (mp);
7993
7994   /* Wait for a reply... */
7995   W (ret);
7996   return ret;
7997 }
7998
7999 static int
8000 api_tap_modify (vat_main_t * vam)
8001 {
8002   unformat_input_t *i = vam->input;
8003   vl_api_tap_modify_t *mp;
8004   u8 mac_address[6];
8005   u8 random_mac = 1;
8006   u8 name_set = 0;
8007   u8 *tap_name;
8008   u32 sw_if_index = ~0;
8009   u8 sw_if_index_set = 0;
8010   int ret;
8011
8012   memset (mac_address, 0, sizeof (mac_address));
8013
8014   /* Parse args required to build the message */
8015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8016     {
8017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8018         sw_if_index_set = 1;
8019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8020         sw_if_index_set = 1;
8021       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8022         {
8023           random_mac = 0;
8024         }
8025       else if (unformat (i, "random-mac"))
8026         random_mac = 1;
8027       else if (unformat (i, "tapname %s", &tap_name))
8028         name_set = 1;
8029       else
8030         break;
8031     }
8032
8033   if (sw_if_index_set == 0)
8034     {
8035       errmsg ("missing vpp interface name");
8036       return -99;
8037     }
8038   if (name_set == 0)
8039     {
8040       errmsg ("missing tap name");
8041       return -99;
8042     }
8043   if (vec_len (tap_name) > 63)
8044     {
8045       errmsg ("tap name too long");
8046     }
8047   vec_add1 (tap_name, 0);
8048
8049   /* Construct the API message */
8050   M (TAP_MODIFY, mp);
8051
8052   mp->use_random_mac = random_mac;
8053   mp->sw_if_index = ntohl (sw_if_index);
8054   clib_memcpy (mp->mac_address, mac_address, 6);
8055   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8056   vec_free (tap_name);
8057
8058   /* send it... */
8059   S (mp);
8060
8061   /* Wait for a reply... */
8062   W (ret);
8063   return ret;
8064 }
8065
8066 static int
8067 api_tap_delete (vat_main_t * vam)
8068 {
8069   unformat_input_t *i = vam->input;
8070   vl_api_tap_delete_t *mp;
8071   u32 sw_if_index = ~0;
8072   u8 sw_if_index_set = 0;
8073   int ret;
8074
8075   /* Parse args required to build the message */
8076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8077     {
8078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8079         sw_if_index_set = 1;
8080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8081         sw_if_index_set = 1;
8082       else
8083         break;
8084     }
8085
8086   if (sw_if_index_set == 0)
8087     {
8088       errmsg ("missing vpp interface name");
8089       return -99;
8090     }
8091
8092   /* Construct the API message */
8093   M (TAP_DELETE, mp);
8094
8095   mp->sw_if_index = ntohl (sw_if_index);
8096
8097   /* send it... */
8098   S (mp);
8099
8100   /* Wait for a reply... */
8101   W (ret);
8102   return ret;
8103 }
8104
8105 static int
8106 api_tap_create_v2 (vat_main_t * vam)
8107 {
8108   unformat_input_t *i = vam->input;
8109   vl_api_tap_create_v2_t *mp;
8110   u8 mac_address[6];
8111   u8 random_mac = 1;
8112   u32 id = ~0;
8113   u8 *host_if_name = 0;
8114   u8 *host_ns = 0;
8115   u8 host_mac_addr[6];
8116   u8 host_mac_addr_set = 0;
8117   u8 *host_bridge = 0;
8118   ip4_address_t host_ip4_addr;
8119   ip4_address_t host_ip4_gw;
8120   u8 host_ip4_gw_set = 0;
8121   u32 host_ip4_prefix_len = 0;
8122   ip6_address_t host_ip6_addr;
8123   ip6_address_t host_ip6_gw;
8124   u8 host_ip6_gw_set = 0;
8125   u32 host_ip6_prefix_len = 0;
8126   int ret;
8127   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8128
8129   memset (mac_address, 0, sizeof (mac_address));
8130
8131   /* Parse args required to build the message */
8132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8133     {
8134       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8135         {
8136           random_mac = 0;
8137         }
8138       else if (unformat (i, "id %u", &id))
8139         ;
8140       else if (unformat (i, "host-if-name %s", &host_if_name))
8141         ;
8142       else if (unformat (i, "host-ns %s", &host_ns))
8143         ;
8144       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8145                          host_mac_addr))
8146         host_mac_addr_set = 1;
8147       else if (unformat (i, "host-bridge %s", &host_bridge))
8148         ;
8149       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8150                          &host_ip4_addr, &host_ip4_prefix_len))
8151         ;
8152       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8153                          &host_ip6_addr, &host_ip6_prefix_len))
8154         ;
8155       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8156                          &host_ip4_gw))
8157         host_ip4_gw_set = 1;
8158       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8159                          &host_ip6_gw))
8160         host_ip6_gw_set = 1;
8161       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8162         ;
8163       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8164         ;
8165       else
8166         break;
8167     }
8168
8169   if (vec_len (host_if_name) > 63)
8170     {
8171       errmsg ("tap name too long. ");
8172       return -99;
8173     }
8174   if (vec_len (host_ns) > 63)
8175     {
8176       errmsg ("host name space too long. ");
8177       return -99;
8178     }
8179   if (vec_len (host_bridge) > 63)
8180     {
8181       errmsg ("host bridge name too long. ");
8182       return -99;
8183     }
8184   if (host_ip4_prefix_len > 32)
8185     {
8186       errmsg ("host ip4 prefix length not valid. ");
8187       return -99;
8188     }
8189   if (host_ip6_prefix_len > 128)
8190     {
8191       errmsg ("host ip6 prefix length not valid. ");
8192       return -99;
8193     }
8194   if (!is_pow2 (rx_ring_sz))
8195     {
8196       errmsg ("rx ring size must be power of 2. ");
8197       return -99;
8198     }
8199   if (rx_ring_sz > 32768)
8200     {
8201       errmsg ("rx ring size must be 32768 or lower. ");
8202       return -99;
8203     }
8204   if (!is_pow2 (tx_ring_sz))
8205     {
8206       errmsg ("tx ring size must be power of 2. ");
8207       return -99;
8208     }
8209   if (tx_ring_sz > 32768)
8210     {
8211       errmsg ("tx ring size must be 32768 or lower. ");
8212       return -99;
8213     }
8214
8215   /* Construct the API message */
8216   M (TAP_CREATE_V2, mp);
8217
8218   mp->use_random_mac = random_mac;
8219
8220   mp->id = ntohl (id);
8221   mp->host_namespace_set = host_ns != 0;
8222   mp->host_bridge_set = host_bridge != 0;
8223   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8224   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8225   mp->rx_ring_sz = ntohs (rx_ring_sz);
8226   mp->tx_ring_sz = ntohs (tx_ring_sz);
8227
8228   if (random_mac == 0)
8229     clib_memcpy (mp->mac_address, mac_address, 6);
8230   if (host_mac_addr_set)
8231     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8232   if (host_if_name)
8233     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8234   if (host_ns)
8235     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8236   if (host_bridge)
8237     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8238   if (host_ip4_prefix_len)
8239     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8240   if (host_ip4_prefix_len)
8241     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8242   if (host_ip4_gw_set)
8243     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8244   if (host_ip6_gw_set)
8245     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8246
8247   vec_free (host_ns);
8248   vec_free (host_if_name);
8249   vec_free (host_bridge);
8250
8251   /* send it... */
8252   S (mp);
8253
8254   /* Wait for a reply... */
8255   W (ret);
8256   return ret;
8257 }
8258
8259 static int
8260 api_tap_delete_v2 (vat_main_t * vam)
8261 {
8262   unformat_input_t *i = vam->input;
8263   vl_api_tap_delete_v2_t *mp;
8264   u32 sw_if_index = ~0;
8265   u8 sw_if_index_set = 0;
8266   int ret;
8267
8268   /* Parse args required to build the message */
8269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8270     {
8271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8272         sw_if_index_set = 1;
8273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8274         sw_if_index_set = 1;
8275       else
8276         break;
8277     }
8278
8279   if (sw_if_index_set == 0)
8280     {
8281       errmsg ("missing vpp interface name. ");
8282       return -99;
8283     }
8284
8285   /* Construct the API message */
8286   M (TAP_DELETE_V2, mp);
8287
8288   mp->sw_if_index = ntohl (sw_if_index);
8289
8290   /* send it... */
8291   S (mp);
8292
8293   /* Wait for a reply... */
8294   W (ret);
8295   return ret;
8296 }
8297
8298 static int
8299 api_bond_create (vat_main_t * vam)
8300 {
8301   unformat_input_t *i = vam->input;
8302   vl_api_bond_create_t *mp;
8303   u8 mac_address[6];
8304   u8 custom_mac = 0;
8305   int ret;
8306   u8 mode;
8307   u8 lb;
8308   u8 mode_is_set = 0;
8309
8310   memset (mac_address, 0, sizeof (mac_address));
8311   lb = BOND_LB_L2;
8312
8313   /* Parse args required to build the message */
8314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8315     {
8316       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8317         mode_is_set = 1;
8318       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8319                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8320         ;
8321       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8322                          mac_address))
8323         custom_mac = 1;
8324       else
8325         break;
8326     }
8327
8328   if (mode_is_set == 0)
8329     {
8330       errmsg ("Missing bond mode. ");
8331       return -99;
8332     }
8333
8334   /* Construct the API message */
8335   M (BOND_CREATE, mp);
8336
8337   mp->use_custom_mac = custom_mac;
8338
8339   mp->mode = mode;
8340   mp->lb = lb;
8341
8342   if (custom_mac)
8343     clib_memcpy (mp->mac_address, mac_address, 6);
8344
8345   /* send it... */
8346   S (mp);
8347
8348   /* Wait for a reply... */
8349   W (ret);
8350   return ret;
8351 }
8352
8353 static int
8354 api_bond_delete (vat_main_t * vam)
8355 {
8356   unformat_input_t *i = vam->input;
8357   vl_api_bond_delete_t *mp;
8358   u32 sw_if_index = ~0;
8359   u8 sw_if_index_set = 0;
8360   int ret;
8361
8362   /* Parse args required to build the message */
8363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8364     {
8365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8366         sw_if_index_set = 1;
8367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8368         sw_if_index_set = 1;
8369       else
8370         break;
8371     }
8372
8373   if (sw_if_index_set == 0)
8374     {
8375       errmsg ("missing vpp interface name. ");
8376       return -99;
8377     }
8378
8379   /* Construct the API message */
8380   M (BOND_DELETE, mp);
8381
8382   mp->sw_if_index = ntohl (sw_if_index);
8383
8384   /* send it... */
8385   S (mp);
8386
8387   /* Wait for a reply... */
8388   W (ret);
8389   return ret;
8390 }
8391
8392 static int
8393 api_bond_enslave (vat_main_t * vam)
8394 {
8395   unformat_input_t *i = vam->input;
8396   vl_api_bond_enslave_t *mp;
8397   u32 bond_sw_if_index;
8398   int ret;
8399   u8 is_passive;
8400   u8 is_long_timeout;
8401   u32 bond_sw_if_index_is_set = 0;
8402   u32 sw_if_index;
8403   u8 sw_if_index_is_set = 0;
8404
8405   /* Parse args required to build the message */
8406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8407     {
8408       if (unformat (i, "sw_if_index %d", &sw_if_index))
8409         sw_if_index_is_set = 1;
8410       else if (unformat (i, "bond %u", &bond_sw_if_index))
8411         bond_sw_if_index_is_set = 1;
8412       else if (unformat (i, "passive %d", &is_passive))
8413         ;
8414       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8415         ;
8416       else
8417         break;
8418     }
8419
8420   if (bond_sw_if_index_is_set == 0)
8421     {
8422       errmsg ("Missing bond sw_if_index. ");
8423       return -99;
8424     }
8425   if (sw_if_index_is_set == 0)
8426     {
8427       errmsg ("Missing slave sw_if_index. ");
8428       return -99;
8429     }
8430
8431   /* Construct the API message */
8432   M (BOND_ENSLAVE, mp);
8433
8434   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8435   mp->sw_if_index = ntohl (sw_if_index);
8436   mp->is_long_timeout = is_long_timeout;
8437   mp->is_passive = is_passive;
8438
8439   /* send it... */
8440   S (mp);
8441
8442   /* Wait for a reply... */
8443   W (ret);
8444   return ret;
8445 }
8446
8447 static int
8448 api_bond_detach_slave (vat_main_t * vam)
8449 {
8450   unformat_input_t *i = vam->input;
8451   vl_api_bond_detach_slave_t *mp;
8452   u32 sw_if_index = ~0;
8453   u8 sw_if_index_set = 0;
8454   int ret;
8455
8456   /* Parse args required to build the message */
8457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8458     {
8459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8460         sw_if_index_set = 1;
8461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8462         sw_if_index_set = 1;
8463       else
8464         break;
8465     }
8466
8467   if (sw_if_index_set == 0)
8468     {
8469       errmsg ("missing vpp interface name. ");
8470       return -99;
8471     }
8472
8473   /* Construct the API message */
8474   M (BOND_DETACH_SLAVE, mp);
8475
8476   mp->sw_if_index = ntohl (sw_if_index);
8477
8478   /* send it... */
8479   S (mp);
8480
8481   /* Wait for a reply... */
8482   W (ret);
8483   return ret;
8484 }
8485
8486 static int
8487 api_ip_table_add_del (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_ip_table_add_del_t *mp;
8491   u32 table_id = ~0;
8492   u8 is_ipv6 = 0;
8493   u8 is_add = 1;
8494   int ret = 0;
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "ipv6"))
8500         is_ipv6 = 1;
8501       else if (unformat (i, "del"))
8502         is_add = 0;
8503       else if (unformat (i, "add"))
8504         is_add = 1;
8505       else if (unformat (i, "table %d", &table_id))
8506         ;
8507       else
8508         {
8509           clib_warning ("parse error '%U'", format_unformat_error, i);
8510           return -99;
8511         }
8512     }
8513
8514   if (~0 == table_id)
8515     {
8516       errmsg ("missing table-ID");
8517       return -99;
8518     }
8519
8520   /* Construct the API message */
8521   M (IP_TABLE_ADD_DEL, mp);
8522
8523   mp->table_id = ntohl (table_id);
8524   mp->is_ipv6 = is_ipv6;
8525   mp->is_add = is_add;
8526
8527   /* send it... */
8528   S (mp);
8529
8530   /* Wait for a reply... */
8531   W (ret);
8532
8533   return ret;
8534 }
8535
8536 static int
8537 api_ip_add_del_route (vat_main_t * vam)
8538 {
8539   unformat_input_t *i = vam->input;
8540   vl_api_ip_add_del_route_t *mp;
8541   u32 sw_if_index = ~0, vrf_id = 0;
8542   u8 is_ipv6 = 0;
8543   u8 is_local = 0, is_drop = 0;
8544   u8 is_unreach = 0, is_prohibit = 0;
8545   u8 is_add = 1;
8546   u32 next_hop_weight = 1;
8547   u8 is_multipath = 0;
8548   u8 address_set = 0;
8549   u8 address_length_set = 0;
8550   u32 next_hop_table_id = 0;
8551   u32 resolve_attempts = 0;
8552   u32 dst_address_length = 0;
8553   u8 next_hop_set = 0;
8554   ip4_address_t v4_dst_address, v4_next_hop_address;
8555   ip6_address_t v6_dst_address, v6_next_hop_address;
8556   int count = 1;
8557   int j;
8558   f64 before = 0;
8559   u32 random_add_del = 0;
8560   u32 *random_vector = 0;
8561   uword *random_hash;
8562   u32 random_seed = 0xdeaddabe;
8563   u32 classify_table_index = ~0;
8564   u8 is_classify = 0;
8565   u8 resolve_host = 0, resolve_attached = 0;
8566   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8567   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8568   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8569
8570   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8571   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8572   /* Parse args required to build the message */
8573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8574     {
8575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8576         ;
8577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8578         ;
8579       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8580         {
8581           address_set = 1;
8582           is_ipv6 = 0;
8583         }
8584       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8585         {
8586           address_set = 1;
8587           is_ipv6 = 1;
8588         }
8589       else if (unformat (i, "/%d", &dst_address_length))
8590         {
8591           address_length_set = 1;
8592         }
8593
8594       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8595                                          &v4_next_hop_address))
8596         {
8597           next_hop_set = 1;
8598         }
8599       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8600                                          &v6_next_hop_address))
8601         {
8602           next_hop_set = 1;
8603         }
8604       else
8605         if (unformat
8606             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8607         {
8608           next_hop_set = 1;
8609         }
8610       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8611         {
8612           next_hop_set = 1;
8613         }
8614       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8615         ;
8616       else if (unformat (i, "weight %d", &next_hop_weight))
8617         ;
8618       else if (unformat (i, "drop"))
8619         {
8620           is_drop = 1;
8621         }
8622       else if (unformat (i, "null-send-unreach"))
8623         {
8624           is_unreach = 1;
8625         }
8626       else if (unformat (i, "null-send-prohibit"))
8627         {
8628           is_prohibit = 1;
8629         }
8630       else if (unformat (i, "local"))
8631         {
8632           is_local = 1;
8633         }
8634       else if (unformat (i, "classify %d", &classify_table_index))
8635         {
8636           is_classify = 1;
8637         }
8638       else if (unformat (i, "del"))
8639         is_add = 0;
8640       else if (unformat (i, "add"))
8641         is_add = 1;
8642       else if (unformat (i, "resolve-via-host"))
8643         resolve_host = 1;
8644       else if (unformat (i, "resolve-via-attached"))
8645         resolve_attached = 1;
8646       else if (unformat (i, "multipath"))
8647         is_multipath = 1;
8648       else if (unformat (i, "vrf %d", &vrf_id))
8649         ;
8650       else if (unformat (i, "count %d", &count))
8651         ;
8652       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8653         ;
8654       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8655         ;
8656       else if (unformat (i, "out-label %d", &next_hop_out_label))
8657         {
8658           vl_api_fib_mpls_label_t fib_label = {
8659             .label = ntohl (next_hop_out_label),
8660             .ttl = 64,
8661             .exp = 0,
8662           };
8663           vec_add1 (next_hop_out_label_stack, fib_label);
8664         }
8665       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8666         ;
8667       else if (unformat (i, "random"))
8668         random_add_del = 1;
8669       else if (unformat (i, "seed %d", &random_seed))
8670         ;
8671       else
8672         {
8673           clib_warning ("parse error '%U'", format_unformat_error, i);
8674           return -99;
8675         }
8676     }
8677
8678   if (!next_hop_set && !is_drop && !is_local &&
8679       !is_classify && !is_unreach && !is_prohibit &&
8680       MPLS_LABEL_INVALID == next_hop_via_label)
8681     {
8682       errmsg
8683         ("next hop / local / drop / unreach / prohibit / classify not set");
8684       return -99;
8685     }
8686
8687   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8688     {
8689       errmsg ("next hop and next-hop via label set");
8690       return -99;
8691     }
8692   if (address_set == 0)
8693     {
8694       errmsg ("missing addresses");
8695       return -99;
8696     }
8697
8698   if (address_length_set == 0)
8699     {
8700       errmsg ("missing address length");
8701       return -99;
8702     }
8703
8704   /* Generate a pile of unique, random routes */
8705   if (random_add_del)
8706     {
8707       u32 this_random_address;
8708       random_hash = hash_create (count, sizeof (uword));
8709
8710       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8711       for (j = 0; j <= count; j++)
8712         {
8713           do
8714             {
8715               this_random_address = random_u32 (&random_seed);
8716               this_random_address =
8717                 clib_host_to_net_u32 (this_random_address);
8718             }
8719           while (hash_get (random_hash, this_random_address));
8720           vec_add1 (random_vector, this_random_address);
8721           hash_set (random_hash, this_random_address, 1);
8722         }
8723       hash_free (random_hash);
8724       v4_dst_address.as_u32 = random_vector[0];
8725     }
8726
8727   if (count > 1)
8728     {
8729       /* Turn on async mode */
8730       vam->async_mode = 1;
8731       vam->async_errors = 0;
8732       before = vat_time_now (vam);
8733     }
8734
8735   for (j = 0; j < count; j++)
8736     {
8737       /* Construct the API message */
8738       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8739           vec_len (next_hop_out_label_stack));
8740
8741       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8742       mp->table_id = ntohl (vrf_id);
8743
8744       mp->is_add = is_add;
8745       mp->is_drop = is_drop;
8746       mp->is_unreach = is_unreach;
8747       mp->is_prohibit = is_prohibit;
8748       mp->is_ipv6 = is_ipv6;
8749       mp->is_local = is_local;
8750       mp->is_classify = is_classify;
8751       mp->is_multipath = is_multipath;
8752       mp->is_resolve_host = resolve_host;
8753       mp->is_resolve_attached = resolve_attached;
8754       mp->next_hop_weight = next_hop_weight;
8755       mp->dst_address_length = dst_address_length;
8756       mp->next_hop_table_id = ntohl (next_hop_table_id);
8757       mp->classify_table_index = ntohl (classify_table_index);
8758       mp->next_hop_via_label = ntohl (next_hop_via_label);
8759       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8760       if (0 != mp->next_hop_n_out_labels)
8761         {
8762           memcpy (mp->next_hop_out_label_stack,
8763                   next_hop_out_label_stack,
8764                   (vec_len (next_hop_out_label_stack) *
8765                    sizeof (vl_api_fib_mpls_label_t)));
8766           vec_free (next_hop_out_label_stack);
8767         }
8768
8769       if (is_ipv6)
8770         {
8771           clib_memcpy (mp->dst_address, &v6_dst_address,
8772                        sizeof (v6_dst_address));
8773           if (next_hop_set)
8774             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8775                          sizeof (v6_next_hop_address));
8776           increment_v6_address (&v6_dst_address);
8777         }
8778       else
8779         {
8780           clib_memcpy (mp->dst_address, &v4_dst_address,
8781                        sizeof (v4_dst_address));
8782           if (next_hop_set)
8783             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8784                          sizeof (v4_next_hop_address));
8785           if (random_add_del)
8786             v4_dst_address.as_u32 = random_vector[j + 1];
8787           else
8788             increment_v4_address (&v4_dst_address);
8789         }
8790       /* send it... */
8791       S (mp);
8792       /* If we receive SIGTERM, stop now... */
8793       if (vam->do_exit)
8794         break;
8795     }
8796
8797   /* When testing multiple add/del ops, use a control-ping to sync */
8798   if (count > 1)
8799     {
8800       vl_api_control_ping_t *mp_ping;
8801       f64 after;
8802       f64 timeout;
8803
8804       /* Shut off async mode */
8805       vam->async_mode = 0;
8806
8807       MPING (CONTROL_PING, mp_ping);
8808       S (mp_ping);
8809
8810       timeout = vat_time_now (vam) + 1.0;
8811       while (vat_time_now (vam) < timeout)
8812         if (vam->result_ready == 1)
8813           goto out;
8814       vam->retval = -99;
8815
8816     out:
8817       if (vam->retval == -99)
8818         errmsg ("timeout");
8819
8820       if (vam->async_errors > 0)
8821         {
8822           errmsg ("%d asynchronous errors", vam->async_errors);
8823           vam->retval = -98;
8824         }
8825       vam->async_errors = 0;
8826       after = vat_time_now (vam);
8827
8828       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8829       if (j > 0)
8830         count = j;
8831
8832       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8833              count, after - before, count / (after - before));
8834     }
8835   else
8836     {
8837       int ret;
8838
8839       /* Wait for a reply... */
8840       W (ret);
8841       return ret;
8842     }
8843
8844   /* Return the good/bad news */
8845   return (vam->retval);
8846 }
8847
8848 static int
8849 api_ip_mroute_add_del (vat_main_t * vam)
8850 {
8851   unformat_input_t *i = vam->input;
8852   vl_api_ip_mroute_add_del_t *mp;
8853   u32 sw_if_index = ~0, vrf_id = 0;
8854   u8 is_ipv6 = 0;
8855   u8 is_local = 0;
8856   u8 is_add = 1;
8857   u8 address_set = 0;
8858   u32 grp_address_length = 0;
8859   ip4_address_t v4_grp_address, v4_src_address;
8860   ip6_address_t v6_grp_address, v6_src_address;
8861   mfib_itf_flags_t iflags = 0;
8862   mfib_entry_flags_t eflags = 0;
8863   int ret;
8864
8865   /* Parse args required to build the message */
8866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8867     {
8868       if (unformat (i, "sw_if_index %d", &sw_if_index))
8869         ;
8870       else if (unformat (i, "%U %U",
8871                          unformat_ip4_address, &v4_src_address,
8872                          unformat_ip4_address, &v4_grp_address))
8873         {
8874           grp_address_length = 64;
8875           address_set = 1;
8876           is_ipv6 = 0;
8877         }
8878       else if (unformat (i, "%U %U",
8879                          unformat_ip6_address, &v6_src_address,
8880                          unformat_ip6_address, &v6_grp_address))
8881         {
8882           grp_address_length = 256;
8883           address_set = 1;
8884           is_ipv6 = 1;
8885         }
8886       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8887         {
8888           memset (&v4_src_address, 0, sizeof (v4_src_address));
8889           grp_address_length = 32;
8890           address_set = 1;
8891           is_ipv6 = 0;
8892         }
8893       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8894         {
8895           memset (&v6_src_address, 0, sizeof (v6_src_address));
8896           grp_address_length = 128;
8897           address_set = 1;
8898           is_ipv6 = 1;
8899         }
8900       else if (unformat (i, "/%d", &grp_address_length))
8901         ;
8902       else if (unformat (i, "local"))
8903         {
8904           is_local = 1;
8905         }
8906       else if (unformat (i, "del"))
8907         is_add = 0;
8908       else if (unformat (i, "add"))
8909         is_add = 1;
8910       else if (unformat (i, "vrf %d", &vrf_id))
8911         ;
8912       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8913         ;
8914       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8915         ;
8916       else
8917         {
8918           clib_warning ("parse error '%U'", format_unformat_error, i);
8919           return -99;
8920         }
8921     }
8922
8923   if (address_set == 0)
8924     {
8925       errmsg ("missing addresses\n");
8926       return -99;
8927     }
8928
8929   /* Construct the API message */
8930   M (IP_MROUTE_ADD_DEL, mp);
8931
8932   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8933   mp->table_id = ntohl (vrf_id);
8934
8935   mp->is_add = is_add;
8936   mp->is_ipv6 = is_ipv6;
8937   mp->is_local = is_local;
8938   mp->itf_flags = ntohl (iflags);
8939   mp->entry_flags = ntohl (eflags);
8940   mp->grp_address_length = grp_address_length;
8941   mp->grp_address_length = ntohs (mp->grp_address_length);
8942
8943   if (is_ipv6)
8944     {
8945       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8946       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8947     }
8948   else
8949     {
8950       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8951       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8952
8953     }
8954
8955   /* send it... */
8956   S (mp);
8957   /* Wait for a reply... */
8958   W (ret);
8959   return ret;
8960 }
8961
8962 static int
8963 api_mpls_table_add_del (vat_main_t * vam)
8964 {
8965   unformat_input_t *i = vam->input;
8966   vl_api_mpls_table_add_del_t *mp;
8967   u32 table_id = ~0;
8968   u8 is_add = 1;
8969   int ret = 0;
8970
8971   /* Parse args required to build the message */
8972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8973     {
8974       if (unformat (i, "table %d", &table_id))
8975         ;
8976       else if (unformat (i, "del"))
8977         is_add = 0;
8978       else if (unformat (i, "add"))
8979         is_add = 1;
8980       else
8981         {
8982           clib_warning ("parse error '%U'", format_unformat_error, i);
8983           return -99;
8984         }
8985     }
8986
8987   if (~0 == table_id)
8988     {
8989       errmsg ("missing table-ID");
8990       return -99;
8991     }
8992
8993   /* Construct the API message */
8994   M (MPLS_TABLE_ADD_DEL, mp);
8995
8996   mp->mt_table_id = ntohl (table_id);
8997   mp->mt_is_add = is_add;
8998
8999   /* send it... */
9000   S (mp);
9001
9002   /* Wait for a reply... */
9003   W (ret);
9004
9005   return ret;
9006 }
9007
9008 static int
9009 api_mpls_route_add_del (vat_main_t * vam)
9010 {
9011   unformat_input_t *i = vam->input;
9012   vl_api_mpls_route_add_del_t *mp;
9013   u32 sw_if_index = ~0, table_id = 0;
9014   u8 is_add = 1;
9015   u32 next_hop_weight = 1;
9016   u8 is_multipath = 0;
9017   u32 next_hop_table_id = 0;
9018   u8 next_hop_set = 0;
9019   ip4_address_t v4_next_hop_address = {
9020     .as_u32 = 0,
9021   };
9022   ip6_address_t v6_next_hop_address = { {0} };
9023   int count = 1;
9024   int j;
9025   f64 before = 0;
9026   u32 classify_table_index = ~0;
9027   u8 is_classify = 0;
9028   u8 resolve_host = 0, resolve_attached = 0;
9029   u8 is_interface_rx = 0;
9030   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9031   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9032   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9033   mpls_label_t local_label = MPLS_LABEL_INVALID;
9034   u8 is_eos = 0;
9035   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9036
9037   /* Parse args required to build the message */
9038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9039     {
9040       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9041         ;
9042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9043         ;
9044       else if (unformat (i, "%d", &local_label))
9045         ;
9046       else if (unformat (i, "eos"))
9047         is_eos = 1;
9048       else if (unformat (i, "non-eos"))
9049         is_eos = 0;
9050       else if (unformat (i, "via %U", unformat_ip4_address,
9051                          &v4_next_hop_address))
9052         {
9053           next_hop_set = 1;
9054           next_hop_proto = DPO_PROTO_IP4;
9055         }
9056       else if (unformat (i, "via %U", unformat_ip6_address,
9057                          &v6_next_hop_address))
9058         {
9059           next_hop_set = 1;
9060           next_hop_proto = DPO_PROTO_IP6;
9061         }
9062       else if (unformat (i, "weight %d", &next_hop_weight))
9063         ;
9064       else if (unformat (i, "classify %d", &classify_table_index))
9065         {
9066           is_classify = 1;
9067         }
9068       else if (unformat (i, "del"))
9069         is_add = 0;
9070       else if (unformat (i, "add"))
9071         is_add = 1;
9072       else if (unformat (i, "resolve-via-host"))
9073         resolve_host = 1;
9074       else if (unformat (i, "resolve-via-attached"))
9075         resolve_attached = 1;
9076       else if (unformat (i, "multipath"))
9077         is_multipath = 1;
9078       else if (unformat (i, "count %d", &count))
9079         ;
9080       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9081         {
9082           next_hop_set = 1;
9083           next_hop_proto = DPO_PROTO_IP4;
9084         }
9085       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9086         {
9087           next_hop_set = 1;
9088           next_hop_proto = DPO_PROTO_IP6;
9089         }
9090       else
9091         if (unformat
9092             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9093              &sw_if_index))
9094         {
9095           next_hop_set = 1;
9096           next_hop_proto = DPO_PROTO_ETHERNET;
9097           is_interface_rx = 1;
9098         }
9099       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9100         {
9101           next_hop_set = 1;
9102           next_hop_proto = DPO_PROTO_ETHERNET;
9103           is_interface_rx = 1;
9104         }
9105       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9106         next_hop_set = 1;
9107       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9108         next_hop_set = 1;
9109       else if (unformat (i, "out-label %d", &next_hop_out_label))
9110         {
9111           vl_api_fib_mpls_label_t fib_label = {
9112             .label = ntohl (next_hop_out_label),
9113             .ttl = 64,
9114             .exp = 0,
9115           };
9116           vec_add1 (next_hop_out_label_stack, fib_label);
9117         }
9118       else
9119         {
9120           clib_warning ("parse error '%U'", format_unformat_error, i);
9121           return -99;
9122         }
9123     }
9124
9125   if (!next_hop_set && !is_classify)
9126     {
9127       errmsg ("next hop / classify not set");
9128       return -99;
9129     }
9130
9131   if (MPLS_LABEL_INVALID == local_label)
9132     {
9133       errmsg ("missing label");
9134       return -99;
9135     }
9136
9137   if (count > 1)
9138     {
9139       /* Turn on async mode */
9140       vam->async_mode = 1;
9141       vam->async_errors = 0;
9142       before = vat_time_now (vam);
9143     }
9144
9145   for (j = 0; j < count; j++)
9146     {
9147       /* Construct the API message */
9148       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9149           vec_len (next_hop_out_label_stack));
9150
9151       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9152       mp->mr_table_id = ntohl (table_id);
9153
9154       mp->mr_is_add = is_add;
9155       mp->mr_next_hop_proto = next_hop_proto;
9156       mp->mr_is_classify = is_classify;
9157       mp->mr_is_multipath = is_multipath;
9158       mp->mr_is_resolve_host = resolve_host;
9159       mp->mr_is_resolve_attached = resolve_attached;
9160       mp->mr_is_interface_rx = is_interface_rx;
9161       mp->mr_next_hop_weight = next_hop_weight;
9162       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9163       mp->mr_classify_table_index = ntohl (classify_table_index);
9164       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9165       mp->mr_label = ntohl (local_label);
9166       mp->mr_eos = is_eos;
9167
9168       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9169       if (0 != mp->mr_next_hop_n_out_labels)
9170         {
9171           memcpy (mp->mr_next_hop_out_label_stack,
9172                   next_hop_out_label_stack,
9173                   vec_len (next_hop_out_label_stack) *
9174                   sizeof (vl_api_fib_mpls_label_t));
9175           vec_free (next_hop_out_label_stack);
9176         }
9177
9178       if (next_hop_set)
9179         {
9180           if (DPO_PROTO_IP4 == next_hop_proto)
9181             {
9182               clib_memcpy (mp->mr_next_hop,
9183                            &v4_next_hop_address,
9184                            sizeof (v4_next_hop_address));
9185             }
9186           else if (DPO_PROTO_IP6 == next_hop_proto)
9187
9188             {
9189               clib_memcpy (mp->mr_next_hop,
9190                            &v6_next_hop_address,
9191                            sizeof (v6_next_hop_address));
9192             }
9193         }
9194       local_label++;
9195
9196       /* send it... */
9197       S (mp);
9198       /* If we receive SIGTERM, stop now... */
9199       if (vam->do_exit)
9200         break;
9201     }
9202
9203   /* When testing multiple add/del ops, use a control-ping to sync */
9204   if (count > 1)
9205     {
9206       vl_api_control_ping_t *mp_ping;
9207       f64 after;
9208       f64 timeout;
9209
9210       /* Shut off async mode */
9211       vam->async_mode = 0;
9212
9213       MPING (CONTROL_PING, mp_ping);
9214       S (mp_ping);
9215
9216       timeout = vat_time_now (vam) + 1.0;
9217       while (vat_time_now (vam) < timeout)
9218         if (vam->result_ready == 1)
9219           goto out;
9220       vam->retval = -99;
9221
9222     out:
9223       if (vam->retval == -99)
9224         errmsg ("timeout");
9225
9226       if (vam->async_errors > 0)
9227         {
9228           errmsg ("%d asynchronous errors", vam->async_errors);
9229           vam->retval = -98;
9230         }
9231       vam->async_errors = 0;
9232       after = vat_time_now (vam);
9233
9234       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9235       if (j > 0)
9236         count = j;
9237
9238       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9239              count, after - before, count / (after - before));
9240     }
9241   else
9242     {
9243       int ret;
9244
9245       /* Wait for a reply... */
9246       W (ret);
9247       return ret;
9248     }
9249
9250   /* Return the good/bad news */
9251   return (vam->retval);
9252 }
9253
9254 static int
9255 api_mpls_ip_bind_unbind (vat_main_t * vam)
9256 {
9257   unformat_input_t *i = vam->input;
9258   vl_api_mpls_ip_bind_unbind_t *mp;
9259   u32 ip_table_id = 0;
9260   u8 is_bind = 1;
9261   u8 is_ip4 = 1;
9262   ip4_address_t v4_address;
9263   ip6_address_t v6_address;
9264   u32 address_length;
9265   u8 address_set = 0;
9266   mpls_label_t local_label = MPLS_LABEL_INVALID;
9267   int ret;
9268
9269   /* Parse args required to build the message */
9270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9271     {
9272       if (unformat (i, "%U/%d", unformat_ip4_address,
9273                     &v4_address, &address_length))
9274         {
9275           is_ip4 = 1;
9276           address_set = 1;
9277         }
9278       else if (unformat (i, "%U/%d", unformat_ip6_address,
9279                          &v6_address, &address_length))
9280         {
9281           is_ip4 = 0;
9282           address_set = 1;
9283         }
9284       else if (unformat (i, "%d", &local_label))
9285         ;
9286       else if (unformat (i, "table-id %d", &ip_table_id))
9287         ;
9288       else if (unformat (i, "unbind"))
9289         is_bind = 0;
9290       else if (unformat (i, "bind"))
9291         is_bind = 1;
9292       else
9293         {
9294           clib_warning ("parse error '%U'", format_unformat_error, i);
9295           return -99;
9296         }
9297     }
9298
9299   if (!address_set)
9300     {
9301       errmsg ("IP address not set");
9302       return -99;
9303     }
9304
9305   if (MPLS_LABEL_INVALID == local_label)
9306     {
9307       errmsg ("missing label");
9308       return -99;
9309     }
9310
9311   /* Construct the API message */
9312   M (MPLS_IP_BIND_UNBIND, mp);
9313
9314   mp->mb_is_bind = is_bind;
9315   mp->mb_is_ip4 = is_ip4;
9316   mp->mb_ip_table_id = ntohl (ip_table_id);
9317   mp->mb_mpls_table_id = 0;
9318   mp->mb_label = ntohl (local_label);
9319   mp->mb_address_length = address_length;
9320
9321   if (is_ip4)
9322     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9323   else
9324     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9325
9326   /* send it... */
9327   S (mp);
9328
9329   /* Wait for a reply... */
9330   W (ret);
9331   return ret;
9332 }
9333
9334 static int
9335 api_sr_mpls_policy_add (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_sr_mpls_policy_add_t *mp;
9339   u32 bsid = 0;
9340   u32 weight = 1;
9341   u8 type = 0;
9342   u8 n_segments = 0;
9343   u32 sid;
9344   u32 *segments = NULL;
9345   int ret;
9346
9347   /* Parse args required to build the message */
9348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (i, "bsid %d", &bsid))
9351         ;
9352       else if (unformat (i, "weight %d", &weight))
9353         ;
9354       else if (unformat (i, "spray"))
9355         type = 1;
9356       else if (unformat (i, "next %d", &sid))
9357         {
9358           n_segments += 1;
9359           vec_add1 (segments, htonl (sid));
9360         }
9361       else
9362         {
9363           clib_warning ("parse error '%U'", format_unformat_error, i);
9364           return -99;
9365         }
9366     }
9367
9368   if (bsid == 0)
9369     {
9370       errmsg ("bsid not set");
9371       return -99;
9372     }
9373
9374   if (n_segments == 0)
9375     {
9376       errmsg ("no sid in segment stack");
9377       return -99;
9378     }
9379
9380   /* Construct the API message */
9381   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9382
9383   mp->bsid = htonl (bsid);
9384   mp->weight = htonl (weight);
9385   mp->type = type;
9386   mp->n_segments = n_segments;
9387   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9388   vec_free (segments);
9389
9390   /* send it... */
9391   S (mp);
9392
9393   /* Wait for a reply... */
9394   W (ret);
9395   return ret;
9396 }
9397
9398 static int
9399 api_sr_mpls_policy_del (vat_main_t * vam)
9400 {
9401   unformat_input_t *i = vam->input;
9402   vl_api_sr_mpls_policy_del_t *mp;
9403   u32 bsid = 0;
9404   int ret;
9405
9406   /* Parse args required to build the message */
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "bsid %d", &bsid))
9410         ;
9411       else
9412         {
9413           clib_warning ("parse error '%U'", format_unformat_error, i);
9414           return -99;
9415         }
9416     }
9417
9418   if (bsid == 0)
9419     {
9420       errmsg ("bsid not set");
9421       return -99;
9422     }
9423
9424   /* Construct the API message */
9425   M (SR_MPLS_POLICY_DEL, mp);
9426
9427   mp->bsid = htonl (bsid);
9428
9429   /* send it... */
9430   S (mp);
9431
9432   /* Wait for a reply... */
9433   W (ret);
9434   return ret;
9435 }
9436
9437 static int
9438 api_bier_table_add_del (vat_main_t * vam)
9439 {
9440   unformat_input_t *i = vam->input;
9441   vl_api_bier_table_add_del_t *mp;
9442   u8 is_add = 1;
9443   u32 set = 0, sub_domain = 0, hdr_len = 3;
9444   mpls_label_t local_label = MPLS_LABEL_INVALID;
9445   int ret;
9446
9447   /* Parse args required to build the message */
9448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9449     {
9450       if (unformat (i, "sub-domain %d", &sub_domain))
9451         ;
9452       else if (unformat (i, "set %d", &set))
9453         ;
9454       else if (unformat (i, "label %d", &local_label))
9455         ;
9456       else if (unformat (i, "hdr-len %d", &hdr_len))
9457         ;
9458       else if (unformat (i, "add"))
9459         is_add = 1;
9460       else if (unformat (i, "del"))
9461         is_add = 0;
9462       else
9463         {
9464           clib_warning ("parse error '%U'", format_unformat_error, i);
9465           return -99;
9466         }
9467     }
9468
9469   if (MPLS_LABEL_INVALID == local_label)
9470     {
9471       errmsg ("missing label\n");
9472       return -99;
9473     }
9474
9475   /* Construct the API message */
9476   M (BIER_TABLE_ADD_DEL, mp);
9477
9478   mp->bt_is_add = is_add;
9479   mp->bt_label = ntohl (local_label);
9480   mp->bt_tbl_id.bt_set = set;
9481   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9482   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9483
9484   /* send it... */
9485   S (mp);
9486
9487   /* Wait for a reply... */
9488   W (ret);
9489
9490   return (ret);
9491 }
9492
9493 static int
9494 api_bier_route_add_del (vat_main_t * vam)
9495 {
9496   unformat_input_t *i = vam->input;
9497   vl_api_bier_route_add_del_t *mp;
9498   u8 is_add = 1;
9499   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9500   ip4_address_t v4_next_hop_address;
9501   ip6_address_t v6_next_hop_address;
9502   u8 next_hop_set = 0;
9503   u8 next_hop_proto_is_ip4 = 1;
9504   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9505   int ret;
9506
9507   /* Parse args required to build the message */
9508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9509     {
9510       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9511         {
9512           next_hop_proto_is_ip4 = 1;
9513           next_hop_set = 1;
9514         }
9515       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9516         {
9517           next_hop_proto_is_ip4 = 0;
9518           next_hop_set = 1;
9519         }
9520       if (unformat (i, "sub-domain %d", &sub_domain))
9521         ;
9522       else if (unformat (i, "set %d", &set))
9523         ;
9524       else if (unformat (i, "hdr-len %d", &hdr_len))
9525         ;
9526       else if (unformat (i, "bp %d", &bp))
9527         ;
9528       else if (unformat (i, "add"))
9529         is_add = 1;
9530       else if (unformat (i, "del"))
9531         is_add = 0;
9532       else if (unformat (i, "out-label %d", &next_hop_out_label))
9533         ;
9534       else
9535         {
9536           clib_warning ("parse error '%U'", format_unformat_error, i);
9537           return -99;
9538         }
9539     }
9540
9541   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9542     {
9543       errmsg ("next hop / label set\n");
9544       return -99;
9545     }
9546   if (0 == bp)
9547     {
9548       errmsg ("bit=position not set\n");
9549       return -99;
9550     }
9551
9552   /* Construct the API message */
9553   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9554
9555   mp->br_is_add = is_add;
9556   mp->br_tbl_id.bt_set = set;
9557   mp->br_tbl_id.bt_sub_domain = sub_domain;
9558   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9559   mp->br_bp = ntohs (bp);
9560   mp->br_n_paths = 1;
9561   mp->br_paths[0].n_labels = 1;
9562   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9563   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9564
9565   if (next_hop_proto_is_ip4)
9566     {
9567       clib_memcpy (mp->br_paths[0].next_hop,
9568                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9569     }
9570   else
9571     {
9572       clib_memcpy (mp->br_paths[0].next_hop,
9573                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9574     }
9575
9576   /* send it... */
9577   S (mp);
9578
9579   /* Wait for a reply... */
9580   W (ret);
9581
9582   return (ret);
9583 }
9584
9585 static int
9586 api_proxy_arp_add_del (vat_main_t * vam)
9587 {
9588   unformat_input_t *i = vam->input;
9589   vl_api_proxy_arp_add_del_t *mp;
9590   u32 vrf_id = 0;
9591   u8 is_add = 1;
9592   ip4_address_t lo, hi;
9593   u8 range_set = 0;
9594   int ret;
9595
9596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9597     {
9598       if (unformat (i, "vrf %d", &vrf_id))
9599         ;
9600       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9601                          unformat_ip4_address, &hi))
9602         range_set = 1;
9603       else if (unformat (i, "del"))
9604         is_add = 0;
9605       else
9606         {
9607           clib_warning ("parse error '%U'", format_unformat_error, i);
9608           return -99;
9609         }
9610     }
9611
9612   if (range_set == 0)
9613     {
9614       errmsg ("address range not set");
9615       return -99;
9616     }
9617
9618   M (PROXY_ARP_ADD_DEL, mp);
9619
9620   mp->proxy.vrf_id = ntohl (vrf_id);
9621   mp->is_add = is_add;
9622   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9623   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9624
9625   S (mp);
9626   W (ret);
9627   return ret;
9628 }
9629
9630 static int
9631 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9632 {
9633   unformat_input_t *i = vam->input;
9634   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9635   u32 sw_if_index;
9636   u8 enable = 1;
9637   u8 sw_if_index_set = 0;
9638   int ret;
9639
9640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9643         sw_if_index_set = 1;
9644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9645         sw_if_index_set = 1;
9646       else if (unformat (i, "enable"))
9647         enable = 1;
9648       else if (unformat (i, "disable"))
9649         enable = 0;
9650       else
9651         {
9652           clib_warning ("parse error '%U'", format_unformat_error, i);
9653           return -99;
9654         }
9655     }
9656
9657   if (sw_if_index_set == 0)
9658     {
9659       errmsg ("missing interface name or sw_if_index");
9660       return -99;
9661     }
9662
9663   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9664
9665   mp->sw_if_index = ntohl (sw_if_index);
9666   mp->enable_disable = enable;
9667
9668   S (mp);
9669   W (ret);
9670   return ret;
9671 }
9672
9673 static int
9674 api_mpls_tunnel_add_del (vat_main_t * vam)
9675 {
9676   unformat_input_t *i = vam->input;
9677   vl_api_mpls_tunnel_add_del_t *mp;
9678
9679   u8 is_add = 1;
9680   u8 l2_only = 0;
9681   u32 sw_if_index = ~0;
9682   u32 next_hop_sw_if_index = ~0;
9683   u32 next_hop_proto_is_ip4 = 1;
9684
9685   u32 next_hop_table_id = 0;
9686   ip4_address_t v4_next_hop_address = {
9687     .as_u32 = 0,
9688   };
9689   ip6_address_t v6_next_hop_address = { {0} };
9690   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9691   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9692   int ret;
9693
9694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (i, "add"))
9697         is_add = 1;
9698       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9699         is_add = 0;
9700       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9701         ;
9702       else if (unformat (i, "via %U",
9703                          unformat_ip4_address, &v4_next_hop_address))
9704         {
9705           next_hop_proto_is_ip4 = 1;
9706         }
9707       else if (unformat (i, "via %U",
9708                          unformat_ip6_address, &v6_next_hop_address))
9709         {
9710           next_hop_proto_is_ip4 = 0;
9711         }
9712       else if (unformat (i, "via-label %d", &next_hop_via_label))
9713         ;
9714       else if (unformat (i, "l2-only"))
9715         l2_only = 1;
9716       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9717         ;
9718       else if (unformat (i, "out-label %d", &next_hop_out_label))
9719         vec_add1 (labels, ntohl (next_hop_out_label));
9720       else
9721         {
9722           clib_warning ("parse error '%U'", format_unformat_error, i);
9723           return -99;
9724         }
9725     }
9726
9727   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9728
9729   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9730   mp->mt_sw_if_index = ntohl (sw_if_index);
9731   mp->mt_is_add = is_add;
9732   mp->mt_l2_only = l2_only;
9733   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9734   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9735   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9736
9737   mp->mt_next_hop_n_out_labels = vec_len (labels);
9738
9739   if (0 != mp->mt_next_hop_n_out_labels)
9740     {
9741       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9742                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9743       vec_free (labels);
9744     }
9745
9746   if (next_hop_proto_is_ip4)
9747     {
9748       clib_memcpy (mp->mt_next_hop,
9749                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9750     }
9751   else
9752     {
9753       clib_memcpy (mp->mt_next_hop,
9754                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9755     }
9756
9757   S (mp);
9758   W (ret);
9759   return ret;
9760 }
9761
9762 static int
9763 api_sw_interface_set_unnumbered (vat_main_t * vam)
9764 {
9765   unformat_input_t *i = vam->input;
9766   vl_api_sw_interface_set_unnumbered_t *mp;
9767   u32 sw_if_index;
9768   u32 unnum_sw_index = ~0;
9769   u8 is_add = 1;
9770   u8 sw_if_index_set = 0;
9771   int ret;
9772
9773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9774     {
9775       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9776         sw_if_index_set = 1;
9777       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9778         sw_if_index_set = 1;
9779       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9780         ;
9781       else if (unformat (i, "del"))
9782         is_add = 0;
9783       else
9784         {
9785           clib_warning ("parse error '%U'", format_unformat_error, i);
9786           return -99;
9787         }
9788     }
9789
9790   if (sw_if_index_set == 0)
9791     {
9792       errmsg ("missing interface name or sw_if_index");
9793       return -99;
9794     }
9795
9796   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9797
9798   mp->sw_if_index = ntohl (sw_if_index);
9799   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9800   mp->is_add = is_add;
9801
9802   S (mp);
9803   W (ret);
9804   return ret;
9805 }
9806
9807 static int
9808 api_ip_neighbor_add_del (vat_main_t * vam)
9809 {
9810   unformat_input_t *i = vam->input;
9811   vl_api_ip_neighbor_add_del_t *mp;
9812   u32 sw_if_index;
9813   u8 sw_if_index_set = 0;
9814   u8 is_add = 1;
9815   u8 is_static = 0;
9816   u8 is_no_fib_entry = 0;
9817   u8 mac_address[6];
9818   u8 mac_set = 0;
9819   u8 v4_address_set = 0;
9820   u8 v6_address_set = 0;
9821   ip4_address_t v4address;
9822   ip6_address_t v6address;
9823   int ret;
9824
9825   memset (mac_address, 0, sizeof (mac_address));
9826
9827   /* Parse args required to build the message */
9828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9829     {
9830       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9831         {
9832           mac_set = 1;
9833         }
9834       else if (unformat (i, "del"))
9835         is_add = 0;
9836       else
9837         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9838         sw_if_index_set = 1;
9839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9840         sw_if_index_set = 1;
9841       else if (unformat (i, "is_static"))
9842         is_static = 1;
9843       else if (unformat (i, "no-fib-entry"))
9844         is_no_fib_entry = 1;
9845       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9846         v4_address_set = 1;
9847       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9848         v6_address_set = 1;
9849       else
9850         {
9851           clib_warning ("parse error '%U'", format_unformat_error, i);
9852           return -99;
9853         }
9854     }
9855
9856   if (sw_if_index_set == 0)
9857     {
9858       errmsg ("missing interface name or sw_if_index");
9859       return -99;
9860     }
9861   if (v4_address_set && v6_address_set)
9862     {
9863       errmsg ("both v4 and v6 addresses set");
9864       return -99;
9865     }
9866   if (!v4_address_set && !v6_address_set)
9867     {
9868       errmsg ("no address set");
9869       return -99;
9870     }
9871
9872   /* Construct the API message */
9873   M (IP_NEIGHBOR_ADD_DEL, mp);
9874
9875   mp->sw_if_index = ntohl (sw_if_index);
9876   mp->is_add = is_add;
9877   mp->is_static = is_static;
9878   mp->is_no_adj_fib = is_no_fib_entry;
9879   if (mac_set)
9880     clib_memcpy (mp->mac_address, mac_address, 6);
9881   if (v6_address_set)
9882     {
9883       mp->is_ipv6 = 1;
9884       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9885     }
9886   else
9887     {
9888       /* mp->is_ipv6 = 0; via memset in M macro above */
9889       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9890     }
9891
9892   /* send it... */
9893   S (mp);
9894
9895   /* Wait for a reply, return good/bad news  */
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_create_vlan_subif (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_create_vlan_subif_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u32 vlan_id;
9908   u8 vlan_id_set = 0;
9909   int ret;
9910
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "sw_if_index %d", &sw_if_index))
9914         sw_if_index_set = 1;
9915       else
9916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "vlan %d", &vlan_id))
9919         vlan_id_set = 1;
9920       else
9921         {
9922           clib_warning ("parse error '%U'", format_unformat_error, i);
9923           return -99;
9924         }
9925     }
9926
9927   if (sw_if_index_set == 0)
9928     {
9929       errmsg ("missing interface name or sw_if_index");
9930       return -99;
9931     }
9932
9933   if (vlan_id_set == 0)
9934     {
9935       errmsg ("missing vlan_id");
9936       return -99;
9937     }
9938   M (CREATE_VLAN_SUBIF, mp);
9939
9940   mp->sw_if_index = ntohl (sw_if_index);
9941   mp->vlan_id = ntohl (vlan_id);
9942
9943   S (mp);
9944   W (ret);
9945   return ret;
9946 }
9947
9948 #define foreach_create_subif_bit                \
9949 _(no_tags)                                      \
9950 _(one_tag)                                      \
9951 _(two_tags)                                     \
9952 _(dot1ad)                                       \
9953 _(exact_match)                                  \
9954 _(default_sub)                                  \
9955 _(outer_vlan_id_any)                            \
9956 _(inner_vlan_id_any)
9957
9958 static int
9959 api_create_subif (vat_main_t * vam)
9960 {
9961   unformat_input_t *i = vam->input;
9962   vl_api_create_subif_t *mp;
9963   u32 sw_if_index;
9964   u8 sw_if_index_set = 0;
9965   u32 sub_id;
9966   u8 sub_id_set = 0;
9967   u32 no_tags = 0;
9968   u32 one_tag = 0;
9969   u32 two_tags = 0;
9970   u32 dot1ad = 0;
9971   u32 exact_match = 0;
9972   u32 default_sub = 0;
9973   u32 outer_vlan_id_any = 0;
9974   u32 inner_vlan_id_any = 0;
9975   u32 tmp;
9976   u16 outer_vlan_id = 0;
9977   u16 inner_vlan_id = 0;
9978   int ret;
9979
9980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9981     {
9982       if (unformat (i, "sw_if_index %d", &sw_if_index))
9983         sw_if_index_set = 1;
9984       else
9985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9986         sw_if_index_set = 1;
9987       else if (unformat (i, "sub_id %d", &sub_id))
9988         sub_id_set = 1;
9989       else if (unformat (i, "outer_vlan_id %d", &tmp))
9990         outer_vlan_id = tmp;
9991       else if (unformat (i, "inner_vlan_id %d", &tmp))
9992         inner_vlan_id = tmp;
9993
9994 #define _(a) else if (unformat (i, #a)) a = 1 ;
9995       foreach_create_subif_bit
9996 #undef _
9997         else
9998         {
9999           clib_warning ("parse error '%U'", format_unformat_error, i);
10000           return -99;
10001         }
10002     }
10003
10004   if (sw_if_index_set == 0)
10005     {
10006       errmsg ("missing interface name or sw_if_index");
10007       return -99;
10008     }
10009
10010   if (sub_id_set == 0)
10011     {
10012       errmsg ("missing sub_id");
10013       return -99;
10014     }
10015   M (CREATE_SUBIF, mp);
10016
10017   mp->sw_if_index = ntohl (sw_if_index);
10018   mp->sub_id = ntohl (sub_id);
10019
10020 #define _(a) mp->a = a;
10021   foreach_create_subif_bit;
10022 #undef _
10023
10024   mp->outer_vlan_id = ntohs (outer_vlan_id);
10025   mp->inner_vlan_id = ntohs (inner_vlan_id);
10026
10027   S (mp);
10028   W (ret);
10029   return ret;
10030 }
10031
10032 static int
10033 api_oam_add_del (vat_main_t * vam)
10034 {
10035   unformat_input_t *i = vam->input;
10036   vl_api_oam_add_del_t *mp;
10037   u32 vrf_id = 0;
10038   u8 is_add = 1;
10039   ip4_address_t src, dst;
10040   u8 src_set = 0;
10041   u8 dst_set = 0;
10042   int ret;
10043
10044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10045     {
10046       if (unformat (i, "vrf %d", &vrf_id))
10047         ;
10048       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10049         src_set = 1;
10050       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10051         dst_set = 1;
10052       else if (unformat (i, "del"))
10053         is_add = 0;
10054       else
10055         {
10056           clib_warning ("parse error '%U'", format_unformat_error, i);
10057           return -99;
10058         }
10059     }
10060
10061   if (src_set == 0)
10062     {
10063       errmsg ("missing src addr");
10064       return -99;
10065     }
10066
10067   if (dst_set == 0)
10068     {
10069       errmsg ("missing dst addr");
10070       return -99;
10071     }
10072
10073   M (OAM_ADD_DEL, mp);
10074
10075   mp->vrf_id = ntohl (vrf_id);
10076   mp->is_add = is_add;
10077   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10078   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10079
10080   S (mp);
10081   W (ret);
10082   return ret;
10083 }
10084
10085 static int
10086 api_reset_fib (vat_main_t * vam)
10087 {
10088   unformat_input_t *i = vam->input;
10089   vl_api_reset_fib_t *mp;
10090   u32 vrf_id = 0;
10091   u8 is_ipv6 = 0;
10092   u8 vrf_id_set = 0;
10093
10094   int ret;
10095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10096     {
10097       if (unformat (i, "vrf %d", &vrf_id))
10098         vrf_id_set = 1;
10099       else if (unformat (i, "ipv6"))
10100         is_ipv6 = 1;
10101       else
10102         {
10103           clib_warning ("parse error '%U'", format_unformat_error, i);
10104           return -99;
10105         }
10106     }
10107
10108   if (vrf_id_set == 0)
10109     {
10110       errmsg ("missing vrf id");
10111       return -99;
10112     }
10113
10114   M (RESET_FIB, mp);
10115
10116   mp->vrf_id = ntohl (vrf_id);
10117   mp->is_ipv6 = is_ipv6;
10118
10119   S (mp);
10120   W (ret);
10121   return ret;
10122 }
10123
10124 static int
10125 api_dhcp_proxy_config (vat_main_t * vam)
10126 {
10127   unformat_input_t *i = vam->input;
10128   vl_api_dhcp_proxy_config_t *mp;
10129   u32 rx_vrf_id = 0;
10130   u32 server_vrf_id = 0;
10131   u8 is_add = 1;
10132   u8 v4_address_set = 0;
10133   u8 v6_address_set = 0;
10134   ip4_address_t v4address;
10135   ip6_address_t v6address;
10136   u8 v4_src_address_set = 0;
10137   u8 v6_src_address_set = 0;
10138   ip4_address_t v4srcaddress;
10139   ip6_address_t v6srcaddress;
10140   int ret;
10141
10142   /* Parse args required to build the message */
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "del"))
10146         is_add = 0;
10147       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10148         ;
10149       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10150         ;
10151       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10152         v4_address_set = 1;
10153       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10154         v6_address_set = 1;
10155       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10156         v4_src_address_set = 1;
10157       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10158         v6_src_address_set = 1;
10159       else
10160         break;
10161     }
10162
10163   if (v4_address_set && v6_address_set)
10164     {
10165       errmsg ("both v4 and v6 server addresses set");
10166       return -99;
10167     }
10168   if (!v4_address_set && !v6_address_set)
10169     {
10170       errmsg ("no server addresses set");
10171       return -99;
10172     }
10173
10174   if (v4_src_address_set && v6_src_address_set)
10175     {
10176       errmsg ("both v4 and v6  src addresses set");
10177       return -99;
10178     }
10179   if (!v4_src_address_set && !v6_src_address_set)
10180     {
10181       errmsg ("no src addresses set");
10182       return -99;
10183     }
10184
10185   if (!(v4_src_address_set && v4_address_set) &&
10186       !(v6_src_address_set && v6_address_set))
10187     {
10188       errmsg ("no matching server and src addresses set");
10189       return -99;
10190     }
10191
10192   /* Construct the API message */
10193   M (DHCP_PROXY_CONFIG, mp);
10194
10195   mp->is_add = is_add;
10196   mp->rx_vrf_id = ntohl (rx_vrf_id);
10197   mp->server_vrf_id = ntohl (server_vrf_id);
10198   if (v6_address_set)
10199     {
10200       mp->is_ipv6 = 1;
10201       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10202       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10203     }
10204   else
10205     {
10206       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10207       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10208     }
10209
10210   /* send it... */
10211   S (mp);
10212
10213   /* Wait for a reply, return good/bad news  */
10214   W (ret);
10215   return ret;
10216 }
10217
10218 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10219 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10220
10221 static void
10222 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10223 {
10224   vat_main_t *vam = &vat_main;
10225   u32 i, count = mp->count;
10226   vl_api_dhcp_server_t *s;
10227
10228   if (mp->is_ipv6)
10229     print (vam->ofp,
10230            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10231            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10232            ntohl (mp->rx_vrf_id),
10233            format_ip6_address, mp->dhcp_src_address,
10234            mp->vss_type, mp->vss_vpn_ascii_id,
10235            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10236   else
10237     print (vam->ofp,
10238            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10239            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10240            ntohl (mp->rx_vrf_id),
10241            format_ip4_address, mp->dhcp_src_address,
10242            mp->vss_type, mp->vss_vpn_ascii_id,
10243            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10244
10245   for (i = 0; i < count; i++)
10246     {
10247       s = &mp->servers[i];
10248
10249       if (mp->is_ipv6)
10250         print (vam->ofp,
10251                " Server Table-ID %d, Server Address %U",
10252                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10253       else
10254         print (vam->ofp,
10255                " Server Table-ID %d, Server Address %U",
10256                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10257     }
10258 }
10259
10260 static void vl_api_dhcp_proxy_details_t_handler_json
10261   (vl_api_dhcp_proxy_details_t * mp)
10262 {
10263   vat_main_t *vam = &vat_main;
10264   vat_json_node_t *node = NULL;
10265   u32 i, count = mp->count;
10266   struct in_addr ip4;
10267   struct in6_addr ip6;
10268   vl_api_dhcp_server_t *s;
10269
10270   if (VAT_JSON_ARRAY != vam->json_tree.type)
10271     {
10272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10273       vat_json_init_array (&vam->json_tree);
10274     }
10275   node = vat_json_array_add (&vam->json_tree);
10276
10277   vat_json_init_object (node);
10278   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10279   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10280                              sizeof (mp->vss_type));
10281   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10282                                    mp->vss_vpn_ascii_id);
10283   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10284   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10285
10286   if (mp->is_ipv6)
10287     {
10288       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10289       vat_json_object_add_ip6 (node, "src_address", ip6);
10290     }
10291   else
10292     {
10293       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10294       vat_json_object_add_ip4 (node, "src_address", ip4);
10295     }
10296
10297   for (i = 0; i < count; i++)
10298     {
10299       s = &mp->servers[i];
10300
10301       vat_json_object_add_uint (node, "server-table-id",
10302                                 ntohl (s->server_vrf_id));
10303
10304       if (mp->is_ipv6)
10305         {
10306           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10307           vat_json_object_add_ip4 (node, "src_address", ip4);
10308         }
10309       else
10310         {
10311           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10312           vat_json_object_add_ip6 (node, "server_address", ip6);
10313         }
10314     }
10315 }
10316
10317 static int
10318 api_dhcp_proxy_dump (vat_main_t * vam)
10319 {
10320   unformat_input_t *i = vam->input;
10321   vl_api_control_ping_t *mp_ping;
10322   vl_api_dhcp_proxy_dump_t *mp;
10323   u8 is_ipv6 = 0;
10324   int ret;
10325
10326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10327     {
10328       if (unformat (i, "ipv6"))
10329         is_ipv6 = 1;
10330       else
10331         {
10332           clib_warning ("parse error '%U'", format_unformat_error, i);
10333           return -99;
10334         }
10335     }
10336
10337   M (DHCP_PROXY_DUMP, mp);
10338
10339   mp->is_ip6 = is_ipv6;
10340   S (mp);
10341
10342   /* Use a control ping for synchronization */
10343   MPING (CONTROL_PING, mp_ping);
10344   S (mp_ping);
10345
10346   W (ret);
10347   return ret;
10348 }
10349
10350 static int
10351 api_dhcp_proxy_set_vss (vat_main_t * vam)
10352 {
10353   unformat_input_t *i = vam->input;
10354   vl_api_dhcp_proxy_set_vss_t *mp;
10355   u8 is_ipv6 = 0;
10356   u8 is_add = 1;
10357   u32 tbl_id = ~0;
10358   u8 vss_type = VSS_TYPE_DEFAULT;
10359   u8 *vpn_ascii_id = 0;
10360   u32 oui = 0;
10361   u32 fib_id = 0;
10362   int ret;
10363
10364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10365     {
10366       if (unformat (i, "tbl_id %d", &tbl_id))
10367         ;
10368       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10369         vss_type = VSS_TYPE_ASCII;
10370       else if (unformat (i, "fib_id %d", &fib_id))
10371         vss_type = VSS_TYPE_VPN_ID;
10372       else if (unformat (i, "oui %d", &oui))
10373         vss_type = VSS_TYPE_VPN_ID;
10374       else if (unformat (i, "ipv6"))
10375         is_ipv6 = 1;
10376       else if (unformat (i, "del"))
10377         is_add = 0;
10378       else
10379         break;
10380     }
10381
10382   if (tbl_id == ~0)
10383     {
10384       errmsg ("missing tbl_id ");
10385       vec_free (vpn_ascii_id);
10386       return -99;
10387     }
10388
10389   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10390     {
10391       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10392       vec_free (vpn_ascii_id);
10393       return -99;
10394     }
10395
10396   M (DHCP_PROXY_SET_VSS, mp);
10397   mp->tbl_id = ntohl (tbl_id);
10398   mp->vss_type = vss_type;
10399   if (vpn_ascii_id)
10400     {
10401       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10402       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10403     }
10404   mp->vpn_index = ntohl (fib_id);
10405   mp->oui = ntohl (oui);
10406   mp->is_ipv6 = is_ipv6;
10407   mp->is_add = is_add;
10408
10409   S (mp);
10410   W (ret);
10411
10412   vec_free (vpn_ascii_id);
10413   return ret;
10414 }
10415
10416 static int
10417 api_dhcp_client_config (vat_main_t * vam)
10418 {
10419   unformat_input_t *i = vam->input;
10420   vl_api_dhcp_client_config_t *mp;
10421   u32 sw_if_index;
10422   u8 sw_if_index_set = 0;
10423   u8 is_add = 1;
10424   u8 *hostname = 0;
10425   u8 disable_event = 0;
10426   int ret;
10427
10428   /* Parse args required to build the message */
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "del"))
10432         is_add = 0;
10433       else
10434         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10435         sw_if_index_set = 1;
10436       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10437         sw_if_index_set = 1;
10438       else if (unformat (i, "hostname %s", &hostname))
10439         ;
10440       else if (unformat (i, "disable_event"))
10441         disable_event = 1;
10442       else
10443         break;
10444     }
10445
10446   if (sw_if_index_set == 0)
10447     {
10448       errmsg ("missing interface name or sw_if_index");
10449       return -99;
10450     }
10451
10452   if (vec_len (hostname) > 63)
10453     {
10454       errmsg ("hostname too long");
10455     }
10456   vec_add1 (hostname, 0);
10457
10458   /* Construct the API message */
10459   M (DHCP_CLIENT_CONFIG, mp);
10460
10461   mp->is_add = is_add;
10462   mp->client.sw_if_index = htonl (sw_if_index);
10463   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10464   vec_free (hostname);
10465   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10466   mp->client.pid = htonl (getpid ());
10467
10468   /* send it... */
10469   S (mp);
10470
10471   /* Wait for a reply, return good/bad news  */
10472   W (ret);
10473   return ret;
10474 }
10475
10476 static int
10477 api_set_ip_flow_hash (vat_main_t * vam)
10478 {
10479   unformat_input_t *i = vam->input;
10480   vl_api_set_ip_flow_hash_t *mp;
10481   u32 vrf_id = 0;
10482   u8 is_ipv6 = 0;
10483   u8 vrf_id_set = 0;
10484   u8 src = 0;
10485   u8 dst = 0;
10486   u8 sport = 0;
10487   u8 dport = 0;
10488   u8 proto = 0;
10489   u8 reverse = 0;
10490   int ret;
10491
10492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10493     {
10494       if (unformat (i, "vrf %d", &vrf_id))
10495         vrf_id_set = 1;
10496       else if (unformat (i, "ipv6"))
10497         is_ipv6 = 1;
10498       else if (unformat (i, "src"))
10499         src = 1;
10500       else if (unformat (i, "dst"))
10501         dst = 1;
10502       else if (unformat (i, "sport"))
10503         sport = 1;
10504       else if (unformat (i, "dport"))
10505         dport = 1;
10506       else if (unformat (i, "proto"))
10507         proto = 1;
10508       else if (unformat (i, "reverse"))
10509         reverse = 1;
10510
10511       else
10512         {
10513           clib_warning ("parse error '%U'", format_unformat_error, i);
10514           return -99;
10515         }
10516     }
10517
10518   if (vrf_id_set == 0)
10519     {
10520       errmsg ("missing vrf id");
10521       return -99;
10522     }
10523
10524   M (SET_IP_FLOW_HASH, mp);
10525   mp->src = src;
10526   mp->dst = dst;
10527   mp->sport = sport;
10528   mp->dport = dport;
10529   mp->proto = proto;
10530   mp->reverse = reverse;
10531   mp->vrf_id = ntohl (vrf_id);
10532   mp->is_ipv6 = is_ipv6;
10533
10534   S (mp);
10535   W (ret);
10536   return ret;
10537 }
10538
10539 static int
10540 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10541 {
10542   unformat_input_t *i = vam->input;
10543   vl_api_sw_interface_ip6_enable_disable_t *mp;
10544   u32 sw_if_index;
10545   u8 sw_if_index_set = 0;
10546   u8 enable = 0;
10547   int ret;
10548
10549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10550     {
10551       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10552         sw_if_index_set = 1;
10553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10554         sw_if_index_set = 1;
10555       else if (unformat (i, "enable"))
10556         enable = 1;
10557       else if (unformat (i, "disable"))
10558         enable = 0;
10559       else
10560         {
10561           clib_warning ("parse error '%U'", format_unformat_error, i);
10562           return -99;
10563         }
10564     }
10565
10566   if (sw_if_index_set == 0)
10567     {
10568       errmsg ("missing interface name or sw_if_index");
10569       return -99;
10570     }
10571
10572   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10573
10574   mp->sw_if_index = ntohl (sw_if_index);
10575   mp->enable = enable;
10576
10577   S (mp);
10578   W (ret);
10579   return ret;
10580 }
10581
10582 static int
10583 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10584 {
10585   unformat_input_t *i = vam->input;
10586   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10587   u32 sw_if_index;
10588   u8 sw_if_index_set = 0;
10589   u8 v6_address_set = 0;
10590   ip6_address_t v6address;
10591   int ret;
10592
10593   /* Parse args required to build the message */
10594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10597         sw_if_index_set = 1;
10598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10599         sw_if_index_set = 1;
10600       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10601         v6_address_set = 1;
10602       else
10603         break;
10604     }
10605
10606   if (sw_if_index_set == 0)
10607     {
10608       errmsg ("missing interface name or sw_if_index");
10609       return -99;
10610     }
10611   if (!v6_address_set)
10612     {
10613       errmsg ("no address set");
10614       return -99;
10615     }
10616
10617   /* Construct the API message */
10618   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10619
10620   mp->sw_if_index = ntohl (sw_if_index);
10621   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10622
10623   /* send it... */
10624   S (mp);
10625
10626   /* Wait for a reply, return good/bad news  */
10627   W (ret);
10628   return ret;
10629 }
10630
10631 static int
10632 api_ip6nd_proxy_add_del (vat_main_t * vam)
10633 {
10634   unformat_input_t *i = vam->input;
10635   vl_api_ip6nd_proxy_add_del_t *mp;
10636   u32 sw_if_index = ~0;
10637   u8 v6_address_set = 0;
10638   ip6_address_t v6address;
10639   u8 is_del = 0;
10640   int ret;
10641
10642   /* Parse args required to build the message */
10643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10644     {
10645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10646         ;
10647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10648         ;
10649       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10650         v6_address_set = 1;
10651       if (unformat (i, "del"))
10652         is_del = 1;
10653       else
10654         {
10655           clib_warning ("parse error '%U'", format_unformat_error, i);
10656           return -99;
10657         }
10658     }
10659
10660   if (sw_if_index == ~0)
10661     {
10662       errmsg ("missing interface name or sw_if_index");
10663       return -99;
10664     }
10665   if (!v6_address_set)
10666     {
10667       errmsg ("no address set");
10668       return -99;
10669     }
10670
10671   /* Construct the API message */
10672   M (IP6ND_PROXY_ADD_DEL, mp);
10673
10674   mp->is_del = is_del;
10675   mp->sw_if_index = ntohl (sw_if_index);
10676   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10677
10678   /* send it... */
10679   S (mp);
10680
10681   /* Wait for a reply, return good/bad news  */
10682   W (ret);
10683   return ret;
10684 }
10685
10686 static int
10687 api_ip6nd_proxy_dump (vat_main_t * vam)
10688 {
10689   vl_api_ip6nd_proxy_dump_t *mp;
10690   vl_api_control_ping_t *mp_ping;
10691   int ret;
10692
10693   M (IP6ND_PROXY_DUMP, mp);
10694
10695   S (mp);
10696
10697   /* Use a control ping for synchronization */
10698   MPING (CONTROL_PING, mp_ping);
10699   S (mp_ping);
10700
10701   W (ret);
10702   return ret;
10703 }
10704
10705 static void vl_api_ip6nd_proxy_details_t_handler
10706   (vl_api_ip6nd_proxy_details_t * mp)
10707 {
10708   vat_main_t *vam = &vat_main;
10709
10710   print (vam->ofp, "host %U sw_if_index %d",
10711          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10712 }
10713
10714 static void vl_api_ip6nd_proxy_details_t_handler_json
10715   (vl_api_ip6nd_proxy_details_t * mp)
10716 {
10717   vat_main_t *vam = &vat_main;
10718   struct in6_addr ip6;
10719   vat_json_node_t *node = NULL;
10720
10721   if (VAT_JSON_ARRAY != vam->json_tree.type)
10722     {
10723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10724       vat_json_init_array (&vam->json_tree);
10725     }
10726   node = vat_json_array_add (&vam->json_tree);
10727
10728   vat_json_init_object (node);
10729   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10730
10731   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10732   vat_json_object_add_ip6 (node, "host", ip6);
10733 }
10734
10735 static int
10736 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10737 {
10738   unformat_input_t *i = vam->input;
10739   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10740   u32 sw_if_index;
10741   u8 sw_if_index_set = 0;
10742   u32 address_length = 0;
10743   u8 v6_address_set = 0;
10744   ip6_address_t v6address;
10745   u8 use_default = 0;
10746   u8 no_advertise = 0;
10747   u8 off_link = 0;
10748   u8 no_autoconfig = 0;
10749   u8 no_onlink = 0;
10750   u8 is_no = 0;
10751   u32 val_lifetime = 0;
10752   u32 pref_lifetime = 0;
10753   int ret;
10754
10755   /* Parse args required to build the message */
10756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10757     {
10758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10759         sw_if_index_set = 1;
10760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "%U/%d",
10763                          unformat_ip6_address, &v6address, &address_length))
10764         v6_address_set = 1;
10765       else if (unformat (i, "val_life %d", &val_lifetime))
10766         ;
10767       else if (unformat (i, "pref_life %d", &pref_lifetime))
10768         ;
10769       else if (unformat (i, "def"))
10770         use_default = 1;
10771       else if (unformat (i, "noadv"))
10772         no_advertise = 1;
10773       else if (unformat (i, "offl"))
10774         off_link = 1;
10775       else if (unformat (i, "noauto"))
10776         no_autoconfig = 1;
10777       else if (unformat (i, "nolink"))
10778         no_onlink = 1;
10779       else if (unformat (i, "isno"))
10780         is_no = 1;
10781       else
10782         {
10783           clib_warning ("parse error '%U'", format_unformat_error, i);
10784           return -99;
10785         }
10786     }
10787
10788   if (sw_if_index_set == 0)
10789     {
10790       errmsg ("missing interface name or sw_if_index");
10791       return -99;
10792     }
10793   if (!v6_address_set)
10794     {
10795       errmsg ("no address set");
10796       return -99;
10797     }
10798
10799   /* Construct the API message */
10800   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10801
10802   mp->sw_if_index = ntohl (sw_if_index);
10803   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10804   mp->address_length = address_length;
10805   mp->use_default = use_default;
10806   mp->no_advertise = no_advertise;
10807   mp->off_link = off_link;
10808   mp->no_autoconfig = no_autoconfig;
10809   mp->no_onlink = no_onlink;
10810   mp->is_no = is_no;
10811   mp->val_lifetime = ntohl (val_lifetime);
10812   mp->pref_lifetime = ntohl (pref_lifetime);
10813
10814   /* send it... */
10815   S (mp);
10816
10817   /* Wait for a reply, return good/bad news  */
10818   W (ret);
10819   return ret;
10820 }
10821
10822 static int
10823 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10824 {
10825   unformat_input_t *i = vam->input;
10826   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10827   u32 sw_if_index;
10828   u8 sw_if_index_set = 0;
10829   u8 suppress = 0;
10830   u8 managed = 0;
10831   u8 other = 0;
10832   u8 ll_option = 0;
10833   u8 send_unicast = 0;
10834   u8 cease = 0;
10835   u8 is_no = 0;
10836   u8 default_router = 0;
10837   u32 max_interval = 0;
10838   u32 min_interval = 0;
10839   u32 lifetime = 0;
10840   u32 initial_count = 0;
10841   u32 initial_interval = 0;
10842   int ret;
10843
10844
10845   /* Parse args required to build the message */
10846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10847     {
10848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10849         sw_if_index_set = 1;
10850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10851         sw_if_index_set = 1;
10852       else if (unformat (i, "maxint %d", &max_interval))
10853         ;
10854       else if (unformat (i, "minint %d", &min_interval))
10855         ;
10856       else if (unformat (i, "life %d", &lifetime))
10857         ;
10858       else if (unformat (i, "count %d", &initial_count))
10859         ;
10860       else if (unformat (i, "interval %d", &initial_interval))
10861         ;
10862       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10863         suppress = 1;
10864       else if (unformat (i, "managed"))
10865         managed = 1;
10866       else if (unformat (i, "other"))
10867         other = 1;
10868       else if (unformat (i, "ll"))
10869         ll_option = 1;
10870       else if (unformat (i, "send"))
10871         send_unicast = 1;
10872       else if (unformat (i, "cease"))
10873         cease = 1;
10874       else if (unformat (i, "isno"))
10875         is_no = 1;
10876       else if (unformat (i, "def"))
10877         default_router = 1;
10878       else
10879         {
10880           clib_warning ("parse error '%U'", format_unformat_error, i);
10881           return -99;
10882         }
10883     }
10884
10885   if (sw_if_index_set == 0)
10886     {
10887       errmsg ("missing interface name or sw_if_index");
10888       return -99;
10889     }
10890
10891   /* Construct the API message */
10892   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10893
10894   mp->sw_if_index = ntohl (sw_if_index);
10895   mp->max_interval = ntohl (max_interval);
10896   mp->min_interval = ntohl (min_interval);
10897   mp->lifetime = ntohl (lifetime);
10898   mp->initial_count = ntohl (initial_count);
10899   mp->initial_interval = ntohl (initial_interval);
10900   mp->suppress = suppress;
10901   mp->managed = managed;
10902   mp->other = other;
10903   mp->ll_option = ll_option;
10904   mp->send_unicast = send_unicast;
10905   mp->cease = cease;
10906   mp->is_no = is_no;
10907   mp->default_router = default_router;
10908
10909   /* send it... */
10910   S (mp);
10911
10912   /* Wait for a reply, return good/bad news  */
10913   W (ret);
10914   return ret;
10915 }
10916
10917 static int
10918 api_set_arp_neighbor_limit (vat_main_t * vam)
10919 {
10920   unformat_input_t *i = vam->input;
10921   vl_api_set_arp_neighbor_limit_t *mp;
10922   u32 arp_nbr_limit;
10923   u8 limit_set = 0;
10924   u8 is_ipv6 = 0;
10925   int ret;
10926
10927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10928     {
10929       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10930         limit_set = 1;
10931       else if (unformat (i, "ipv6"))
10932         is_ipv6 = 1;
10933       else
10934         {
10935           clib_warning ("parse error '%U'", format_unformat_error, i);
10936           return -99;
10937         }
10938     }
10939
10940   if (limit_set == 0)
10941     {
10942       errmsg ("missing limit value");
10943       return -99;
10944     }
10945
10946   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10947
10948   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10949   mp->is_ipv6 = is_ipv6;
10950
10951   S (mp);
10952   W (ret);
10953   return ret;
10954 }
10955
10956 static int
10957 api_l2_patch_add_del (vat_main_t * vam)
10958 {
10959   unformat_input_t *i = vam->input;
10960   vl_api_l2_patch_add_del_t *mp;
10961   u32 rx_sw_if_index;
10962   u8 rx_sw_if_index_set = 0;
10963   u32 tx_sw_if_index;
10964   u8 tx_sw_if_index_set = 0;
10965   u8 is_add = 1;
10966   int ret;
10967
10968   /* Parse args required to build the message */
10969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10970     {
10971       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10972         rx_sw_if_index_set = 1;
10973       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10974         tx_sw_if_index_set = 1;
10975       else if (unformat (i, "rx"))
10976         {
10977           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10978             {
10979               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10980                             &rx_sw_if_index))
10981                 rx_sw_if_index_set = 1;
10982             }
10983           else
10984             break;
10985         }
10986       else if (unformat (i, "tx"))
10987         {
10988           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10989             {
10990               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10991                             &tx_sw_if_index))
10992                 tx_sw_if_index_set = 1;
10993             }
10994           else
10995             break;
10996         }
10997       else if (unformat (i, "del"))
10998         is_add = 0;
10999       else
11000         break;
11001     }
11002
11003   if (rx_sw_if_index_set == 0)
11004     {
11005       errmsg ("missing rx interface name or rx_sw_if_index");
11006       return -99;
11007     }
11008
11009   if (tx_sw_if_index_set == 0)
11010     {
11011       errmsg ("missing tx interface name or tx_sw_if_index");
11012       return -99;
11013     }
11014
11015   M (L2_PATCH_ADD_DEL, mp);
11016
11017   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11018   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11019   mp->is_add = is_add;
11020
11021   S (mp);
11022   W (ret);
11023   return ret;
11024 }
11025
11026 u8 is_del;
11027 u8 localsid_addr[16];
11028 u8 end_psp;
11029 u8 behavior;
11030 u32 sw_if_index;
11031 u32 vlan_index;
11032 u32 fib_table;
11033 u8 nh_addr[16];
11034
11035 static int
11036 api_sr_localsid_add_del (vat_main_t * vam)
11037 {
11038   unformat_input_t *i = vam->input;
11039   vl_api_sr_localsid_add_del_t *mp;
11040
11041   u8 is_del;
11042   ip6_address_t localsid;
11043   u8 end_psp = 0;
11044   u8 behavior = ~0;
11045   u32 sw_if_index;
11046   u32 fib_table = ~(u32) 0;
11047   ip6_address_t nh_addr6;
11048   ip4_address_t nh_addr4;
11049   memset (&nh_addr6, 0, sizeof (ip6_address_t));
11050   memset (&nh_addr4, 0, sizeof (ip4_address_t));
11051
11052   bool nexthop_set = 0;
11053
11054   int ret;
11055
11056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11057     {
11058       if (unformat (i, "del"))
11059         is_del = 1;
11060       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11061       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11062         nexthop_set = 1;
11063       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11064         nexthop_set = 1;
11065       else if (unformat (i, "behavior %u", &behavior));
11066       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11067       else if (unformat (i, "fib-table %u", &fib_table));
11068       else if (unformat (i, "end.psp %u", &behavior));
11069       else
11070         break;
11071     }
11072
11073   M (SR_LOCALSID_ADD_DEL, mp);
11074
11075   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11076   if (nexthop_set)
11077     {
11078       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11079       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11080     }
11081   mp->behavior = behavior;
11082   mp->sw_if_index = ntohl (sw_if_index);
11083   mp->fib_table = ntohl (fib_table);
11084   mp->end_psp = end_psp;
11085   mp->is_del = is_del;
11086
11087   S (mp);
11088   W (ret);
11089   return ret;
11090 }
11091
11092 static int
11093 api_ioam_enable (vat_main_t * vam)
11094 {
11095   unformat_input_t *input = vam->input;
11096   vl_api_ioam_enable_t *mp;
11097   u32 id = 0;
11098   int has_trace_option = 0;
11099   int has_pot_option = 0;
11100   int has_seqno_option = 0;
11101   int has_analyse_option = 0;
11102   int ret;
11103
11104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11105     {
11106       if (unformat (input, "trace"))
11107         has_trace_option = 1;
11108       else if (unformat (input, "pot"))
11109         has_pot_option = 1;
11110       else if (unformat (input, "seqno"))
11111         has_seqno_option = 1;
11112       else if (unformat (input, "analyse"))
11113         has_analyse_option = 1;
11114       else
11115         break;
11116     }
11117   M (IOAM_ENABLE, mp);
11118   mp->id = htons (id);
11119   mp->seqno = has_seqno_option;
11120   mp->analyse = has_analyse_option;
11121   mp->pot_enable = has_pot_option;
11122   mp->trace_enable = has_trace_option;
11123
11124   S (mp);
11125   W (ret);
11126   return ret;
11127 }
11128
11129
11130 static int
11131 api_ioam_disable (vat_main_t * vam)
11132 {
11133   vl_api_ioam_disable_t *mp;
11134   int ret;
11135
11136   M (IOAM_DISABLE, mp);
11137   S (mp);
11138   W (ret);
11139   return ret;
11140 }
11141
11142 #define foreach_tcp_proto_field                 \
11143 _(src_port)                                     \
11144 _(dst_port)
11145
11146 #define foreach_udp_proto_field                 \
11147 _(src_port)                                     \
11148 _(dst_port)
11149
11150 #define foreach_ip4_proto_field                 \
11151 _(src_address)                                  \
11152 _(dst_address)                                  \
11153 _(tos)                                          \
11154 _(length)                                       \
11155 _(fragment_id)                                  \
11156 _(ttl)                                          \
11157 _(protocol)                                     \
11158 _(checksum)
11159
11160 typedef struct
11161 {
11162   u16 src_port, dst_port;
11163 } tcpudp_header_t;
11164
11165 #if VPP_API_TEST_BUILTIN == 0
11166 uword
11167 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11168 {
11169   u8 **maskp = va_arg (*args, u8 **);
11170   u8 *mask = 0;
11171   u8 found_something = 0;
11172   tcp_header_t *tcp;
11173
11174 #define _(a) u8 a=0;
11175   foreach_tcp_proto_field;
11176 #undef _
11177
11178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11179     {
11180       if (0);
11181 #define _(a) else if (unformat (input, #a)) a=1;
11182       foreach_tcp_proto_field
11183 #undef _
11184         else
11185         break;
11186     }
11187
11188 #define _(a) found_something += a;
11189   foreach_tcp_proto_field;
11190 #undef _
11191
11192   if (found_something == 0)
11193     return 0;
11194
11195   vec_validate (mask, sizeof (*tcp) - 1);
11196
11197   tcp = (tcp_header_t *) mask;
11198
11199 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11200   foreach_tcp_proto_field;
11201 #undef _
11202
11203   *maskp = mask;
11204   return 1;
11205 }
11206
11207 uword
11208 unformat_udp_mask (unformat_input_t * input, va_list * args)
11209 {
11210   u8 **maskp = va_arg (*args, u8 **);
11211   u8 *mask = 0;
11212   u8 found_something = 0;
11213   udp_header_t *udp;
11214
11215 #define _(a) u8 a=0;
11216   foreach_udp_proto_field;
11217 #undef _
11218
11219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (0);
11222 #define _(a) else if (unformat (input, #a)) a=1;
11223       foreach_udp_proto_field
11224 #undef _
11225         else
11226         break;
11227     }
11228
11229 #define _(a) found_something += a;
11230   foreach_udp_proto_field;
11231 #undef _
11232
11233   if (found_something == 0)
11234     return 0;
11235
11236   vec_validate (mask, sizeof (*udp) - 1);
11237
11238   udp = (udp_header_t *) mask;
11239
11240 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11241   foreach_udp_proto_field;
11242 #undef _
11243
11244   *maskp = mask;
11245   return 1;
11246 }
11247
11248 uword
11249 unformat_l4_mask (unformat_input_t * input, va_list * args)
11250 {
11251   u8 **maskp = va_arg (*args, u8 **);
11252   u16 src_port = 0, dst_port = 0;
11253   tcpudp_header_t *tcpudp;
11254
11255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11256     {
11257       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11258         return 1;
11259       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11260         return 1;
11261       else if (unformat (input, "src_port"))
11262         src_port = 0xFFFF;
11263       else if (unformat (input, "dst_port"))
11264         dst_port = 0xFFFF;
11265       else
11266         return 0;
11267     }
11268
11269   if (!src_port && !dst_port)
11270     return 0;
11271
11272   u8 *mask = 0;
11273   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11274
11275   tcpudp = (tcpudp_header_t *) mask;
11276   tcpudp->src_port = src_port;
11277   tcpudp->dst_port = dst_port;
11278
11279   *maskp = mask;
11280
11281   return 1;
11282 }
11283
11284 uword
11285 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11286 {
11287   u8 **maskp = va_arg (*args, u8 **);
11288   u8 *mask = 0;
11289   u8 found_something = 0;
11290   ip4_header_t *ip;
11291
11292 #define _(a) u8 a=0;
11293   foreach_ip4_proto_field;
11294 #undef _
11295   u8 version = 0;
11296   u8 hdr_length = 0;
11297
11298
11299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11300     {
11301       if (unformat (input, "version"))
11302         version = 1;
11303       else if (unformat (input, "hdr_length"))
11304         hdr_length = 1;
11305       else if (unformat (input, "src"))
11306         src_address = 1;
11307       else if (unformat (input, "dst"))
11308         dst_address = 1;
11309       else if (unformat (input, "proto"))
11310         protocol = 1;
11311
11312 #define _(a) else if (unformat (input, #a)) a=1;
11313       foreach_ip4_proto_field
11314 #undef _
11315         else
11316         break;
11317     }
11318
11319 #define _(a) found_something += a;
11320   foreach_ip4_proto_field;
11321 #undef _
11322
11323   if (found_something == 0)
11324     return 0;
11325
11326   vec_validate (mask, sizeof (*ip) - 1);
11327
11328   ip = (ip4_header_t *) mask;
11329
11330 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11331   foreach_ip4_proto_field;
11332 #undef _
11333
11334   ip->ip_version_and_header_length = 0;
11335
11336   if (version)
11337     ip->ip_version_and_header_length |= 0xF0;
11338
11339   if (hdr_length)
11340     ip->ip_version_and_header_length |= 0x0F;
11341
11342   *maskp = mask;
11343   return 1;
11344 }
11345
11346 #define foreach_ip6_proto_field                 \
11347 _(src_address)                                  \
11348 _(dst_address)                                  \
11349 _(payload_length)                               \
11350 _(hop_limit)                                    \
11351 _(protocol)
11352
11353 uword
11354 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11355 {
11356   u8 **maskp = va_arg (*args, u8 **);
11357   u8 *mask = 0;
11358   u8 found_something = 0;
11359   ip6_header_t *ip;
11360   u32 ip_version_traffic_class_and_flow_label;
11361
11362 #define _(a) u8 a=0;
11363   foreach_ip6_proto_field;
11364 #undef _
11365   u8 version = 0;
11366   u8 traffic_class = 0;
11367   u8 flow_label = 0;
11368
11369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11370     {
11371       if (unformat (input, "version"))
11372         version = 1;
11373       else if (unformat (input, "traffic-class"))
11374         traffic_class = 1;
11375       else if (unformat (input, "flow-label"))
11376         flow_label = 1;
11377       else if (unformat (input, "src"))
11378         src_address = 1;
11379       else if (unformat (input, "dst"))
11380         dst_address = 1;
11381       else if (unformat (input, "proto"))
11382         protocol = 1;
11383
11384 #define _(a) else if (unformat (input, #a)) a=1;
11385       foreach_ip6_proto_field
11386 #undef _
11387         else
11388         break;
11389     }
11390
11391 #define _(a) found_something += a;
11392   foreach_ip6_proto_field;
11393 #undef _
11394
11395   if (found_something == 0)
11396     return 0;
11397
11398   vec_validate (mask, sizeof (*ip) - 1);
11399
11400   ip = (ip6_header_t *) mask;
11401
11402 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11403   foreach_ip6_proto_field;
11404 #undef _
11405
11406   ip_version_traffic_class_and_flow_label = 0;
11407
11408   if (version)
11409     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11410
11411   if (traffic_class)
11412     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11413
11414   if (flow_label)
11415     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11416
11417   ip->ip_version_traffic_class_and_flow_label =
11418     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11419
11420   *maskp = mask;
11421   return 1;
11422 }
11423
11424 uword
11425 unformat_l3_mask (unformat_input_t * input, va_list * args)
11426 {
11427   u8 **maskp = va_arg (*args, u8 **);
11428
11429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11432         return 1;
11433       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11434         return 1;
11435       else
11436         break;
11437     }
11438   return 0;
11439 }
11440
11441 uword
11442 unformat_l2_mask (unformat_input_t * input, va_list * args)
11443 {
11444   u8 **maskp = va_arg (*args, u8 **);
11445   u8 *mask = 0;
11446   u8 src = 0;
11447   u8 dst = 0;
11448   u8 proto = 0;
11449   u8 tag1 = 0;
11450   u8 tag2 = 0;
11451   u8 ignore_tag1 = 0;
11452   u8 ignore_tag2 = 0;
11453   u8 cos1 = 0;
11454   u8 cos2 = 0;
11455   u8 dot1q = 0;
11456   u8 dot1ad = 0;
11457   int len = 14;
11458
11459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11460     {
11461       if (unformat (input, "src"))
11462         src = 1;
11463       else if (unformat (input, "dst"))
11464         dst = 1;
11465       else if (unformat (input, "proto"))
11466         proto = 1;
11467       else if (unformat (input, "tag1"))
11468         tag1 = 1;
11469       else if (unformat (input, "tag2"))
11470         tag2 = 1;
11471       else if (unformat (input, "ignore-tag1"))
11472         ignore_tag1 = 1;
11473       else if (unformat (input, "ignore-tag2"))
11474         ignore_tag2 = 1;
11475       else if (unformat (input, "cos1"))
11476         cos1 = 1;
11477       else if (unformat (input, "cos2"))
11478         cos2 = 1;
11479       else if (unformat (input, "dot1q"))
11480         dot1q = 1;
11481       else if (unformat (input, "dot1ad"))
11482         dot1ad = 1;
11483       else
11484         break;
11485     }
11486   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11487        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11488     return 0;
11489
11490   if (tag1 || ignore_tag1 || cos1 || dot1q)
11491     len = 18;
11492   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11493     len = 22;
11494
11495   vec_validate (mask, len - 1);
11496
11497   if (dst)
11498     memset (mask, 0xff, 6);
11499
11500   if (src)
11501     memset (mask + 6, 0xff, 6);
11502
11503   if (tag2 || dot1ad)
11504     {
11505       /* inner vlan tag */
11506       if (tag2)
11507         {
11508           mask[19] = 0xff;
11509           mask[18] = 0x0f;
11510         }
11511       if (cos2)
11512         mask[18] |= 0xe0;
11513       if (proto)
11514         mask[21] = mask[20] = 0xff;
11515       if (tag1)
11516         {
11517           mask[15] = 0xff;
11518           mask[14] = 0x0f;
11519         }
11520       if (cos1)
11521         mask[14] |= 0xe0;
11522       *maskp = mask;
11523       return 1;
11524     }
11525   if (tag1 | dot1q)
11526     {
11527       if (tag1)
11528         {
11529           mask[15] = 0xff;
11530           mask[14] = 0x0f;
11531         }
11532       if (cos1)
11533         mask[14] |= 0xe0;
11534       if (proto)
11535         mask[16] = mask[17] = 0xff;
11536
11537       *maskp = mask;
11538       return 1;
11539     }
11540   if (cos2)
11541     mask[18] |= 0xe0;
11542   if (cos1)
11543     mask[14] |= 0xe0;
11544   if (proto)
11545     mask[12] = mask[13] = 0xff;
11546
11547   *maskp = mask;
11548   return 1;
11549 }
11550
11551 uword
11552 unformat_classify_mask (unformat_input_t * input, va_list * args)
11553 {
11554   u8 **maskp = va_arg (*args, u8 **);
11555   u32 *skipp = va_arg (*args, u32 *);
11556   u32 *matchp = va_arg (*args, u32 *);
11557   u32 match;
11558   u8 *mask = 0;
11559   u8 *l2 = 0;
11560   u8 *l3 = 0;
11561   u8 *l4 = 0;
11562   int i;
11563
11564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11565     {
11566       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11567         ;
11568       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11569         ;
11570       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11571         ;
11572       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11573         ;
11574       else
11575         break;
11576     }
11577
11578   if (l4 && !l3)
11579     {
11580       vec_free (mask);
11581       vec_free (l2);
11582       vec_free (l4);
11583       return 0;
11584     }
11585
11586   if (mask || l2 || l3 || l4)
11587     {
11588       if (l2 || l3 || l4)
11589         {
11590           /* "With a free Ethernet header in every package" */
11591           if (l2 == 0)
11592             vec_validate (l2, 13);
11593           mask = l2;
11594           if (vec_len (l3))
11595             {
11596               vec_append (mask, l3);
11597               vec_free (l3);
11598             }
11599           if (vec_len (l4))
11600             {
11601               vec_append (mask, l4);
11602               vec_free (l4);
11603             }
11604         }
11605
11606       /* Scan forward looking for the first significant mask octet */
11607       for (i = 0; i < vec_len (mask); i++)
11608         if (mask[i])
11609           break;
11610
11611       /* compute (skip, match) params */
11612       *skipp = i / sizeof (u32x4);
11613       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11614
11615       /* Pad mask to an even multiple of the vector size */
11616       while (vec_len (mask) % sizeof (u32x4))
11617         vec_add1 (mask, 0);
11618
11619       match = vec_len (mask) / sizeof (u32x4);
11620
11621       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11622         {
11623           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11624           if (*tmp || *(tmp + 1))
11625             break;
11626           match--;
11627         }
11628       if (match == 0)
11629         clib_warning ("BUG: match 0");
11630
11631       _vec_len (mask) = match * sizeof (u32x4);
11632
11633       *matchp = match;
11634       *maskp = mask;
11635
11636       return 1;
11637     }
11638
11639   return 0;
11640 }
11641 #endif /* VPP_API_TEST_BUILTIN */
11642
11643 #define foreach_l2_next                         \
11644 _(drop, DROP)                                   \
11645 _(ethernet, ETHERNET_INPUT)                     \
11646 _(ip4, IP4_INPUT)                               \
11647 _(ip6, IP6_INPUT)
11648
11649 uword
11650 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11651 {
11652   u32 *miss_next_indexp = va_arg (*args, u32 *);
11653   u32 next_index = 0;
11654   u32 tmp;
11655
11656 #define _(n,N) \
11657   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11658   foreach_l2_next;
11659 #undef _
11660
11661   if (unformat (input, "%d", &tmp))
11662     {
11663       next_index = tmp;
11664       goto out;
11665     }
11666
11667   return 0;
11668
11669 out:
11670   *miss_next_indexp = next_index;
11671   return 1;
11672 }
11673
11674 #define foreach_ip_next                         \
11675 _(drop, DROP)                                   \
11676 _(local, LOCAL)                                 \
11677 _(rewrite, REWRITE)
11678
11679 uword
11680 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11681 {
11682   u32 *miss_next_indexp = va_arg (*args, u32 *);
11683   u32 next_index = 0;
11684   u32 tmp;
11685
11686 #define _(n,N) \
11687   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11688   foreach_ip_next;
11689 #undef _
11690
11691   if (unformat (input, "%d", &tmp))
11692     {
11693       next_index = tmp;
11694       goto out;
11695     }
11696
11697   return 0;
11698
11699 out:
11700   *miss_next_indexp = next_index;
11701   return 1;
11702 }
11703
11704 #define foreach_acl_next                        \
11705 _(deny, DENY)
11706
11707 uword
11708 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11709 {
11710   u32 *miss_next_indexp = va_arg (*args, u32 *);
11711   u32 next_index = 0;
11712   u32 tmp;
11713
11714 #define _(n,N) \
11715   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11716   foreach_acl_next;
11717 #undef _
11718
11719   if (unformat (input, "permit"))
11720     {
11721       next_index = ~0;
11722       goto out;
11723     }
11724   else if (unformat (input, "%d", &tmp))
11725     {
11726       next_index = tmp;
11727       goto out;
11728     }
11729
11730   return 0;
11731
11732 out:
11733   *miss_next_indexp = next_index;
11734   return 1;
11735 }
11736
11737 uword
11738 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11739 {
11740   u32 *r = va_arg (*args, u32 *);
11741
11742   if (unformat (input, "conform-color"))
11743     *r = POLICE_CONFORM;
11744   else if (unformat (input, "exceed-color"))
11745     *r = POLICE_EXCEED;
11746   else
11747     return 0;
11748
11749   return 1;
11750 }
11751
11752 static int
11753 api_classify_add_del_table (vat_main_t * vam)
11754 {
11755   unformat_input_t *i = vam->input;
11756   vl_api_classify_add_del_table_t *mp;
11757
11758   u32 nbuckets = 2;
11759   u32 skip = ~0;
11760   u32 match = ~0;
11761   int is_add = 1;
11762   int del_chain = 0;
11763   u32 table_index = ~0;
11764   u32 next_table_index = ~0;
11765   u32 miss_next_index = ~0;
11766   u32 memory_size = 32 << 20;
11767   u8 *mask = 0;
11768   u32 current_data_flag = 0;
11769   int current_data_offset = 0;
11770   int ret;
11771
11772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11773     {
11774       if (unformat (i, "del"))
11775         is_add = 0;
11776       else if (unformat (i, "del-chain"))
11777         {
11778           is_add = 0;
11779           del_chain = 1;
11780         }
11781       else if (unformat (i, "buckets %d", &nbuckets))
11782         ;
11783       else if (unformat (i, "memory_size %d", &memory_size))
11784         ;
11785       else if (unformat (i, "skip %d", &skip))
11786         ;
11787       else if (unformat (i, "match %d", &match))
11788         ;
11789       else if (unformat (i, "table %d", &table_index))
11790         ;
11791       else if (unformat (i, "mask %U", unformat_classify_mask,
11792                          &mask, &skip, &match))
11793         ;
11794       else if (unformat (i, "next-table %d", &next_table_index))
11795         ;
11796       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11797                          &miss_next_index))
11798         ;
11799       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11800                          &miss_next_index))
11801         ;
11802       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11803                          &miss_next_index))
11804         ;
11805       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11806         ;
11807       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11808         ;
11809       else
11810         break;
11811     }
11812
11813   if (is_add && mask == 0)
11814     {
11815       errmsg ("Mask required");
11816       return -99;
11817     }
11818
11819   if (is_add && skip == ~0)
11820     {
11821       errmsg ("skip count required");
11822       return -99;
11823     }
11824
11825   if (is_add && match == ~0)
11826     {
11827       errmsg ("match count required");
11828       return -99;
11829     }
11830
11831   if (!is_add && table_index == ~0)
11832     {
11833       errmsg ("table index required for delete");
11834       return -99;
11835     }
11836
11837   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11838
11839   mp->is_add = is_add;
11840   mp->del_chain = del_chain;
11841   mp->table_index = ntohl (table_index);
11842   mp->nbuckets = ntohl (nbuckets);
11843   mp->memory_size = ntohl (memory_size);
11844   mp->skip_n_vectors = ntohl (skip);
11845   mp->match_n_vectors = ntohl (match);
11846   mp->next_table_index = ntohl (next_table_index);
11847   mp->miss_next_index = ntohl (miss_next_index);
11848   mp->current_data_flag = ntohl (current_data_flag);
11849   mp->current_data_offset = ntohl (current_data_offset);
11850   mp->mask_len = ntohl (vec_len (mask));
11851   clib_memcpy (mp->mask, mask, vec_len (mask));
11852
11853   vec_free (mask);
11854
11855   S (mp);
11856   W (ret);
11857   return ret;
11858 }
11859
11860 #if VPP_API_TEST_BUILTIN == 0
11861 uword
11862 unformat_l4_match (unformat_input_t * input, va_list * args)
11863 {
11864   u8 **matchp = va_arg (*args, u8 **);
11865
11866   u8 *proto_header = 0;
11867   int src_port = 0;
11868   int dst_port = 0;
11869
11870   tcpudp_header_t h;
11871
11872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11873     {
11874       if (unformat (input, "src_port %d", &src_port))
11875         ;
11876       else if (unformat (input, "dst_port %d", &dst_port))
11877         ;
11878       else
11879         return 0;
11880     }
11881
11882   h.src_port = clib_host_to_net_u16 (src_port);
11883   h.dst_port = clib_host_to_net_u16 (dst_port);
11884   vec_validate (proto_header, sizeof (h) - 1);
11885   memcpy (proto_header, &h, sizeof (h));
11886
11887   *matchp = proto_header;
11888
11889   return 1;
11890 }
11891
11892 uword
11893 unformat_ip4_match (unformat_input_t * input, va_list * args)
11894 {
11895   u8 **matchp = va_arg (*args, u8 **);
11896   u8 *match = 0;
11897   ip4_header_t *ip;
11898   int version = 0;
11899   u32 version_val;
11900   int hdr_length = 0;
11901   u32 hdr_length_val;
11902   int src = 0, dst = 0;
11903   ip4_address_t src_val, dst_val;
11904   int proto = 0;
11905   u32 proto_val;
11906   int tos = 0;
11907   u32 tos_val;
11908   int length = 0;
11909   u32 length_val;
11910   int fragment_id = 0;
11911   u32 fragment_id_val;
11912   int ttl = 0;
11913   int ttl_val;
11914   int checksum = 0;
11915   u32 checksum_val;
11916
11917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (input, "version %d", &version_val))
11920         version = 1;
11921       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11922         hdr_length = 1;
11923       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11924         src = 1;
11925       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11926         dst = 1;
11927       else if (unformat (input, "proto %d", &proto_val))
11928         proto = 1;
11929       else if (unformat (input, "tos %d", &tos_val))
11930         tos = 1;
11931       else if (unformat (input, "length %d", &length_val))
11932         length = 1;
11933       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11934         fragment_id = 1;
11935       else if (unformat (input, "ttl %d", &ttl_val))
11936         ttl = 1;
11937       else if (unformat (input, "checksum %d", &checksum_val))
11938         checksum = 1;
11939       else
11940         break;
11941     }
11942
11943   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11944       + ttl + checksum == 0)
11945     return 0;
11946
11947   /*
11948    * Aligned because we use the real comparison functions
11949    */
11950   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11951
11952   ip = (ip4_header_t *) match;
11953
11954   /* These are realistically matched in practice */
11955   if (src)
11956     ip->src_address.as_u32 = src_val.as_u32;
11957
11958   if (dst)
11959     ip->dst_address.as_u32 = dst_val.as_u32;
11960
11961   if (proto)
11962     ip->protocol = proto_val;
11963
11964
11965   /* These are not, but they're included for completeness */
11966   if (version)
11967     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11968
11969   if (hdr_length)
11970     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11971
11972   if (tos)
11973     ip->tos = tos_val;
11974
11975   if (length)
11976     ip->length = clib_host_to_net_u16 (length_val);
11977
11978   if (ttl)
11979     ip->ttl = ttl_val;
11980
11981   if (checksum)
11982     ip->checksum = clib_host_to_net_u16 (checksum_val);
11983
11984   *matchp = match;
11985   return 1;
11986 }
11987
11988 uword
11989 unformat_ip6_match (unformat_input_t * input, va_list * args)
11990 {
11991   u8 **matchp = va_arg (*args, u8 **);
11992   u8 *match = 0;
11993   ip6_header_t *ip;
11994   int version = 0;
11995   u32 version_val;
11996   u8 traffic_class = 0;
11997   u32 traffic_class_val = 0;
11998   u8 flow_label = 0;
11999   u8 flow_label_val;
12000   int src = 0, dst = 0;
12001   ip6_address_t src_val, dst_val;
12002   int proto = 0;
12003   u32 proto_val;
12004   int payload_length = 0;
12005   u32 payload_length_val;
12006   int hop_limit = 0;
12007   int hop_limit_val;
12008   u32 ip_version_traffic_class_and_flow_label;
12009
12010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12011     {
12012       if (unformat (input, "version %d", &version_val))
12013         version = 1;
12014       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12015         traffic_class = 1;
12016       else if (unformat (input, "flow_label %d", &flow_label_val))
12017         flow_label = 1;
12018       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12019         src = 1;
12020       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12021         dst = 1;
12022       else if (unformat (input, "proto %d", &proto_val))
12023         proto = 1;
12024       else if (unformat (input, "payload_length %d", &payload_length_val))
12025         payload_length = 1;
12026       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12027         hop_limit = 1;
12028       else
12029         break;
12030     }
12031
12032   if (version + traffic_class + flow_label + src + dst + proto +
12033       payload_length + hop_limit == 0)
12034     return 0;
12035
12036   /*
12037    * Aligned because we use the real comparison functions
12038    */
12039   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12040
12041   ip = (ip6_header_t *) match;
12042
12043   if (src)
12044     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12045
12046   if (dst)
12047     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12048
12049   if (proto)
12050     ip->protocol = proto_val;
12051
12052   ip_version_traffic_class_and_flow_label = 0;
12053
12054   if (version)
12055     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12056
12057   if (traffic_class)
12058     ip_version_traffic_class_and_flow_label |=
12059       (traffic_class_val & 0xFF) << 20;
12060
12061   if (flow_label)
12062     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12063
12064   ip->ip_version_traffic_class_and_flow_label =
12065     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12066
12067   if (payload_length)
12068     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12069
12070   if (hop_limit)
12071     ip->hop_limit = hop_limit_val;
12072
12073   *matchp = match;
12074   return 1;
12075 }
12076
12077 uword
12078 unformat_l3_match (unformat_input_t * input, va_list * args)
12079 {
12080   u8 **matchp = va_arg (*args, u8 **);
12081
12082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12083     {
12084       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12085         return 1;
12086       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12087         return 1;
12088       else
12089         break;
12090     }
12091   return 0;
12092 }
12093
12094 uword
12095 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12096 {
12097   u8 *tagp = va_arg (*args, u8 *);
12098   u32 tag;
12099
12100   if (unformat (input, "%d", &tag))
12101     {
12102       tagp[0] = (tag >> 8) & 0x0F;
12103       tagp[1] = tag & 0xFF;
12104       return 1;
12105     }
12106
12107   return 0;
12108 }
12109
12110 uword
12111 unformat_l2_match (unformat_input_t * input, va_list * args)
12112 {
12113   u8 **matchp = va_arg (*args, u8 **);
12114   u8 *match = 0;
12115   u8 src = 0;
12116   u8 src_val[6];
12117   u8 dst = 0;
12118   u8 dst_val[6];
12119   u8 proto = 0;
12120   u16 proto_val;
12121   u8 tag1 = 0;
12122   u8 tag1_val[2];
12123   u8 tag2 = 0;
12124   u8 tag2_val[2];
12125   int len = 14;
12126   u8 ignore_tag1 = 0;
12127   u8 ignore_tag2 = 0;
12128   u8 cos1 = 0;
12129   u8 cos2 = 0;
12130   u32 cos1_val = 0;
12131   u32 cos2_val = 0;
12132
12133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12136         src = 1;
12137       else
12138         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12139         dst = 1;
12140       else if (unformat (input, "proto %U",
12141                          unformat_ethernet_type_host_byte_order, &proto_val))
12142         proto = 1;
12143       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12144         tag1 = 1;
12145       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12146         tag2 = 1;
12147       else if (unformat (input, "ignore-tag1"))
12148         ignore_tag1 = 1;
12149       else if (unformat (input, "ignore-tag2"))
12150         ignore_tag2 = 1;
12151       else if (unformat (input, "cos1 %d", &cos1_val))
12152         cos1 = 1;
12153       else if (unformat (input, "cos2 %d", &cos2_val))
12154         cos2 = 1;
12155       else
12156         break;
12157     }
12158   if ((src + dst + proto + tag1 + tag2 +
12159        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12160     return 0;
12161
12162   if (tag1 || ignore_tag1 || cos1)
12163     len = 18;
12164   if (tag2 || ignore_tag2 || cos2)
12165     len = 22;
12166
12167   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12168
12169   if (dst)
12170     clib_memcpy (match, dst_val, 6);
12171
12172   if (src)
12173     clib_memcpy (match + 6, src_val, 6);
12174
12175   if (tag2)
12176     {
12177       /* inner vlan tag */
12178       match[19] = tag2_val[1];
12179       match[18] = tag2_val[0];
12180       if (cos2)
12181         match[18] |= (cos2_val & 0x7) << 5;
12182       if (proto)
12183         {
12184           match[21] = proto_val & 0xff;
12185           match[20] = proto_val >> 8;
12186         }
12187       if (tag1)
12188         {
12189           match[15] = tag1_val[1];
12190           match[14] = tag1_val[0];
12191         }
12192       if (cos1)
12193         match[14] |= (cos1_val & 0x7) << 5;
12194       *matchp = match;
12195       return 1;
12196     }
12197   if (tag1)
12198     {
12199       match[15] = tag1_val[1];
12200       match[14] = tag1_val[0];
12201       if (proto)
12202         {
12203           match[17] = proto_val & 0xff;
12204           match[16] = proto_val >> 8;
12205         }
12206       if (cos1)
12207         match[14] |= (cos1_val & 0x7) << 5;
12208
12209       *matchp = match;
12210       return 1;
12211     }
12212   if (cos2)
12213     match[18] |= (cos2_val & 0x7) << 5;
12214   if (cos1)
12215     match[14] |= (cos1_val & 0x7) << 5;
12216   if (proto)
12217     {
12218       match[13] = proto_val & 0xff;
12219       match[12] = proto_val >> 8;
12220     }
12221
12222   *matchp = match;
12223   return 1;
12224 }
12225
12226 uword
12227 unformat_qos_source (unformat_input_t * input, va_list * args)
12228 {
12229   int *qs = va_arg (*args, int *);
12230
12231   if (unformat (input, "ip"))
12232     *qs = QOS_SOURCE_IP;
12233   else if (unformat (input, "mpls"))
12234     *qs = QOS_SOURCE_MPLS;
12235   else if (unformat (input, "ext"))
12236     *qs = QOS_SOURCE_EXT;
12237   else if (unformat (input, "vlan"))
12238     *qs = QOS_SOURCE_VLAN;
12239   else
12240     return 0;
12241
12242   return 1;
12243 }
12244 #endif
12245
12246 uword
12247 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12248 {
12249   u8 **matchp = va_arg (*args, u8 **);
12250   u32 skip_n_vectors = va_arg (*args, u32);
12251   u32 match_n_vectors = va_arg (*args, u32);
12252
12253   u8 *match = 0;
12254   u8 *l2 = 0;
12255   u8 *l3 = 0;
12256   u8 *l4 = 0;
12257
12258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (input, "hex %U", unformat_hex_string, &match))
12261         ;
12262       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12263         ;
12264       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12265         ;
12266       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12267         ;
12268       else
12269         break;
12270     }
12271
12272   if (l4 && !l3)
12273     {
12274       vec_free (match);
12275       vec_free (l2);
12276       vec_free (l4);
12277       return 0;
12278     }
12279
12280   if (match || l2 || l3 || l4)
12281     {
12282       if (l2 || l3 || l4)
12283         {
12284           /* "Win a free Ethernet header in every packet" */
12285           if (l2 == 0)
12286             vec_validate_aligned (l2, 13, sizeof (u32x4));
12287           match = l2;
12288           if (vec_len (l3))
12289             {
12290               vec_append_aligned (match, l3, sizeof (u32x4));
12291               vec_free (l3);
12292             }
12293           if (vec_len (l4))
12294             {
12295               vec_append_aligned (match, l4, sizeof (u32x4));
12296               vec_free (l4);
12297             }
12298         }
12299
12300       /* Make sure the vector is big enough even if key is all 0's */
12301       vec_validate_aligned
12302         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12303          sizeof (u32x4));
12304
12305       /* Set size, include skipped vectors */
12306       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12307
12308       *matchp = match;
12309
12310       return 1;
12311     }
12312
12313   return 0;
12314 }
12315
12316 static int
12317 api_classify_add_del_session (vat_main_t * vam)
12318 {
12319   unformat_input_t *i = vam->input;
12320   vl_api_classify_add_del_session_t *mp;
12321   int is_add = 1;
12322   u32 table_index = ~0;
12323   u32 hit_next_index = ~0;
12324   u32 opaque_index = ~0;
12325   u8 *match = 0;
12326   i32 advance = 0;
12327   u32 skip_n_vectors = 0;
12328   u32 match_n_vectors = 0;
12329   u32 action = 0;
12330   u32 metadata = 0;
12331   int ret;
12332
12333   /*
12334    * Warning: you have to supply skip_n and match_n
12335    * because the API client cant simply look at the classify
12336    * table object.
12337    */
12338
12339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12340     {
12341       if (unformat (i, "del"))
12342         is_add = 0;
12343       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12344                          &hit_next_index))
12345         ;
12346       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12347                          &hit_next_index))
12348         ;
12349       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12350                          &hit_next_index))
12351         ;
12352       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12353         ;
12354       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12355         ;
12356       else if (unformat (i, "opaque-index %d", &opaque_index))
12357         ;
12358       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12359         ;
12360       else if (unformat (i, "match_n %d", &match_n_vectors))
12361         ;
12362       else if (unformat (i, "match %U", api_unformat_classify_match,
12363                          &match, skip_n_vectors, match_n_vectors))
12364         ;
12365       else if (unformat (i, "advance %d", &advance))
12366         ;
12367       else if (unformat (i, "table-index %d", &table_index))
12368         ;
12369       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12370         action = 1;
12371       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12372         action = 2;
12373       else if (unformat (i, "action %d", &action))
12374         ;
12375       else if (unformat (i, "metadata %d", &metadata))
12376         ;
12377       else
12378         break;
12379     }
12380
12381   if (table_index == ~0)
12382     {
12383       errmsg ("Table index required");
12384       return -99;
12385     }
12386
12387   if (is_add && match == 0)
12388     {
12389       errmsg ("Match value required");
12390       return -99;
12391     }
12392
12393   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12394
12395   mp->is_add = is_add;
12396   mp->table_index = ntohl (table_index);
12397   mp->hit_next_index = ntohl (hit_next_index);
12398   mp->opaque_index = ntohl (opaque_index);
12399   mp->advance = ntohl (advance);
12400   mp->action = action;
12401   mp->metadata = ntohl (metadata);
12402   mp->match_len = ntohl (vec_len (match));
12403   clib_memcpy (mp->match, match, vec_len (match));
12404   vec_free (match);
12405
12406   S (mp);
12407   W (ret);
12408   return ret;
12409 }
12410
12411 static int
12412 api_classify_set_interface_ip_table (vat_main_t * vam)
12413 {
12414   unformat_input_t *i = vam->input;
12415   vl_api_classify_set_interface_ip_table_t *mp;
12416   u32 sw_if_index;
12417   int sw_if_index_set;
12418   u32 table_index = ~0;
12419   u8 is_ipv6 = 0;
12420   int ret;
12421
12422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12423     {
12424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12425         sw_if_index_set = 1;
12426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12427         sw_if_index_set = 1;
12428       else if (unformat (i, "table %d", &table_index))
12429         ;
12430       else
12431         {
12432           clib_warning ("parse error '%U'", format_unformat_error, i);
12433           return -99;
12434         }
12435     }
12436
12437   if (sw_if_index_set == 0)
12438     {
12439       errmsg ("missing interface name or sw_if_index");
12440       return -99;
12441     }
12442
12443
12444   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12445
12446   mp->sw_if_index = ntohl (sw_if_index);
12447   mp->table_index = ntohl (table_index);
12448   mp->is_ipv6 = is_ipv6;
12449
12450   S (mp);
12451   W (ret);
12452   return ret;
12453 }
12454
12455 static int
12456 api_classify_set_interface_l2_tables (vat_main_t * vam)
12457 {
12458   unformat_input_t *i = vam->input;
12459   vl_api_classify_set_interface_l2_tables_t *mp;
12460   u32 sw_if_index;
12461   int sw_if_index_set;
12462   u32 ip4_table_index = ~0;
12463   u32 ip6_table_index = ~0;
12464   u32 other_table_index = ~0;
12465   u32 is_input = 1;
12466   int ret;
12467
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12471         sw_if_index_set = 1;
12472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         sw_if_index_set = 1;
12474       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12475         ;
12476       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12477         ;
12478       else if (unformat (i, "other-table %d", &other_table_index))
12479         ;
12480       else if (unformat (i, "is-input %d", &is_input))
12481         ;
12482       else
12483         {
12484           clib_warning ("parse error '%U'", format_unformat_error, i);
12485           return -99;
12486         }
12487     }
12488
12489   if (sw_if_index_set == 0)
12490     {
12491       errmsg ("missing interface name or sw_if_index");
12492       return -99;
12493     }
12494
12495
12496   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12497
12498   mp->sw_if_index = ntohl (sw_if_index);
12499   mp->ip4_table_index = ntohl (ip4_table_index);
12500   mp->ip6_table_index = ntohl (ip6_table_index);
12501   mp->other_table_index = ntohl (other_table_index);
12502   mp->is_input = (u8) is_input;
12503
12504   S (mp);
12505   W (ret);
12506   return ret;
12507 }
12508
12509 static int
12510 api_set_ipfix_exporter (vat_main_t * vam)
12511 {
12512   unformat_input_t *i = vam->input;
12513   vl_api_set_ipfix_exporter_t *mp;
12514   ip4_address_t collector_address;
12515   u8 collector_address_set = 0;
12516   u32 collector_port = ~0;
12517   ip4_address_t src_address;
12518   u8 src_address_set = 0;
12519   u32 vrf_id = ~0;
12520   u32 path_mtu = ~0;
12521   u32 template_interval = ~0;
12522   u8 udp_checksum = 0;
12523   int ret;
12524
12525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (i, "collector_address %U", unformat_ip4_address,
12528                     &collector_address))
12529         collector_address_set = 1;
12530       else if (unformat (i, "collector_port %d", &collector_port))
12531         ;
12532       else if (unformat (i, "src_address %U", unformat_ip4_address,
12533                          &src_address))
12534         src_address_set = 1;
12535       else if (unformat (i, "vrf_id %d", &vrf_id))
12536         ;
12537       else if (unformat (i, "path_mtu %d", &path_mtu))
12538         ;
12539       else if (unformat (i, "template_interval %d", &template_interval))
12540         ;
12541       else if (unformat (i, "udp_checksum"))
12542         udp_checksum = 1;
12543       else
12544         break;
12545     }
12546
12547   if (collector_address_set == 0)
12548     {
12549       errmsg ("collector_address required");
12550       return -99;
12551     }
12552
12553   if (src_address_set == 0)
12554     {
12555       errmsg ("src_address required");
12556       return -99;
12557     }
12558
12559   M (SET_IPFIX_EXPORTER, mp);
12560
12561   memcpy (mp->collector_address, collector_address.data,
12562           sizeof (collector_address.data));
12563   mp->collector_port = htons ((u16) collector_port);
12564   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12565   mp->vrf_id = htonl (vrf_id);
12566   mp->path_mtu = htonl (path_mtu);
12567   mp->template_interval = htonl (template_interval);
12568   mp->udp_checksum = udp_checksum;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static int
12576 api_set_ipfix_classify_stream (vat_main_t * vam)
12577 {
12578   unformat_input_t *i = vam->input;
12579   vl_api_set_ipfix_classify_stream_t *mp;
12580   u32 domain_id = 0;
12581   u32 src_port = UDP_DST_PORT_ipfix;
12582   int ret;
12583
12584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12585     {
12586       if (unformat (i, "domain %d", &domain_id))
12587         ;
12588       else if (unformat (i, "src_port %d", &src_port))
12589         ;
12590       else
12591         {
12592           errmsg ("unknown input `%U'", format_unformat_error, i);
12593           return -99;
12594         }
12595     }
12596
12597   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12598
12599   mp->domain_id = htonl (domain_id);
12600   mp->src_port = htons ((u16) src_port);
12601
12602   S (mp);
12603   W (ret);
12604   return ret;
12605 }
12606
12607 static int
12608 api_ipfix_classify_table_add_del (vat_main_t * vam)
12609 {
12610   unformat_input_t *i = vam->input;
12611   vl_api_ipfix_classify_table_add_del_t *mp;
12612   int is_add = -1;
12613   u32 classify_table_index = ~0;
12614   u8 ip_version = 0;
12615   u8 transport_protocol = 255;
12616   int ret;
12617
12618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12619     {
12620       if (unformat (i, "add"))
12621         is_add = 1;
12622       else if (unformat (i, "del"))
12623         is_add = 0;
12624       else if (unformat (i, "table %d", &classify_table_index))
12625         ;
12626       else if (unformat (i, "ip4"))
12627         ip_version = 4;
12628       else if (unformat (i, "ip6"))
12629         ip_version = 6;
12630       else if (unformat (i, "tcp"))
12631         transport_protocol = 6;
12632       else if (unformat (i, "udp"))
12633         transport_protocol = 17;
12634       else
12635         {
12636           errmsg ("unknown input `%U'", format_unformat_error, i);
12637           return -99;
12638         }
12639     }
12640
12641   if (is_add == -1)
12642     {
12643       errmsg ("expecting: add|del");
12644       return -99;
12645     }
12646   if (classify_table_index == ~0)
12647     {
12648       errmsg ("classifier table not specified");
12649       return -99;
12650     }
12651   if (ip_version == 0)
12652     {
12653       errmsg ("IP version not specified");
12654       return -99;
12655     }
12656
12657   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12658
12659   mp->is_add = is_add;
12660   mp->table_id = htonl (classify_table_index);
12661   mp->ip_version = ip_version;
12662   mp->transport_protocol = transport_protocol;
12663
12664   S (mp);
12665   W (ret);
12666   return ret;
12667 }
12668
12669 static int
12670 api_get_node_index (vat_main_t * vam)
12671 {
12672   unformat_input_t *i = vam->input;
12673   vl_api_get_node_index_t *mp;
12674   u8 *name = 0;
12675   int ret;
12676
12677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12678     {
12679       if (unformat (i, "node %s", &name))
12680         ;
12681       else
12682         break;
12683     }
12684   if (name == 0)
12685     {
12686       errmsg ("node name required");
12687       return -99;
12688     }
12689   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12690     {
12691       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12692       return -99;
12693     }
12694
12695   M (GET_NODE_INDEX, mp);
12696   clib_memcpy (mp->node_name, name, vec_len (name));
12697   vec_free (name);
12698
12699   S (mp);
12700   W (ret);
12701   return ret;
12702 }
12703
12704 static int
12705 api_get_next_index (vat_main_t * vam)
12706 {
12707   unformat_input_t *i = vam->input;
12708   vl_api_get_next_index_t *mp;
12709   u8 *node_name = 0, *next_node_name = 0;
12710   int ret;
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "node-name %s", &node_name))
12715         ;
12716       else if (unformat (i, "next-node-name %s", &next_node_name))
12717         break;
12718     }
12719
12720   if (node_name == 0)
12721     {
12722       errmsg ("node name required");
12723       return -99;
12724     }
12725   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12726     {
12727       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12728       return -99;
12729     }
12730
12731   if (next_node_name == 0)
12732     {
12733       errmsg ("next node name required");
12734       return -99;
12735     }
12736   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12737     {
12738       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12739       return -99;
12740     }
12741
12742   M (GET_NEXT_INDEX, mp);
12743   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12744   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12745   vec_free (node_name);
12746   vec_free (next_node_name);
12747
12748   S (mp);
12749   W (ret);
12750   return ret;
12751 }
12752
12753 static int
12754 api_add_node_next (vat_main_t * vam)
12755 {
12756   unformat_input_t *i = vam->input;
12757   vl_api_add_node_next_t *mp;
12758   u8 *name = 0;
12759   u8 *next = 0;
12760   int ret;
12761
12762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (i, "node %s", &name))
12765         ;
12766       else if (unformat (i, "next %s", &next))
12767         ;
12768       else
12769         break;
12770     }
12771   if (name == 0)
12772     {
12773       errmsg ("node name required");
12774       return -99;
12775     }
12776   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12777     {
12778       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12779       return -99;
12780     }
12781   if (next == 0)
12782     {
12783       errmsg ("next node required");
12784       return -99;
12785     }
12786   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12787     {
12788       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12789       return -99;
12790     }
12791
12792   M (ADD_NODE_NEXT, mp);
12793   clib_memcpy (mp->node_name, name, vec_len (name));
12794   clib_memcpy (mp->next_name, next, vec_len (next));
12795   vec_free (name);
12796   vec_free (next);
12797
12798   S (mp);
12799   W (ret);
12800   return ret;
12801 }
12802
12803 static int
12804 api_l2tpv3_create_tunnel (vat_main_t * vam)
12805 {
12806   unformat_input_t *i = vam->input;
12807   ip6_address_t client_address, our_address;
12808   int client_address_set = 0;
12809   int our_address_set = 0;
12810   u32 local_session_id = 0;
12811   u32 remote_session_id = 0;
12812   u64 local_cookie = 0;
12813   u64 remote_cookie = 0;
12814   u8 l2_sublayer_present = 0;
12815   vl_api_l2tpv3_create_tunnel_t *mp;
12816   int ret;
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "client_address %U", unformat_ip6_address,
12821                     &client_address))
12822         client_address_set = 1;
12823       else if (unformat (i, "our_address %U", unformat_ip6_address,
12824                          &our_address))
12825         our_address_set = 1;
12826       else if (unformat (i, "local_session_id %d", &local_session_id))
12827         ;
12828       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12829         ;
12830       else if (unformat (i, "local_cookie %lld", &local_cookie))
12831         ;
12832       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12833         ;
12834       else if (unformat (i, "l2-sublayer-present"))
12835         l2_sublayer_present = 1;
12836       else
12837         break;
12838     }
12839
12840   if (client_address_set == 0)
12841     {
12842       errmsg ("client_address required");
12843       return -99;
12844     }
12845
12846   if (our_address_set == 0)
12847     {
12848       errmsg ("our_address required");
12849       return -99;
12850     }
12851
12852   M (L2TPV3_CREATE_TUNNEL, mp);
12853
12854   clib_memcpy (mp->client_address, client_address.as_u8,
12855                sizeof (mp->client_address));
12856
12857   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12858
12859   mp->local_session_id = ntohl (local_session_id);
12860   mp->remote_session_id = ntohl (remote_session_id);
12861   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12862   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12863   mp->l2_sublayer_present = l2_sublayer_present;
12864   mp->is_ipv6 = 1;
12865
12866   S (mp);
12867   W (ret);
12868   return ret;
12869 }
12870
12871 static int
12872 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12873 {
12874   unformat_input_t *i = vam->input;
12875   u32 sw_if_index;
12876   u8 sw_if_index_set = 0;
12877   u64 new_local_cookie = 0;
12878   u64 new_remote_cookie = 0;
12879   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12880   int ret;
12881
12882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12885         sw_if_index_set = 1;
12886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12887         sw_if_index_set = 1;
12888       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12889         ;
12890       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12891         ;
12892       else
12893         break;
12894     }
12895
12896   if (sw_if_index_set == 0)
12897     {
12898       errmsg ("missing interface name or sw_if_index");
12899       return -99;
12900     }
12901
12902   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12903
12904   mp->sw_if_index = ntohl (sw_if_index);
12905   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12906   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12907
12908   S (mp);
12909   W (ret);
12910   return ret;
12911 }
12912
12913 static int
12914 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12915 {
12916   unformat_input_t *i = vam->input;
12917   vl_api_l2tpv3_interface_enable_disable_t *mp;
12918   u32 sw_if_index;
12919   u8 sw_if_index_set = 0;
12920   u8 enable_disable = 1;
12921   int ret;
12922
12923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12924     {
12925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12926         sw_if_index_set = 1;
12927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12928         sw_if_index_set = 1;
12929       else if (unformat (i, "enable"))
12930         enable_disable = 1;
12931       else if (unformat (i, "disable"))
12932         enable_disable = 0;
12933       else
12934         break;
12935     }
12936
12937   if (sw_if_index_set == 0)
12938     {
12939       errmsg ("missing interface name or sw_if_index");
12940       return -99;
12941     }
12942
12943   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12944
12945   mp->sw_if_index = ntohl (sw_if_index);
12946   mp->enable_disable = enable_disable;
12947
12948   S (mp);
12949   W (ret);
12950   return ret;
12951 }
12952
12953 static int
12954 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12955 {
12956   unformat_input_t *i = vam->input;
12957   vl_api_l2tpv3_set_lookup_key_t *mp;
12958   u8 key = ~0;
12959   int ret;
12960
12961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12962     {
12963       if (unformat (i, "lookup_v6_src"))
12964         key = L2T_LOOKUP_SRC_ADDRESS;
12965       else if (unformat (i, "lookup_v6_dst"))
12966         key = L2T_LOOKUP_DST_ADDRESS;
12967       else if (unformat (i, "lookup_session_id"))
12968         key = L2T_LOOKUP_SESSION_ID;
12969       else
12970         break;
12971     }
12972
12973   if (key == (u8) ~ 0)
12974     {
12975       errmsg ("l2tp session lookup key unset");
12976       return -99;
12977     }
12978
12979   M (L2TPV3_SET_LOOKUP_KEY, mp);
12980
12981   mp->key = key;
12982
12983   S (mp);
12984   W (ret);
12985   return ret;
12986 }
12987
12988 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12989   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12990 {
12991   vat_main_t *vam = &vat_main;
12992
12993   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12994          format_ip6_address, mp->our_address,
12995          format_ip6_address, mp->client_address,
12996          clib_net_to_host_u32 (mp->sw_if_index));
12997
12998   print (vam->ofp,
12999          "   local cookies %016llx %016llx remote cookie %016llx",
13000          clib_net_to_host_u64 (mp->local_cookie[0]),
13001          clib_net_to_host_u64 (mp->local_cookie[1]),
13002          clib_net_to_host_u64 (mp->remote_cookie));
13003
13004   print (vam->ofp, "   local session-id %d remote session-id %d",
13005          clib_net_to_host_u32 (mp->local_session_id),
13006          clib_net_to_host_u32 (mp->remote_session_id));
13007
13008   print (vam->ofp, "   l2 specific sublayer %s\n",
13009          mp->l2_sublayer_present ? "preset" : "absent");
13010
13011 }
13012
13013 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13014   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13015 {
13016   vat_main_t *vam = &vat_main;
13017   vat_json_node_t *node = NULL;
13018   struct in6_addr addr;
13019
13020   if (VAT_JSON_ARRAY != vam->json_tree.type)
13021     {
13022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13023       vat_json_init_array (&vam->json_tree);
13024     }
13025   node = vat_json_array_add (&vam->json_tree);
13026
13027   vat_json_init_object (node);
13028
13029   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13030   vat_json_object_add_ip6 (node, "our_address", addr);
13031   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13032   vat_json_object_add_ip6 (node, "client_address", addr);
13033
13034   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13035   vat_json_init_array (lc);
13036   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13037   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13038   vat_json_object_add_uint (node, "remote_cookie",
13039                             clib_net_to_host_u64 (mp->remote_cookie));
13040
13041   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13042   vat_json_object_add_uint (node, "local_session_id",
13043                             clib_net_to_host_u32 (mp->local_session_id));
13044   vat_json_object_add_uint (node, "remote_session_id",
13045                             clib_net_to_host_u32 (mp->remote_session_id));
13046   vat_json_object_add_string_copy (node, "l2_sublayer",
13047                                    mp->l2_sublayer_present ? (u8 *) "present"
13048                                    : (u8 *) "absent");
13049 }
13050
13051 static int
13052 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13053 {
13054   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13055   vl_api_control_ping_t *mp_ping;
13056   int ret;
13057
13058   /* Get list of l2tpv3-tunnel interfaces */
13059   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13060   S (mp);
13061
13062   /* Use a control ping for synchronization */
13063   MPING (CONTROL_PING, mp_ping);
13064   S (mp_ping);
13065
13066   W (ret);
13067   return ret;
13068 }
13069
13070
13071 static void vl_api_sw_interface_tap_details_t_handler
13072   (vl_api_sw_interface_tap_details_t * mp)
13073 {
13074   vat_main_t *vam = &vat_main;
13075
13076   print (vam->ofp, "%-16s %d",
13077          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13078 }
13079
13080 static void vl_api_sw_interface_tap_details_t_handler_json
13081   (vl_api_sw_interface_tap_details_t * mp)
13082 {
13083   vat_main_t *vam = &vat_main;
13084   vat_json_node_t *node = NULL;
13085
13086   if (VAT_JSON_ARRAY != vam->json_tree.type)
13087     {
13088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13089       vat_json_init_array (&vam->json_tree);
13090     }
13091   node = vat_json_array_add (&vam->json_tree);
13092
13093   vat_json_init_object (node);
13094   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13095   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13096 }
13097
13098 static int
13099 api_sw_interface_tap_dump (vat_main_t * vam)
13100 {
13101   vl_api_sw_interface_tap_dump_t *mp;
13102   vl_api_control_ping_t *mp_ping;
13103   int ret;
13104
13105   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13106   /* Get list of tap interfaces */
13107   M (SW_INTERFACE_TAP_DUMP, mp);
13108   S (mp);
13109
13110   /* Use a control ping for synchronization */
13111   MPING (CONTROL_PING, mp_ping);
13112   S (mp_ping);
13113
13114   W (ret);
13115   return ret;
13116 }
13117
13118 static void vl_api_sw_interface_tap_v2_details_t_handler
13119   (vl_api_sw_interface_tap_v2_details_t * mp)
13120 {
13121   vat_main_t *vam = &vat_main;
13122
13123   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13124                     mp->host_ip4_prefix_len);
13125   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13126                     mp->host_ip6_prefix_len);
13127
13128   print (vam->ofp,
13129          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13130          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13131          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13132          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13133          mp->host_bridge, ip4, ip6);
13134
13135   vec_free (ip4);
13136   vec_free (ip6);
13137 }
13138
13139 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13140   (vl_api_sw_interface_tap_v2_details_t * mp)
13141 {
13142   vat_main_t *vam = &vat_main;
13143   vat_json_node_t *node = NULL;
13144
13145   if (VAT_JSON_ARRAY != vam->json_tree.type)
13146     {
13147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13148       vat_json_init_array (&vam->json_tree);
13149     }
13150   node = vat_json_array_add (&vam->json_tree);
13151
13152   vat_json_init_object (node);
13153   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13154   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13155   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13156   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13157   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13158   vat_json_object_add_string_copy (node, "host_mac_addr",
13159                                    format (0, "%U", format_ethernet_address,
13160                                            &mp->host_mac_addr));
13161   vat_json_object_add_string_copy (node, "host_namespace",
13162                                    mp->host_namespace);
13163   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13164   vat_json_object_add_string_copy (node, "host_ip4_addr",
13165                                    format (0, "%U/%d", format_ip4_address,
13166                                            mp->host_ip4_addr,
13167                                            mp->host_ip4_prefix_len));
13168   vat_json_object_add_string_copy (node, "host_ip6_addr",
13169                                    format (0, "%U/%d", format_ip6_address,
13170                                            mp->host_ip6_addr,
13171                                            mp->host_ip6_prefix_len));
13172
13173 }
13174
13175 static int
13176 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13177 {
13178   vl_api_sw_interface_tap_v2_dump_t *mp;
13179   vl_api_control_ping_t *mp_ping;
13180   int ret;
13181
13182   print (vam->ofp,
13183          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13184          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13185          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13186          "host_ip6_addr");
13187
13188   /* Get list of tap interfaces */
13189   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13190   S (mp);
13191
13192   /* Use a control ping for synchronization */
13193   MPING (CONTROL_PING, mp_ping);
13194   S (mp_ping);
13195
13196   W (ret);
13197   return ret;
13198 }
13199
13200 static int
13201 api_vxlan_offload_rx (vat_main_t * vam)
13202 {
13203   unformat_input_t *line_input = vam->input;
13204   vl_api_vxlan_offload_rx_t *mp;
13205   u32 hw_if_index = ~0, rx_if_index = ~0;
13206   u8 is_add = 1;
13207   int ret;
13208
13209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13210     {
13211       if (unformat (line_input, "del"))
13212         is_add = 0;
13213       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13214                          &hw_if_index))
13215         ;
13216       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13217         ;
13218       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13219                          &rx_if_index))
13220         ;
13221       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13222         ;
13223       else
13224         {
13225           errmsg ("parse error '%U'", format_unformat_error, line_input);
13226           return -99;
13227         }
13228     }
13229
13230   if (hw_if_index == ~0)
13231     {
13232       errmsg ("no hw interface");
13233       return -99;
13234     }
13235
13236   if (rx_if_index == ~0)
13237     {
13238       errmsg ("no rx tunnel");
13239       return -99;
13240     }
13241
13242   M (VXLAN_OFFLOAD_RX, mp);
13243
13244   mp->hw_if_index = ntohl (hw_if_index);
13245   mp->sw_if_index = ntohl (rx_if_index);
13246   mp->enable = is_add;
13247
13248   S (mp);
13249   W (ret);
13250   return ret;
13251 }
13252
13253 static uword unformat_vxlan_decap_next
13254   (unformat_input_t * input, va_list * args)
13255 {
13256   u32 *result = va_arg (*args, u32 *);
13257   u32 tmp;
13258
13259   if (unformat (input, "l2"))
13260     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13261   else if (unformat (input, "%d", &tmp))
13262     *result = tmp;
13263   else
13264     return 0;
13265   return 1;
13266 }
13267
13268 static int
13269 api_vxlan_add_del_tunnel (vat_main_t * vam)
13270 {
13271   unformat_input_t *line_input = vam->input;
13272   vl_api_vxlan_add_del_tunnel_t *mp;
13273   ip46_address_t src, dst;
13274   u8 is_add = 1;
13275   u8 ipv4_set = 0, ipv6_set = 0;
13276   u8 src_set = 0;
13277   u8 dst_set = 0;
13278   u8 grp_set = 0;
13279   u32 instance = ~0;
13280   u32 mcast_sw_if_index = ~0;
13281   u32 encap_vrf_id = 0;
13282   u32 decap_next_index = ~0;
13283   u32 vni = 0;
13284   int ret;
13285
13286   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13287   memset (&src, 0, sizeof src);
13288   memset (&dst, 0, sizeof dst);
13289
13290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13291     {
13292       if (unformat (line_input, "del"))
13293         is_add = 0;
13294       else if (unformat (line_input, "instance %d", &instance))
13295         ;
13296       else
13297         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13298         {
13299           ipv4_set = 1;
13300           src_set = 1;
13301         }
13302       else
13303         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13304         {
13305           ipv4_set = 1;
13306           dst_set = 1;
13307         }
13308       else
13309         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13310         {
13311           ipv6_set = 1;
13312           src_set = 1;
13313         }
13314       else
13315         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13316         {
13317           ipv6_set = 1;
13318           dst_set = 1;
13319         }
13320       else if (unformat (line_input, "group %U %U",
13321                          unformat_ip4_address, &dst.ip4,
13322                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13323         {
13324           grp_set = dst_set = 1;
13325           ipv4_set = 1;
13326         }
13327       else if (unformat (line_input, "group %U",
13328                          unformat_ip4_address, &dst.ip4))
13329         {
13330           grp_set = dst_set = 1;
13331           ipv4_set = 1;
13332         }
13333       else if (unformat (line_input, "group %U %U",
13334                          unformat_ip6_address, &dst.ip6,
13335                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13336         {
13337           grp_set = dst_set = 1;
13338           ipv6_set = 1;
13339         }
13340       else if (unformat (line_input, "group %U",
13341                          unformat_ip6_address, &dst.ip6))
13342         {
13343           grp_set = dst_set = 1;
13344           ipv6_set = 1;
13345         }
13346       else
13347         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13348         ;
13349       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13350         ;
13351       else if (unformat (line_input, "decap-next %U",
13352                          unformat_vxlan_decap_next, &decap_next_index))
13353         ;
13354       else if (unformat (line_input, "vni %d", &vni))
13355         ;
13356       else
13357         {
13358           errmsg ("parse error '%U'", format_unformat_error, line_input);
13359           return -99;
13360         }
13361     }
13362
13363   if (src_set == 0)
13364     {
13365       errmsg ("tunnel src address not specified");
13366       return -99;
13367     }
13368   if (dst_set == 0)
13369     {
13370       errmsg ("tunnel dst address not specified");
13371       return -99;
13372     }
13373
13374   if (grp_set && !ip46_address_is_multicast (&dst))
13375     {
13376       errmsg ("tunnel group address not multicast");
13377       return -99;
13378     }
13379   if (grp_set && mcast_sw_if_index == ~0)
13380     {
13381       errmsg ("tunnel nonexistent multicast device");
13382       return -99;
13383     }
13384   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13385     {
13386       errmsg ("tunnel dst address must be unicast");
13387       return -99;
13388     }
13389
13390
13391   if (ipv4_set && ipv6_set)
13392     {
13393       errmsg ("both IPv4 and IPv6 addresses specified");
13394       return -99;
13395     }
13396
13397   if ((vni == 0) || (vni >> 24))
13398     {
13399       errmsg ("vni not specified or out of range");
13400       return -99;
13401     }
13402
13403   M (VXLAN_ADD_DEL_TUNNEL, mp);
13404
13405   if (ipv6_set)
13406     {
13407       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13408       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13409     }
13410   else
13411     {
13412       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13413       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13414     }
13415
13416   mp->instance = htonl (instance);
13417   mp->encap_vrf_id = ntohl (encap_vrf_id);
13418   mp->decap_next_index = ntohl (decap_next_index);
13419   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13420   mp->vni = ntohl (vni);
13421   mp->is_add = is_add;
13422   mp->is_ipv6 = ipv6_set;
13423
13424   S (mp);
13425   W (ret);
13426   return ret;
13427 }
13428
13429 static void vl_api_vxlan_tunnel_details_t_handler
13430   (vl_api_vxlan_tunnel_details_t * mp)
13431 {
13432   vat_main_t *vam = &vat_main;
13433   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13434   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13435
13436   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13437          ntohl (mp->sw_if_index),
13438          ntohl (mp->instance),
13439          format_ip46_address, &src, IP46_TYPE_ANY,
13440          format_ip46_address, &dst, IP46_TYPE_ANY,
13441          ntohl (mp->encap_vrf_id),
13442          ntohl (mp->decap_next_index), ntohl (mp->vni),
13443          ntohl (mp->mcast_sw_if_index));
13444 }
13445
13446 static void vl_api_vxlan_tunnel_details_t_handler_json
13447   (vl_api_vxlan_tunnel_details_t * mp)
13448 {
13449   vat_main_t *vam = &vat_main;
13450   vat_json_node_t *node = NULL;
13451
13452   if (VAT_JSON_ARRAY != vam->json_tree.type)
13453     {
13454       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13455       vat_json_init_array (&vam->json_tree);
13456     }
13457   node = vat_json_array_add (&vam->json_tree);
13458
13459   vat_json_init_object (node);
13460   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13461
13462   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13463
13464   if (mp->is_ipv6)
13465     {
13466       struct in6_addr ip6;
13467
13468       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13469       vat_json_object_add_ip6 (node, "src_address", ip6);
13470       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13471       vat_json_object_add_ip6 (node, "dst_address", ip6);
13472     }
13473   else
13474     {
13475       struct in_addr ip4;
13476
13477       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13478       vat_json_object_add_ip4 (node, "src_address", ip4);
13479       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13480       vat_json_object_add_ip4 (node, "dst_address", ip4);
13481     }
13482   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13483   vat_json_object_add_uint (node, "decap_next_index",
13484                             ntohl (mp->decap_next_index));
13485   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13486   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13487   vat_json_object_add_uint (node, "mcast_sw_if_index",
13488                             ntohl (mp->mcast_sw_if_index));
13489 }
13490
13491 static int
13492 api_vxlan_tunnel_dump (vat_main_t * vam)
13493 {
13494   unformat_input_t *i = vam->input;
13495   vl_api_vxlan_tunnel_dump_t *mp;
13496   vl_api_control_ping_t *mp_ping;
13497   u32 sw_if_index;
13498   u8 sw_if_index_set = 0;
13499   int ret;
13500
13501   /* Parse args required to build the message */
13502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13503     {
13504       if (unformat (i, "sw_if_index %d", &sw_if_index))
13505         sw_if_index_set = 1;
13506       else
13507         break;
13508     }
13509
13510   if (sw_if_index_set == 0)
13511     {
13512       sw_if_index = ~0;
13513     }
13514
13515   if (!vam->json_output)
13516     {
13517       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13518              "sw_if_index", "instance", "src_address", "dst_address",
13519              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13520     }
13521
13522   /* Get list of vxlan-tunnel interfaces */
13523   M (VXLAN_TUNNEL_DUMP, mp);
13524
13525   mp->sw_if_index = htonl (sw_if_index);
13526
13527   S (mp);
13528
13529   /* Use a control ping for synchronization */
13530   MPING (CONTROL_PING, mp_ping);
13531   S (mp_ping);
13532
13533   W (ret);
13534   return ret;
13535 }
13536
13537 static uword unformat_geneve_decap_next
13538   (unformat_input_t * input, va_list * args)
13539 {
13540   u32 *result = va_arg (*args, u32 *);
13541   u32 tmp;
13542
13543   if (unformat (input, "l2"))
13544     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13545   else if (unformat (input, "%d", &tmp))
13546     *result = tmp;
13547   else
13548     return 0;
13549   return 1;
13550 }
13551
13552 static int
13553 api_geneve_add_del_tunnel (vat_main_t * vam)
13554 {
13555   unformat_input_t *line_input = vam->input;
13556   vl_api_geneve_add_del_tunnel_t *mp;
13557   ip46_address_t src, dst;
13558   u8 is_add = 1;
13559   u8 ipv4_set = 0, ipv6_set = 0;
13560   u8 src_set = 0;
13561   u8 dst_set = 0;
13562   u8 grp_set = 0;
13563   u32 mcast_sw_if_index = ~0;
13564   u32 encap_vrf_id = 0;
13565   u32 decap_next_index = ~0;
13566   u32 vni = 0;
13567   int ret;
13568
13569   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13570   memset (&src, 0, sizeof src);
13571   memset (&dst, 0, sizeof dst);
13572
13573   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13574     {
13575       if (unformat (line_input, "del"))
13576         is_add = 0;
13577       else
13578         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13579         {
13580           ipv4_set = 1;
13581           src_set = 1;
13582         }
13583       else
13584         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13585         {
13586           ipv4_set = 1;
13587           dst_set = 1;
13588         }
13589       else
13590         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13591         {
13592           ipv6_set = 1;
13593           src_set = 1;
13594         }
13595       else
13596         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13597         {
13598           ipv6_set = 1;
13599           dst_set = 1;
13600         }
13601       else if (unformat (line_input, "group %U %U",
13602                          unformat_ip4_address, &dst.ip4,
13603                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13604         {
13605           grp_set = dst_set = 1;
13606           ipv4_set = 1;
13607         }
13608       else if (unformat (line_input, "group %U",
13609                          unformat_ip4_address, &dst.ip4))
13610         {
13611           grp_set = dst_set = 1;
13612           ipv4_set = 1;
13613         }
13614       else if (unformat (line_input, "group %U %U",
13615                          unformat_ip6_address, &dst.ip6,
13616                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13617         {
13618           grp_set = dst_set = 1;
13619           ipv6_set = 1;
13620         }
13621       else if (unformat (line_input, "group %U",
13622                          unformat_ip6_address, &dst.ip6))
13623         {
13624           grp_set = dst_set = 1;
13625           ipv6_set = 1;
13626         }
13627       else
13628         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13629         ;
13630       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13631         ;
13632       else if (unformat (line_input, "decap-next %U",
13633                          unformat_geneve_decap_next, &decap_next_index))
13634         ;
13635       else if (unformat (line_input, "vni %d", &vni))
13636         ;
13637       else
13638         {
13639           errmsg ("parse error '%U'", format_unformat_error, line_input);
13640           return -99;
13641         }
13642     }
13643
13644   if (src_set == 0)
13645     {
13646       errmsg ("tunnel src address not specified");
13647       return -99;
13648     }
13649   if (dst_set == 0)
13650     {
13651       errmsg ("tunnel dst address not specified");
13652       return -99;
13653     }
13654
13655   if (grp_set && !ip46_address_is_multicast (&dst))
13656     {
13657       errmsg ("tunnel group address not multicast");
13658       return -99;
13659     }
13660   if (grp_set && mcast_sw_if_index == ~0)
13661     {
13662       errmsg ("tunnel nonexistent multicast device");
13663       return -99;
13664     }
13665   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13666     {
13667       errmsg ("tunnel dst address must be unicast");
13668       return -99;
13669     }
13670
13671
13672   if (ipv4_set && ipv6_set)
13673     {
13674       errmsg ("both IPv4 and IPv6 addresses specified");
13675       return -99;
13676     }
13677
13678   if ((vni == 0) || (vni >> 24))
13679     {
13680       errmsg ("vni not specified or out of range");
13681       return -99;
13682     }
13683
13684   M (GENEVE_ADD_DEL_TUNNEL, mp);
13685
13686   if (ipv6_set)
13687     {
13688       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13689       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13690     }
13691   else
13692     {
13693       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13694       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13695     }
13696   mp->encap_vrf_id = ntohl (encap_vrf_id);
13697   mp->decap_next_index = ntohl (decap_next_index);
13698   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13699   mp->vni = ntohl (vni);
13700   mp->is_add = is_add;
13701   mp->is_ipv6 = ipv6_set;
13702
13703   S (mp);
13704   W (ret);
13705   return ret;
13706 }
13707
13708 static void vl_api_geneve_tunnel_details_t_handler
13709   (vl_api_geneve_tunnel_details_t * mp)
13710 {
13711   vat_main_t *vam = &vat_main;
13712   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13713   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13714
13715   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13716          ntohl (mp->sw_if_index),
13717          format_ip46_address, &src, IP46_TYPE_ANY,
13718          format_ip46_address, &dst, IP46_TYPE_ANY,
13719          ntohl (mp->encap_vrf_id),
13720          ntohl (mp->decap_next_index), ntohl (mp->vni),
13721          ntohl (mp->mcast_sw_if_index));
13722 }
13723
13724 static void vl_api_geneve_tunnel_details_t_handler_json
13725   (vl_api_geneve_tunnel_details_t * mp)
13726 {
13727   vat_main_t *vam = &vat_main;
13728   vat_json_node_t *node = NULL;
13729
13730   if (VAT_JSON_ARRAY != vam->json_tree.type)
13731     {
13732       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13733       vat_json_init_array (&vam->json_tree);
13734     }
13735   node = vat_json_array_add (&vam->json_tree);
13736
13737   vat_json_init_object (node);
13738   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13739   if (mp->is_ipv6)
13740     {
13741       struct in6_addr ip6;
13742
13743       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13744       vat_json_object_add_ip6 (node, "src_address", ip6);
13745       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13746       vat_json_object_add_ip6 (node, "dst_address", ip6);
13747     }
13748   else
13749     {
13750       struct in_addr ip4;
13751
13752       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13753       vat_json_object_add_ip4 (node, "src_address", ip4);
13754       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13755       vat_json_object_add_ip4 (node, "dst_address", ip4);
13756     }
13757   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13758   vat_json_object_add_uint (node, "decap_next_index",
13759                             ntohl (mp->decap_next_index));
13760   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13761   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13762   vat_json_object_add_uint (node, "mcast_sw_if_index",
13763                             ntohl (mp->mcast_sw_if_index));
13764 }
13765
13766 static int
13767 api_geneve_tunnel_dump (vat_main_t * vam)
13768 {
13769   unformat_input_t *i = vam->input;
13770   vl_api_geneve_tunnel_dump_t *mp;
13771   vl_api_control_ping_t *mp_ping;
13772   u32 sw_if_index;
13773   u8 sw_if_index_set = 0;
13774   int ret;
13775
13776   /* Parse args required to build the message */
13777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13778     {
13779       if (unformat (i, "sw_if_index %d", &sw_if_index))
13780         sw_if_index_set = 1;
13781       else
13782         break;
13783     }
13784
13785   if (sw_if_index_set == 0)
13786     {
13787       sw_if_index = ~0;
13788     }
13789
13790   if (!vam->json_output)
13791     {
13792       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13793              "sw_if_index", "local_address", "remote_address",
13794              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13795     }
13796
13797   /* Get list of geneve-tunnel interfaces */
13798   M (GENEVE_TUNNEL_DUMP, mp);
13799
13800   mp->sw_if_index = htonl (sw_if_index);
13801
13802   S (mp);
13803
13804   /* Use a control ping for synchronization */
13805   M (CONTROL_PING, mp_ping);
13806   S (mp_ping);
13807
13808   W (ret);
13809   return ret;
13810 }
13811
13812 static int
13813 api_gre_add_del_tunnel (vat_main_t * vam)
13814 {
13815   unformat_input_t *line_input = vam->input;
13816   vl_api_gre_add_del_tunnel_t *mp;
13817   ip4_address_t src4, dst4;
13818   ip6_address_t src6, dst6;
13819   u8 is_add = 1;
13820   u8 ipv4_set = 0;
13821   u8 ipv6_set = 0;
13822   u8 t_type = GRE_TUNNEL_TYPE_L3;
13823   u8 src_set = 0;
13824   u8 dst_set = 0;
13825   u32 outer_fib_id = 0;
13826   u32 session_id = 0;
13827   u32 instance = ~0;
13828   int ret;
13829
13830   memset (&src4, 0, sizeof src4);
13831   memset (&dst4, 0, sizeof dst4);
13832   memset (&src6, 0, sizeof src6);
13833   memset (&dst6, 0, sizeof dst6);
13834
13835   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13836     {
13837       if (unformat (line_input, "del"))
13838         is_add = 0;
13839       else if (unformat (line_input, "instance %d", &instance))
13840         ;
13841       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13842         {
13843           src_set = 1;
13844           ipv4_set = 1;
13845         }
13846       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13847         {
13848           dst_set = 1;
13849           ipv4_set = 1;
13850         }
13851       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13852         {
13853           src_set = 1;
13854           ipv6_set = 1;
13855         }
13856       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13857         {
13858           dst_set = 1;
13859           ipv6_set = 1;
13860         }
13861       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13862         ;
13863       else if (unformat (line_input, "teb"))
13864         t_type = GRE_TUNNEL_TYPE_TEB;
13865       else if (unformat (line_input, "erspan %d", &session_id))
13866         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13867       else
13868         {
13869           errmsg ("parse error '%U'", format_unformat_error, line_input);
13870           return -99;
13871         }
13872     }
13873
13874   if (src_set == 0)
13875     {
13876       errmsg ("tunnel src address not specified");
13877       return -99;
13878     }
13879   if (dst_set == 0)
13880     {
13881       errmsg ("tunnel dst address not specified");
13882       return -99;
13883     }
13884   if (ipv4_set && ipv6_set)
13885     {
13886       errmsg ("both IPv4 and IPv6 addresses specified");
13887       return -99;
13888     }
13889
13890
13891   M (GRE_ADD_DEL_TUNNEL, mp);
13892
13893   if (ipv4_set)
13894     {
13895       clib_memcpy (&mp->src_address, &src4, 4);
13896       clib_memcpy (&mp->dst_address, &dst4, 4);
13897     }
13898   else
13899     {
13900       clib_memcpy (&mp->src_address, &src6, 16);
13901       clib_memcpy (&mp->dst_address, &dst6, 16);
13902     }
13903   mp->instance = htonl (instance);
13904   mp->outer_fib_id = htonl (outer_fib_id);
13905   mp->is_add = is_add;
13906   mp->session_id = htons ((u16) session_id);
13907   mp->tunnel_type = t_type;
13908   mp->is_ipv6 = ipv6_set;
13909
13910   S (mp);
13911   W (ret);
13912   return ret;
13913 }
13914
13915 static void vl_api_gre_tunnel_details_t_handler
13916   (vl_api_gre_tunnel_details_t * mp)
13917 {
13918   vat_main_t *vam = &vat_main;
13919   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13920   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13921
13922   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13923          ntohl (mp->sw_if_index),
13924          ntohl (mp->instance),
13925          format_ip46_address, &src, IP46_TYPE_ANY,
13926          format_ip46_address, &dst, IP46_TYPE_ANY,
13927          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13928 }
13929
13930 static void vl_api_gre_tunnel_details_t_handler_json
13931   (vl_api_gre_tunnel_details_t * mp)
13932 {
13933   vat_main_t *vam = &vat_main;
13934   vat_json_node_t *node = NULL;
13935   struct in_addr ip4;
13936   struct in6_addr ip6;
13937
13938   if (VAT_JSON_ARRAY != vam->json_tree.type)
13939     {
13940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13941       vat_json_init_array (&vam->json_tree);
13942     }
13943   node = vat_json_array_add (&vam->json_tree);
13944
13945   vat_json_init_object (node);
13946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13947   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13948   if (!mp->is_ipv6)
13949     {
13950       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13951       vat_json_object_add_ip4 (node, "src_address", ip4);
13952       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13953       vat_json_object_add_ip4 (node, "dst_address", ip4);
13954     }
13955   else
13956     {
13957       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13958       vat_json_object_add_ip6 (node, "src_address", ip6);
13959       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13960       vat_json_object_add_ip6 (node, "dst_address", ip6);
13961     }
13962   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13963   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13964   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13965   vat_json_object_add_uint (node, "session_id", mp->session_id);
13966 }
13967
13968 static int
13969 api_gre_tunnel_dump (vat_main_t * vam)
13970 {
13971   unformat_input_t *i = vam->input;
13972   vl_api_gre_tunnel_dump_t *mp;
13973   vl_api_control_ping_t *mp_ping;
13974   u32 sw_if_index;
13975   u8 sw_if_index_set = 0;
13976   int ret;
13977
13978   /* Parse args required to build the message */
13979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13980     {
13981       if (unformat (i, "sw_if_index %d", &sw_if_index))
13982         sw_if_index_set = 1;
13983       else
13984         break;
13985     }
13986
13987   if (sw_if_index_set == 0)
13988     {
13989       sw_if_index = ~0;
13990     }
13991
13992   if (!vam->json_output)
13993     {
13994       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13995              "sw_if_index", "instance", "src_address", "dst_address",
13996              "tunnel_type", "outer_fib_id", "session_id");
13997     }
13998
13999   /* Get list of gre-tunnel interfaces */
14000   M (GRE_TUNNEL_DUMP, mp);
14001
14002   mp->sw_if_index = htonl (sw_if_index);
14003
14004   S (mp);
14005
14006   /* Use a control ping for synchronization */
14007   MPING (CONTROL_PING, mp_ping);
14008   S (mp_ping);
14009
14010   W (ret);
14011   return ret;
14012 }
14013
14014 static int
14015 api_l2_fib_clear_table (vat_main_t * vam)
14016 {
14017 //  unformat_input_t * i = vam->input;
14018   vl_api_l2_fib_clear_table_t *mp;
14019   int ret;
14020
14021   M (L2_FIB_CLEAR_TABLE, mp);
14022
14023   S (mp);
14024   W (ret);
14025   return ret;
14026 }
14027
14028 static int
14029 api_l2_interface_efp_filter (vat_main_t * vam)
14030 {
14031   unformat_input_t *i = vam->input;
14032   vl_api_l2_interface_efp_filter_t *mp;
14033   u32 sw_if_index;
14034   u8 enable = 1;
14035   u8 sw_if_index_set = 0;
14036   int ret;
14037
14038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14039     {
14040       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14041         sw_if_index_set = 1;
14042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14043         sw_if_index_set = 1;
14044       else if (unformat (i, "enable"))
14045         enable = 1;
14046       else if (unformat (i, "disable"))
14047         enable = 0;
14048       else
14049         {
14050           clib_warning ("parse error '%U'", format_unformat_error, i);
14051           return -99;
14052         }
14053     }
14054
14055   if (sw_if_index_set == 0)
14056     {
14057       errmsg ("missing sw_if_index");
14058       return -99;
14059     }
14060
14061   M (L2_INTERFACE_EFP_FILTER, mp);
14062
14063   mp->sw_if_index = ntohl (sw_if_index);
14064   mp->enable_disable = enable;
14065
14066   S (mp);
14067   W (ret);
14068   return ret;
14069 }
14070
14071 #define foreach_vtr_op                          \
14072 _("disable",  L2_VTR_DISABLED)                  \
14073 _("push-1",  L2_VTR_PUSH_1)                     \
14074 _("push-2",  L2_VTR_PUSH_2)                     \
14075 _("pop-1",  L2_VTR_POP_1)                       \
14076 _("pop-2",  L2_VTR_POP_2)                       \
14077 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14078 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14079 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14080 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14081
14082 static int
14083 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14084 {
14085   unformat_input_t *i = vam->input;
14086   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14087   u32 sw_if_index;
14088   u8 sw_if_index_set = 0;
14089   u8 vtr_op_set = 0;
14090   u32 vtr_op = 0;
14091   u32 push_dot1q = 1;
14092   u32 tag1 = ~0;
14093   u32 tag2 = ~0;
14094   int ret;
14095
14096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14097     {
14098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14099         sw_if_index_set = 1;
14100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14101         sw_if_index_set = 1;
14102       else if (unformat (i, "vtr_op %d", &vtr_op))
14103         vtr_op_set = 1;
14104 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14105       foreach_vtr_op
14106 #undef _
14107         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14108         ;
14109       else if (unformat (i, "tag1 %d", &tag1))
14110         ;
14111       else if (unformat (i, "tag2 %d", &tag2))
14112         ;
14113       else
14114         {
14115           clib_warning ("parse error '%U'", format_unformat_error, i);
14116           return -99;
14117         }
14118     }
14119
14120   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14121     {
14122       errmsg ("missing vtr operation or sw_if_index");
14123       return -99;
14124     }
14125
14126   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14127   mp->sw_if_index = ntohl (sw_if_index);
14128   mp->vtr_op = ntohl (vtr_op);
14129   mp->push_dot1q = ntohl (push_dot1q);
14130   mp->tag1 = ntohl (tag1);
14131   mp->tag2 = ntohl (tag2);
14132
14133   S (mp);
14134   W (ret);
14135   return ret;
14136 }
14137
14138 static int
14139 api_create_vhost_user_if (vat_main_t * vam)
14140 {
14141   unformat_input_t *i = vam->input;
14142   vl_api_create_vhost_user_if_t *mp;
14143   u8 *file_name;
14144   u8 is_server = 0;
14145   u8 file_name_set = 0;
14146   u32 custom_dev_instance = ~0;
14147   u8 hwaddr[6];
14148   u8 use_custom_mac = 0;
14149   u8 disable_mrg_rxbuf = 0;
14150   u8 disable_indirect_desc = 0;
14151   u8 *tag = 0;
14152   int ret;
14153
14154   /* Shut up coverity */
14155   memset (hwaddr, 0, sizeof (hwaddr));
14156
14157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14158     {
14159       if (unformat (i, "socket %s", &file_name))
14160         {
14161           file_name_set = 1;
14162         }
14163       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14164         ;
14165       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14166         use_custom_mac = 1;
14167       else if (unformat (i, "server"))
14168         is_server = 1;
14169       else if (unformat (i, "disable_mrg_rxbuf"))
14170         disable_mrg_rxbuf = 1;
14171       else if (unformat (i, "disable_indirect_desc"))
14172         disable_indirect_desc = 1;
14173       else if (unformat (i, "tag %s", &tag))
14174         ;
14175       else
14176         break;
14177     }
14178
14179   if (file_name_set == 0)
14180     {
14181       errmsg ("missing socket file name");
14182       return -99;
14183     }
14184
14185   if (vec_len (file_name) > 255)
14186     {
14187       errmsg ("socket file name too long");
14188       return -99;
14189     }
14190   vec_add1 (file_name, 0);
14191
14192   M (CREATE_VHOST_USER_IF, mp);
14193
14194   mp->is_server = is_server;
14195   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14196   mp->disable_indirect_desc = disable_indirect_desc;
14197   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14198   vec_free (file_name);
14199   if (custom_dev_instance != ~0)
14200     {
14201       mp->renumber = 1;
14202       mp->custom_dev_instance = ntohl (custom_dev_instance);
14203     }
14204
14205   mp->use_custom_mac = use_custom_mac;
14206   clib_memcpy (mp->mac_address, hwaddr, 6);
14207   if (tag)
14208     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14209   vec_free (tag);
14210
14211   S (mp);
14212   W (ret);
14213   return ret;
14214 }
14215
14216 static int
14217 api_modify_vhost_user_if (vat_main_t * vam)
14218 {
14219   unformat_input_t *i = vam->input;
14220   vl_api_modify_vhost_user_if_t *mp;
14221   u8 *file_name;
14222   u8 is_server = 0;
14223   u8 file_name_set = 0;
14224   u32 custom_dev_instance = ~0;
14225   u8 sw_if_index_set = 0;
14226   u32 sw_if_index = (u32) ~ 0;
14227   int ret;
14228
14229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14230     {
14231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14232         sw_if_index_set = 1;
14233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14234         sw_if_index_set = 1;
14235       else if (unformat (i, "socket %s", &file_name))
14236         {
14237           file_name_set = 1;
14238         }
14239       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14240         ;
14241       else if (unformat (i, "server"))
14242         is_server = 1;
14243       else
14244         break;
14245     }
14246
14247   if (sw_if_index_set == 0)
14248     {
14249       errmsg ("missing sw_if_index or interface name");
14250       return -99;
14251     }
14252
14253   if (file_name_set == 0)
14254     {
14255       errmsg ("missing socket file name");
14256       return -99;
14257     }
14258
14259   if (vec_len (file_name) > 255)
14260     {
14261       errmsg ("socket file name too long");
14262       return -99;
14263     }
14264   vec_add1 (file_name, 0);
14265
14266   M (MODIFY_VHOST_USER_IF, mp);
14267
14268   mp->sw_if_index = ntohl (sw_if_index);
14269   mp->is_server = is_server;
14270   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14271   vec_free (file_name);
14272   if (custom_dev_instance != ~0)
14273     {
14274       mp->renumber = 1;
14275       mp->custom_dev_instance = ntohl (custom_dev_instance);
14276     }
14277
14278   S (mp);
14279   W (ret);
14280   return ret;
14281 }
14282
14283 static int
14284 api_delete_vhost_user_if (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_delete_vhost_user_if_t *mp;
14288   u32 sw_if_index = ~0;
14289   u8 sw_if_index_set = 0;
14290   int ret;
14291
14292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14295         sw_if_index_set = 1;
14296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14297         sw_if_index_set = 1;
14298       else
14299         break;
14300     }
14301
14302   if (sw_if_index_set == 0)
14303     {
14304       errmsg ("missing sw_if_index or interface name");
14305       return -99;
14306     }
14307
14308
14309   M (DELETE_VHOST_USER_IF, mp);
14310
14311   mp->sw_if_index = ntohl (sw_if_index);
14312
14313   S (mp);
14314   W (ret);
14315   return ret;
14316 }
14317
14318 static void vl_api_sw_interface_vhost_user_details_t_handler
14319   (vl_api_sw_interface_vhost_user_details_t * mp)
14320 {
14321   vat_main_t *vam = &vat_main;
14322
14323   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14324          (char *) mp->interface_name,
14325          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14326          clib_net_to_host_u64 (mp->features), mp->is_server,
14327          ntohl (mp->num_regions), (char *) mp->sock_filename);
14328   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14329 }
14330
14331 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14332   (vl_api_sw_interface_vhost_user_details_t * mp)
14333 {
14334   vat_main_t *vam = &vat_main;
14335   vat_json_node_t *node = NULL;
14336
14337   if (VAT_JSON_ARRAY != vam->json_tree.type)
14338     {
14339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14340       vat_json_init_array (&vam->json_tree);
14341     }
14342   node = vat_json_array_add (&vam->json_tree);
14343
14344   vat_json_init_object (node);
14345   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14346   vat_json_object_add_string_copy (node, "interface_name",
14347                                    mp->interface_name);
14348   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14349                             ntohl (mp->virtio_net_hdr_sz));
14350   vat_json_object_add_uint (node, "features",
14351                             clib_net_to_host_u64 (mp->features));
14352   vat_json_object_add_uint (node, "is_server", mp->is_server);
14353   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14354   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14355   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14356 }
14357
14358 static int
14359 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14360 {
14361   vl_api_sw_interface_vhost_user_dump_t *mp;
14362   vl_api_control_ping_t *mp_ping;
14363   int ret;
14364   print (vam->ofp,
14365          "Interface name            idx hdr_sz features server regions filename");
14366
14367   /* Get list of vhost-user interfaces */
14368   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14369   S (mp);
14370
14371   /* Use a control ping for synchronization */
14372   MPING (CONTROL_PING, mp_ping);
14373   S (mp_ping);
14374
14375   W (ret);
14376   return ret;
14377 }
14378
14379 static int
14380 api_show_version (vat_main_t * vam)
14381 {
14382   vl_api_show_version_t *mp;
14383   int ret;
14384
14385   M (SHOW_VERSION, mp);
14386
14387   S (mp);
14388   W (ret);
14389   return ret;
14390 }
14391
14392
14393 static int
14394 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14395 {
14396   unformat_input_t *line_input = vam->input;
14397   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14398   ip4_address_t local4, remote4;
14399   ip6_address_t local6, remote6;
14400   u8 is_add = 1;
14401   u8 ipv4_set = 0, ipv6_set = 0;
14402   u8 local_set = 0;
14403   u8 remote_set = 0;
14404   u8 grp_set = 0;
14405   u32 mcast_sw_if_index = ~0;
14406   u32 encap_vrf_id = 0;
14407   u32 decap_vrf_id = 0;
14408   u8 protocol = ~0;
14409   u32 vni;
14410   u8 vni_set = 0;
14411   int ret;
14412
14413   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14414   memset (&local4, 0, sizeof local4);
14415   memset (&remote4, 0, sizeof remote4);
14416   memset (&local6, 0, sizeof local6);
14417   memset (&remote6, 0, sizeof remote6);
14418
14419   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14420     {
14421       if (unformat (line_input, "del"))
14422         is_add = 0;
14423       else if (unformat (line_input, "local %U",
14424                          unformat_ip4_address, &local4))
14425         {
14426           local_set = 1;
14427           ipv4_set = 1;
14428         }
14429       else if (unformat (line_input, "remote %U",
14430                          unformat_ip4_address, &remote4))
14431         {
14432           remote_set = 1;
14433           ipv4_set = 1;
14434         }
14435       else if (unformat (line_input, "local %U",
14436                          unformat_ip6_address, &local6))
14437         {
14438           local_set = 1;
14439           ipv6_set = 1;
14440         }
14441       else if (unformat (line_input, "remote %U",
14442                          unformat_ip6_address, &remote6))
14443         {
14444           remote_set = 1;
14445           ipv6_set = 1;
14446         }
14447       else if (unformat (line_input, "group %U %U",
14448                          unformat_ip4_address, &remote4,
14449                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14450         {
14451           grp_set = remote_set = 1;
14452           ipv4_set = 1;
14453         }
14454       else if (unformat (line_input, "group %U",
14455                          unformat_ip4_address, &remote4))
14456         {
14457           grp_set = remote_set = 1;
14458           ipv4_set = 1;
14459         }
14460       else if (unformat (line_input, "group %U %U",
14461                          unformat_ip6_address, &remote6,
14462                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14463         {
14464           grp_set = remote_set = 1;
14465           ipv6_set = 1;
14466         }
14467       else if (unformat (line_input, "group %U",
14468                          unformat_ip6_address, &remote6))
14469         {
14470           grp_set = remote_set = 1;
14471           ipv6_set = 1;
14472         }
14473       else
14474         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14475         ;
14476       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14477         ;
14478       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14479         ;
14480       else if (unformat (line_input, "vni %d", &vni))
14481         vni_set = 1;
14482       else if (unformat (line_input, "next-ip4"))
14483         protocol = 1;
14484       else if (unformat (line_input, "next-ip6"))
14485         protocol = 2;
14486       else if (unformat (line_input, "next-ethernet"))
14487         protocol = 3;
14488       else if (unformat (line_input, "next-nsh"))
14489         protocol = 4;
14490       else
14491         {
14492           errmsg ("parse error '%U'", format_unformat_error, line_input);
14493           return -99;
14494         }
14495     }
14496
14497   if (local_set == 0)
14498     {
14499       errmsg ("tunnel local address not specified");
14500       return -99;
14501     }
14502   if (remote_set == 0)
14503     {
14504       errmsg ("tunnel remote address not specified");
14505       return -99;
14506     }
14507   if (grp_set && mcast_sw_if_index == ~0)
14508     {
14509       errmsg ("tunnel nonexistent multicast device");
14510       return -99;
14511     }
14512   if (ipv4_set && ipv6_set)
14513     {
14514       errmsg ("both IPv4 and IPv6 addresses specified");
14515       return -99;
14516     }
14517
14518   if (vni_set == 0)
14519     {
14520       errmsg ("vni not specified");
14521       return -99;
14522     }
14523
14524   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14525
14526
14527   if (ipv6_set)
14528     {
14529       clib_memcpy (&mp->local, &local6, sizeof (local6));
14530       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14531     }
14532   else
14533     {
14534       clib_memcpy (&mp->local, &local4, sizeof (local4));
14535       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14536     }
14537
14538   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14539   mp->encap_vrf_id = ntohl (encap_vrf_id);
14540   mp->decap_vrf_id = ntohl (decap_vrf_id);
14541   mp->protocol = protocol;
14542   mp->vni = ntohl (vni);
14543   mp->is_add = is_add;
14544   mp->is_ipv6 = ipv6_set;
14545
14546   S (mp);
14547   W (ret);
14548   return ret;
14549 }
14550
14551 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14552   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14553 {
14554   vat_main_t *vam = &vat_main;
14555   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14556   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14557
14558   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14559          ntohl (mp->sw_if_index),
14560          format_ip46_address, &local, IP46_TYPE_ANY,
14561          format_ip46_address, &remote, IP46_TYPE_ANY,
14562          ntohl (mp->vni), mp->protocol,
14563          ntohl (mp->mcast_sw_if_index),
14564          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14565 }
14566
14567
14568 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14569   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14570 {
14571   vat_main_t *vam = &vat_main;
14572   vat_json_node_t *node = NULL;
14573   struct in_addr ip4;
14574   struct in6_addr ip6;
14575
14576   if (VAT_JSON_ARRAY != vam->json_tree.type)
14577     {
14578       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14579       vat_json_init_array (&vam->json_tree);
14580     }
14581   node = vat_json_array_add (&vam->json_tree);
14582
14583   vat_json_init_object (node);
14584   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14585   if (mp->is_ipv6)
14586     {
14587       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14588       vat_json_object_add_ip6 (node, "local", ip6);
14589       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14590       vat_json_object_add_ip6 (node, "remote", ip6);
14591     }
14592   else
14593     {
14594       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14595       vat_json_object_add_ip4 (node, "local", ip4);
14596       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14597       vat_json_object_add_ip4 (node, "remote", ip4);
14598     }
14599   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14600   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14601   vat_json_object_add_uint (node, "mcast_sw_if_index",
14602                             ntohl (mp->mcast_sw_if_index));
14603   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14604   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14605   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14606 }
14607
14608 static int
14609 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14610 {
14611   unformat_input_t *i = vam->input;
14612   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14613   vl_api_control_ping_t *mp_ping;
14614   u32 sw_if_index;
14615   u8 sw_if_index_set = 0;
14616   int ret;
14617
14618   /* Parse args required to build the message */
14619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14620     {
14621       if (unformat (i, "sw_if_index %d", &sw_if_index))
14622         sw_if_index_set = 1;
14623       else
14624         break;
14625     }
14626
14627   if (sw_if_index_set == 0)
14628     {
14629       sw_if_index = ~0;
14630     }
14631
14632   if (!vam->json_output)
14633     {
14634       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14635              "sw_if_index", "local", "remote", "vni",
14636              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14637     }
14638
14639   /* Get list of vxlan-tunnel interfaces */
14640   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14641
14642   mp->sw_if_index = htonl (sw_if_index);
14643
14644   S (mp);
14645
14646   /* Use a control ping for synchronization */
14647   MPING (CONTROL_PING, mp_ping);
14648   S (mp_ping);
14649
14650   W (ret);
14651   return ret;
14652 }
14653
14654 static void vl_api_l2_fib_table_details_t_handler
14655   (vl_api_l2_fib_table_details_t * mp)
14656 {
14657   vat_main_t *vam = &vat_main;
14658
14659   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14660          "       %d       %d     %d",
14661          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14662          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14663          mp->bvi_mac);
14664 }
14665
14666 static void vl_api_l2_fib_table_details_t_handler_json
14667   (vl_api_l2_fib_table_details_t * mp)
14668 {
14669   vat_main_t *vam = &vat_main;
14670   vat_json_node_t *node = NULL;
14671
14672   if (VAT_JSON_ARRAY != vam->json_tree.type)
14673     {
14674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14675       vat_json_init_array (&vam->json_tree);
14676     }
14677   node = vat_json_array_add (&vam->json_tree);
14678
14679   vat_json_init_object (node);
14680   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14681   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14682   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14683   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14684   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14685   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14686 }
14687
14688 static int
14689 api_l2_fib_table_dump (vat_main_t * vam)
14690 {
14691   unformat_input_t *i = vam->input;
14692   vl_api_l2_fib_table_dump_t *mp;
14693   vl_api_control_ping_t *mp_ping;
14694   u32 bd_id;
14695   u8 bd_id_set = 0;
14696   int ret;
14697
14698   /* Parse args required to build the message */
14699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14700     {
14701       if (unformat (i, "bd_id %d", &bd_id))
14702         bd_id_set = 1;
14703       else
14704         break;
14705     }
14706
14707   if (bd_id_set == 0)
14708     {
14709       errmsg ("missing bridge domain");
14710       return -99;
14711     }
14712
14713   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14714
14715   /* Get list of l2 fib entries */
14716   M (L2_FIB_TABLE_DUMP, mp);
14717
14718   mp->bd_id = ntohl (bd_id);
14719   S (mp);
14720
14721   /* Use a control ping for synchronization */
14722   MPING (CONTROL_PING, mp_ping);
14723   S (mp_ping);
14724
14725   W (ret);
14726   return ret;
14727 }
14728
14729
14730 static int
14731 api_interface_name_renumber (vat_main_t * vam)
14732 {
14733   unformat_input_t *line_input = vam->input;
14734   vl_api_interface_name_renumber_t *mp;
14735   u32 sw_if_index = ~0;
14736   u32 new_show_dev_instance = ~0;
14737   int ret;
14738
14739   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14740     {
14741       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14742                     &sw_if_index))
14743         ;
14744       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14745         ;
14746       else if (unformat (line_input, "new_show_dev_instance %d",
14747                          &new_show_dev_instance))
14748         ;
14749       else
14750         break;
14751     }
14752
14753   if (sw_if_index == ~0)
14754     {
14755       errmsg ("missing interface name or sw_if_index");
14756       return -99;
14757     }
14758
14759   if (new_show_dev_instance == ~0)
14760     {
14761       errmsg ("missing new_show_dev_instance");
14762       return -99;
14763     }
14764
14765   M (INTERFACE_NAME_RENUMBER, mp);
14766
14767   mp->sw_if_index = ntohl (sw_if_index);
14768   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14769
14770   S (mp);
14771   W (ret);
14772   return ret;
14773 }
14774
14775 static int
14776 api_ip_probe_neighbor (vat_main_t * vam)
14777 {
14778   unformat_input_t *i = vam->input;
14779   vl_api_ip_probe_neighbor_t *mp;
14780   u8 int_set = 0;
14781   u8 adr_set = 0;
14782   u8 is_ipv6 = 0;
14783   u8 dst_adr[16];
14784   u32 sw_if_index;
14785   int ret;
14786
14787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14788     {
14789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14790         int_set = 1;
14791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14792         int_set = 1;
14793       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14794         adr_set = 1;
14795       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14796         {
14797           adr_set = 1;
14798           is_ipv6 = 1;
14799         }
14800       else
14801         break;
14802     }
14803
14804   if (int_set == 0)
14805     {
14806       errmsg ("missing interface");
14807       return -99;
14808     }
14809
14810   if (adr_set == 0)
14811     {
14812       errmsg ("missing addresses");
14813       return -99;
14814     }
14815
14816   M (IP_PROBE_NEIGHBOR, mp);
14817
14818   mp->sw_if_index = ntohl (sw_if_index);
14819   mp->is_ipv6 = is_ipv6;
14820   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14821
14822   S (mp);
14823   W (ret);
14824   return ret;
14825 }
14826
14827 static int
14828 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14829 {
14830   unformat_input_t *i = vam->input;
14831   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14832   u8 mode = IP_SCAN_V46_NEIGHBORS;
14833   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14834   int ret;
14835
14836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14837     {
14838       if (unformat (i, "ip4"))
14839         mode = IP_SCAN_V4_NEIGHBORS;
14840       else if (unformat (i, "ip6"))
14841         mode = IP_SCAN_V6_NEIGHBORS;
14842       if (unformat (i, "both"))
14843         mode = IP_SCAN_V46_NEIGHBORS;
14844       else if (unformat (i, "disable"))
14845         mode = IP_SCAN_DISABLED;
14846       else if (unformat (i, "interval %d", &interval))
14847         ;
14848       else if (unformat (i, "max-time %d", &time))
14849         ;
14850       else if (unformat (i, "max-update %d", &update))
14851         ;
14852       else if (unformat (i, "delay %d", &delay))
14853         ;
14854       else if (unformat (i, "stale %d", &stale))
14855         ;
14856       else
14857         break;
14858     }
14859
14860   if (interval > 255)
14861     {
14862       errmsg ("interval cannot exceed 255 minutes.");
14863       return -99;
14864     }
14865   if (time > 255)
14866     {
14867       errmsg ("max-time cannot exceed 255 usec.");
14868       return -99;
14869     }
14870   if (update > 255)
14871     {
14872       errmsg ("max-update cannot exceed 255.");
14873       return -99;
14874     }
14875   if (delay > 255)
14876     {
14877       errmsg ("delay cannot exceed 255 msec.");
14878       return -99;
14879     }
14880   if (stale > 255)
14881     {
14882       errmsg ("stale cannot exceed 255 minutes.");
14883       return -99;
14884     }
14885
14886   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14887   mp->mode = mode;
14888   mp->scan_interval = interval;
14889   mp->max_proc_time = time;
14890   mp->max_update = update;
14891   mp->scan_int_delay = delay;
14892   mp->stale_threshold = stale;
14893
14894   S (mp);
14895   W (ret);
14896   return ret;
14897 }
14898
14899 static int
14900 api_want_ip4_arp_events (vat_main_t * vam)
14901 {
14902   unformat_input_t *line_input = vam->input;
14903   vl_api_want_ip4_arp_events_t *mp;
14904   ip4_address_t address;
14905   int address_set = 0;
14906   u32 enable_disable = 1;
14907   int ret;
14908
14909   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14910     {
14911       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14912         address_set = 1;
14913       else if (unformat (line_input, "del"))
14914         enable_disable = 0;
14915       else
14916         break;
14917     }
14918
14919   if (address_set == 0)
14920     {
14921       errmsg ("missing addresses");
14922       return -99;
14923     }
14924
14925   M (WANT_IP4_ARP_EVENTS, mp);
14926   mp->enable_disable = enable_disable;
14927   mp->pid = htonl (getpid ());
14928   mp->address = address.as_u32;
14929
14930   S (mp);
14931   W (ret);
14932   return ret;
14933 }
14934
14935 static int
14936 api_want_ip6_nd_events (vat_main_t * vam)
14937 {
14938   unformat_input_t *line_input = vam->input;
14939   vl_api_want_ip6_nd_events_t *mp;
14940   ip6_address_t address;
14941   int address_set = 0;
14942   u32 enable_disable = 1;
14943   int ret;
14944
14945   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14946     {
14947       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14948         address_set = 1;
14949       else if (unformat (line_input, "del"))
14950         enable_disable = 0;
14951       else
14952         break;
14953     }
14954
14955   if (address_set == 0)
14956     {
14957       errmsg ("missing addresses");
14958       return -99;
14959     }
14960
14961   M (WANT_IP6_ND_EVENTS, mp);
14962   mp->enable_disable = enable_disable;
14963   mp->pid = htonl (getpid ());
14964   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14965
14966   S (mp);
14967   W (ret);
14968   return ret;
14969 }
14970
14971 static int
14972 api_want_l2_macs_events (vat_main_t * vam)
14973 {
14974   unformat_input_t *line_input = vam->input;
14975   vl_api_want_l2_macs_events_t *mp;
14976   u8 enable_disable = 1;
14977   u32 scan_delay = 0;
14978   u32 max_macs_in_event = 0;
14979   u32 learn_limit = 0;
14980   int ret;
14981
14982   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14983     {
14984       if (unformat (line_input, "learn-limit %d", &learn_limit))
14985         ;
14986       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14987         ;
14988       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14989         ;
14990       else if (unformat (line_input, "disable"))
14991         enable_disable = 0;
14992       else
14993         break;
14994     }
14995
14996   M (WANT_L2_MACS_EVENTS, mp);
14997   mp->enable_disable = enable_disable;
14998   mp->pid = htonl (getpid ());
14999   mp->learn_limit = htonl (learn_limit);
15000   mp->scan_delay = (u8) scan_delay;
15001   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15002   S (mp);
15003   W (ret);
15004   return ret;
15005 }
15006
15007 static int
15008 api_input_acl_set_interface (vat_main_t * vam)
15009 {
15010   unformat_input_t *i = vam->input;
15011   vl_api_input_acl_set_interface_t *mp;
15012   u32 sw_if_index;
15013   int sw_if_index_set;
15014   u32 ip4_table_index = ~0;
15015   u32 ip6_table_index = ~0;
15016   u32 l2_table_index = ~0;
15017   u8 is_add = 1;
15018   int ret;
15019
15020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15021     {
15022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15023         sw_if_index_set = 1;
15024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15025         sw_if_index_set = 1;
15026       else if (unformat (i, "del"))
15027         is_add = 0;
15028       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15029         ;
15030       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15031         ;
15032       else if (unformat (i, "l2-table %d", &l2_table_index))
15033         ;
15034       else
15035         {
15036           clib_warning ("parse error '%U'", format_unformat_error, i);
15037           return -99;
15038         }
15039     }
15040
15041   if (sw_if_index_set == 0)
15042     {
15043       errmsg ("missing interface name or sw_if_index");
15044       return -99;
15045     }
15046
15047   M (INPUT_ACL_SET_INTERFACE, mp);
15048
15049   mp->sw_if_index = ntohl (sw_if_index);
15050   mp->ip4_table_index = ntohl (ip4_table_index);
15051   mp->ip6_table_index = ntohl (ip6_table_index);
15052   mp->l2_table_index = ntohl (l2_table_index);
15053   mp->is_add = is_add;
15054
15055   S (mp);
15056   W (ret);
15057   return ret;
15058 }
15059
15060 static int
15061 api_output_acl_set_interface (vat_main_t * vam)
15062 {
15063   unformat_input_t *i = vam->input;
15064   vl_api_output_acl_set_interface_t *mp;
15065   u32 sw_if_index;
15066   int sw_if_index_set;
15067   u32 ip4_table_index = ~0;
15068   u32 ip6_table_index = ~0;
15069   u32 l2_table_index = ~0;
15070   u8 is_add = 1;
15071   int ret;
15072
15073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15074     {
15075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15076         sw_if_index_set = 1;
15077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15078         sw_if_index_set = 1;
15079       else if (unformat (i, "del"))
15080         is_add = 0;
15081       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15082         ;
15083       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15084         ;
15085       else if (unformat (i, "l2-table %d", &l2_table_index))
15086         ;
15087       else
15088         {
15089           clib_warning ("parse error '%U'", format_unformat_error, i);
15090           return -99;
15091         }
15092     }
15093
15094   if (sw_if_index_set == 0)
15095     {
15096       errmsg ("missing interface name or sw_if_index");
15097       return -99;
15098     }
15099
15100   M (OUTPUT_ACL_SET_INTERFACE, mp);
15101
15102   mp->sw_if_index = ntohl (sw_if_index);
15103   mp->ip4_table_index = ntohl (ip4_table_index);
15104   mp->ip6_table_index = ntohl (ip6_table_index);
15105   mp->l2_table_index = ntohl (l2_table_index);
15106   mp->is_add = is_add;
15107
15108   S (mp);
15109   W (ret);
15110   return ret;
15111 }
15112
15113 static int
15114 api_ip_address_dump (vat_main_t * vam)
15115 {
15116   unformat_input_t *i = vam->input;
15117   vl_api_ip_address_dump_t *mp;
15118   vl_api_control_ping_t *mp_ping;
15119   u32 sw_if_index = ~0;
15120   u8 sw_if_index_set = 0;
15121   u8 ipv4_set = 0;
15122   u8 ipv6_set = 0;
15123   int ret;
15124
15125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15126     {
15127       if (unformat (i, "sw_if_index %d", &sw_if_index))
15128         sw_if_index_set = 1;
15129       else
15130         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15131         sw_if_index_set = 1;
15132       else if (unformat (i, "ipv4"))
15133         ipv4_set = 1;
15134       else if (unformat (i, "ipv6"))
15135         ipv6_set = 1;
15136       else
15137         break;
15138     }
15139
15140   if (ipv4_set && ipv6_set)
15141     {
15142       errmsg ("ipv4 and ipv6 flags cannot be both set");
15143       return -99;
15144     }
15145
15146   if ((!ipv4_set) && (!ipv6_set))
15147     {
15148       errmsg ("no ipv4 nor ipv6 flag set");
15149       return -99;
15150     }
15151
15152   if (sw_if_index_set == 0)
15153     {
15154       errmsg ("missing interface name or sw_if_index");
15155       return -99;
15156     }
15157
15158   vam->current_sw_if_index = sw_if_index;
15159   vam->is_ipv6 = ipv6_set;
15160
15161   M (IP_ADDRESS_DUMP, mp);
15162   mp->sw_if_index = ntohl (sw_if_index);
15163   mp->is_ipv6 = ipv6_set;
15164   S (mp);
15165
15166   /* Use a control ping for synchronization */
15167   MPING (CONTROL_PING, mp_ping);
15168   S (mp_ping);
15169
15170   W (ret);
15171   return ret;
15172 }
15173
15174 static int
15175 api_ip_dump (vat_main_t * vam)
15176 {
15177   vl_api_ip_dump_t *mp;
15178   vl_api_control_ping_t *mp_ping;
15179   unformat_input_t *in = vam->input;
15180   int ipv4_set = 0;
15181   int ipv6_set = 0;
15182   int is_ipv6;
15183   int i;
15184   int ret;
15185
15186   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15187     {
15188       if (unformat (in, "ipv4"))
15189         ipv4_set = 1;
15190       else if (unformat (in, "ipv6"))
15191         ipv6_set = 1;
15192       else
15193         break;
15194     }
15195
15196   if (ipv4_set && ipv6_set)
15197     {
15198       errmsg ("ipv4 and ipv6 flags cannot be both set");
15199       return -99;
15200     }
15201
15202   if ((!ipv4_set) && (!ipv6_set))
15203     {
15204       errmsg ("no ipv4 nor ipv6 flag set");
15205       return -99;
15206     }
15207
15208   is_ipv6 = ipv6_set;
15209   vam->is_ipv6 = is_ipv6;
15210
15211   /* free old data */
15212   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15213     {
15214       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15215     }
15216   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15217
15218   M (IP_DUMP, mp);
15219   mp->is_ipv6 = ipv6_set;
15220   S (mp);
15221
15222   /* Use a control ping for synchronization */
15223   MPING (CONTROL_PING, mp_ping);
15224   S (mp_ping);
15225
15226   W (ret);
15227   return ret;
15228 }
15229
15230 static int
15231 api_ipsec_spd_add_del (vat_main_t * vam)
15232 {
15233   unformat_input_t *i = vam->input;
15234   vl_api_ipsec_spd_add_del_t *mp;
15235   u32 spd_id = ~0;
15236   u8 is_add = 1;
15237   int ret;
15238
15239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (i, "spd_id %d", &spd_id))
15242         ;
15243       else if (unformat (i, "del"))
15244         is_add = 0;
15245       else
15246         {
15247           clib_warning ("parse error '%U'", format_unformat_error, i);
15248           return -99;
15249         }
15250     }
15251   if (spd_id == ~0)
15252     {
15253       errmsg ("spd_id must be set");
15254       return -99;
15255     }
15256
15257   M (IPSEC_SPD_ADD_DEL, mp);
15258
15259   mp->spd_id = ntohl (spd_id);
15260   mp->is_add = is_add;
15261
15262   S (mp);
15263   W (ret);
15264   return ret;
15265 }
15266
15267 static int
15268 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15269 {
15270   unformat_input_t *i = vam->input;
15271   vl_api_ipsec_interface_add_del_spd_t *mp;
15272   u32 sw_if_index;
15273   u8 sw_if_index_set = 0;
15274   u32 spd_id = (u32) ~ 0;
15275   u8 is_add = 1;
15276   int ret;
15277
15278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15279     {
15280       if (unformat (i, "del"))
15281         is_add = 0;
15282       else if (unformat (i, "spd_id %d", &spd_id))
15283         ;
15284       else
15285         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15286         sw_if_index_set = 1;
15287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15288         sw_if_index_set = 1;
15289       else
15290         {
15291           clib_warning ("parse error '%U'", format_unformat_error, i);
15292           return -99;
15293         }
15294
15295     }
15296
15297   if (spd_id == (u32) ~ 0)
15298     {
15299       errmsg ("spd_id must be set");
15300       return -99;
15301     }
15302
15303   if (sw_if_index_set == 0)
15304     {
15305       errmsg ("missing interface name or sw_if_index");
15306       return -99;
15307     }
15308
15309   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15310
15311   mp->spd_id = ntohl (spd_id);
15312   mp->sw_if_index = ntohl (sw_if_index);
15313   mp->is_add = is_add;
15314
15315   S (mp);
15316   W (ret);
15317   return ret;
15318 }
15319
15320 static int
15321 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15322 {
15323   unformat_input_t *i = vam->input;
15324   vl_api_ipsec_spd_add_del_entry_t *mp;
15325   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15326   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15327   i32 priority = 0;
15328   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15329   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15330   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15331   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15332   int ret;
15333
15334   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15335   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15336   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15337   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15338   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15339   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15340
15341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15342     {
15343       if (unformat (i, "del"))
15344         is_add = 0;
15345       if (unformat (i, "outbound"))
15346         is_outbound = 1;
15347       if (unformat (i, "inbound"))
15348         is_outbound = 0;
15349       else if (unformat (i, "spd_id %d", &spd_id))
15350         ;
15351       else if (unformat (i, "sa_id %d", &sa_id))
15352         ;
15353       else if (unformat (i, "priority %d", &priority))
15354         ;
15355       else if (unformat (i, "protocol %d", &protocol))
15356         ;
15357       else if (unformat (i, "lport_start %d", &lport_start))
15358         ;
15359       else if (unformat (i, "lport_stop %d", &lport_stop))
15360         ;
15361       else if (unformat (i, "rport_start %d", &rport_start))
15362         ;
15363       else if (unformat (i, "rport_stop %d", &rport_stop))
15364         ;
15365       else
15366         if (unformat
15367             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15368         {
15369           is_ipv6 = 0;
15370           is_ip_any = 0;
15371         }
15372       else
15373         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15374         {
15375           is_ipv6 = 0;
15376           is_ip_any = 0;
15377         }
15378       else
15379         if (unformat
15380             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15381         {
15382           is_ipv6 = 0;
15383           is_ip_any = 0;
15384         }
15385       else
15386         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15387         {
15388           is_ipv6 = 0;
15389           is_ip_any = 0;
15390         }
15391       else
15392         if (unformat
15393             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15394         {
15395           is_ipv6 = 1;
15396           is_ip_any = 0;
15397         }
15398       else
15399         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15400         {
15401           is_ipv6 = 1;
15402           is_ip_any = 0;
15403         }
15404       else
15405         if (unformat
15406             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15407         {
15408           is_ipv6 = 1;
15409           is_ip_any = 0;
15410         }
15411       else
15412         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15413         {
15414           is_ipv6 = 1;
15415           is_ip_any = 0;
15416         }
15417       else
15418         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15419         {
15420           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15421             {
15422               clib_warning ("unsupported action: 'resolve'");
15423               return -99;
15424             }
15425         }
15426       else
15427         {
15428           clib_warning ("parse error '%U'", format_unformat_error, i);
15429           return -99;
15430         }
15431
15432     }
15433
15434   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15435
15436   mp->spd_id = ntohl (spd_id);
15437   mp->priority = ntohl (priority);
15438   mp->is_outbound = is_outbound;
15439
15440   mp->is_ipv6 = is_ipv6;
15441   if (is_ipv6 || is_ip_any)
15442     {
15443       clib_memcpy (mp->remote_address_start, &raddr6_start,
15444                    sizeof (ip6_address_t));
15445       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15446                    sizeof (ip6_address_t));
15447       clib_memcpy (mp->local_address_start, &laddr6_start,
15448                    sizeof (ip6_address_t));
15449       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15450                    sizeof (ip6_address_t));
15451     }
15452   else
15453     {
15454       clib_memcpy (mp->remote_address_start, &raddr4_start,
15455                    sizeof (ip4_address_t));
15456       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15457                    sizeof (ip4_address_t));
15458       clib_memcpy (mp->local_address_start, &laddr4_start,
15459                    sizeof (ip4_address_t));
15460       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15461                    sizeof (ip4_address_t));
15462     }
15463   mp->protocol = (u8) protocol;
15464   mp->local_port_start = ntohs ((u16) lport_start);
15465   mp->local_port_stop = ntohs ((u16) lport_stop);
15466   mp->remote_port_start = ntohs ((u16) rport_start);
15467   mp->remote_port_stop = ntohs ((u16) rport_stop);
15468   mp->policy = (u8) policy;
15469   mp->sa_id = ntohl (sa_id);
15470   mp->is_add = is_add;
15471   mp->is_ip_any = is_ip_any;
15472   S (mp);
15473   W (ret);
15474   return ret;
15475 }
15476
15477 static int
15478 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15479 {
15480   unformat_input_t *i = vam->input;
15481   vl_api_ipsec_sad_add_del_entry_t *mp;
15482   u32 sad_id = 0, spi = 0;
15483   u8 *ck = 0, *ik = 0;
15484   u8 is_add = 1;
15485
15486   u8 protocol = IPSEC_PROTOCOL_AH;
15487   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15488   u32 crypto_alg = 0, integ_alg = 0;
15489   ip4_address_t tun_src4;
15490   ip4_address_t tun_dst4;
15491   ip6_address_t tun_src6;
15492   ip6_address_t tun_dst6;
15493   int ret;
15494
15495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15496     {
15497       if (unformat (i, "del"))
15498         is_add = 0;
15499       else if (unformat (i, "sad_id %d", &sad_id))
15500         ;
15501       else if (unformat (i, "spi %d", &spi))
15502         ;
15503       else if (unformat (i, "esp"))
15504         protocol = IPSEC_PROTOCOL_ESP;
15505       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15506         {
15507           is_tunnel = 1;
15508           is_tunnel_ipv6 = 0;
15509         }
15510       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15511         {
15512           is_tunnel = 1;
15513           is_tunnel_ipv6 = 0;
15514         }
15515       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15516         {
15517           is_tunnel = 1;
15518           is_tunnel_ipv6 = 1;
15519         }
15520       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15521         {
15522           is_tunnel = 1;
15523           is_tunnel_ipv6 = 1;
15524         }
15525       else
15526         if (unformat
15527             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15528         {
15529           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15530             {
15531               clib_warning ("unsupported crypto-alg: '%U'",
15532                             format_ipsec_crypto_alg, crypto_alg);
15533               return -99;
15534             }
15535         }
15536       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15537         ;
15538       else
15539         if (unformat
15540             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15541         {
15542           if (integ_alg >= IPSEC_INTEG_N_ALG)
15543             {
15544               clib_warning ("unsupported integ-alg: '%U'",
15545                             format_ipsec_integ_alg, integ_alg);
15546               return -99;
15547             }
15548         }
15549       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15550         ;
15551       else
15552         {
15553           clib_warning ("parse error '%U'", format_unformat_error, i);
15554           return -99;
15555         }
15556
15557     }
15558
15559   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15560
15561   mp->sad_id = ntohl (sad_id);
15562   mp->is_add = is_add;
15563   mp->protocol = protocol;
15564   mp->spi = ntohl (spi);
15565   mp->is_tunnel = is_tunnel;
15566   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15567   mp->crypto_algorithm = crypto_alg;
15568   mp->integrity_algorithm = integ_alg;
15569   mp->crypto_key_length = vec_len (ck);
15570   mp->integrity_key_length = vec_len (ik);
15571
15572   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15573     mp->crypto_key_length = sizeof (mp->crypto_key);
15574
15575   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15576     mp->integrity_key_length = sizeof (mp->integrity_key);
15577
15578   if (ck)
15579     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15580   if (ik)
15581     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15582
15583   if (is_tunnel)
15584     {
15585       if (is_tunnel_ipv6)
15586         {
15587           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15588                        sizeof (ip6_address_t));
15589           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15590                        sizeof (ip6_address_t));
15591         }
15592       else
15593         {
15594           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15595                        sizeof (ip4_address_t));
15596           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15597                        sizeof (ip4_address_t));
15598         }
15599     }
15600
15601   S (mp);
15602   W (ret);
15603   return ret;
15604 }
15605
15606 static int
15607 api_ipsec_sa_set_key (vat_main_t * vam)
15608 {
15609   unformat_input_t *i = vam->input;
15610   vl_api_ipsec_sa_set_key_t *mp;
15611   u32 sa_id;
15612   u8 *ck = 0, *ik = 0;
15613   int ret;
15614
15615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15616     {
15617       if (unformat (i, "sa_id %d", &sa_id))
15618         ;
15619       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15620         ;
15621       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15622         ;
15623       else
15624         {
15625           clib_warning ("parse error '%U'", format_unformat_error, i);
15626           return -99;
15627         }
15628     }
15629
15630   M (IPSEC_SA_SET_KEY, mp);
15631
15632   mp->sa_id = ntohl (sa_id);
15633   mp->crypto_key_length = vec_len (ck);
15634   mp->integrity_key_length = vec_len (ik);
15635
15636   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15637     mp->crypto_key_length = sizeof (mp->crypto_key);
15638
15639   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15640     mp->integrity_key_length = sizeof (mp->integrity_key);
15641
15642   if (ck)
15643     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15644   if (ik)
15645     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15646
15647   S (mp);
15648   W (ret);
15649   return ret;
15650 }
15651
15652 static int
15653 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15654 {
15655   unformat_input_t *i = vam->input;
15656   vl_api_ipsec_tunnel_if_add_del_t *mp;
15657   u32 local_spi = 0, remote_spi = 0;
15658   u32 crypto_alg = 0, integ_alg = 0;
15659   u8 *lck = NULL, *rck = NULL;
15660   u8 *lik = NULL, *rik = NULL;
15661   ip4_address_t local_ip = { {0} };
15662   ip4_address_t remote_ip = { {0} };
15663   u8 is_add = 1;
15664   u8 esn = 0;
15665   u8 anti_replay = 0;
15666   u8 renumber = 0;
15667   u32 instance = ~0;
15668   int ret;
15669
15670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15671     {
15672       if (unformat (i, "del"))
15673         is_add = 0;
15674       else if (unformat (i, "esn"))
15675         esn = 1;
15676       else if (unformat (i, "anti_replay"))
15677         anti_replay = 1;
15678       else if (unformat (i, "local_spi %d", &local_spi))
15679         ;
15680       else if (unformat (i, "remote_spi %d", &remote_spi))
15681         ;
15682       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15683         ;
15684       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15685         ;
15686       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15687         ;
15688       else
15689         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15690         ;
15691       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15692         ;
15693       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15694         ;
15695       else
15696         if (unformat
15697             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15698         {
15699           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15700             {
15701               errmsg ("unsupported crypto-alg: '%U'\n",
15702                       format_ipsec_crypto_alg, crypto_alg);
15703               return -99;
15704             }
15705         }
15706       else
15707         if (unformat
15708             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15709         {
15710           if (integ_alg >= IPSEC_INTEG_N_ALG)
15711             {
15712               errmsg ("unsupported integ-alg: '%U'\n",
15713                       format_ipsec_integ_alg, integ_alg);
15714               return -99;
15715             }
15716         }
15717       else if (unformat (i, "instance %u", &instance))
15718         renumber = 1;
15719       else
15720         {
15721           errmsg ("parse error '%U'\n", format_unformat_error, i);
15722           return -99;
15723         }
15724     }
15725
15726   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15727
15728   mp->is_add = is_add;
15729   mp->esn = esn;
15730   mp->anti_replay = anti_replay;
15731
15732   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15733   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15734
15735   mp->local_spi = htonl (local_spi);
15736   mp->remote_spi = htonl (remote_spi);
15737   mp->crypto_alg = (u8) crypto_alg;
15738
15739   mp->local_crypto_key_len = 0;
15740   if (lck)
15741     {
15742       mp->local_crypto_key_len = vec_len (lck);
15743       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15744         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15745       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15746     }
15747
15748   mp->remote_crypto_key_len = 0;
15749   if (rck)
15750     {
15751       mp->remote_crypto_key_len = vec_len (rck);
15752       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15753         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15754       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15755     }
15756
15757   mp->integ_alg = (u8) integ_alg;
15758
15759   mp->local_integ_key_len = 0;
15760   if (lik)
15761     {
15762       mp->local_integ_key_len = vec_len (lik);
15763       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15764         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15765       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15766     }
15767
15768   mp->remote_integ_key_len = 0;
15769   if (rik)
15770     {
15771       mp->remote_integ_key_len = vec_len (rik);
15772       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15773         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15774       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15775     }
15776
15777   if (renumber)
15778     {
15779       mp->renumber = renumber;
15780       mp->show_instance = ntohl (instance);
15781     }
15782
15783   S (mp);
15784   W (ret);
15785   return ret;
15786 }
15787
15788 static void
15789 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15790 {
15791   vat_main_t *vam = &vat_main;
15792
15793   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15794          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15795          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15796          "tunnel_src_addr %U tunnel_dst_addr %U "
15797          "salt %u seq_outbound %lu last_seq_inbound %lu "
15798          "replay_window %lu total_data_size %lu\n",
15799          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15800          mp->protocol,
15801          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15802          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15803          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15804          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15805          mp->tunnel_src_addr,
15806          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15807          mp->tunnel_dst_addr,
15808          ntohl (mp->salt),
15809          clib_net_to_host_u64 (mp->seq_outbound),
15810          clib_net_to_host_u64 (mp->last_seq_inbound),
15811          clib_net_to_host_u64 (mp->replay_window),
15812          clib_net_to_host_u64 (mp->total_data_size));
15813 }
15814
15815 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15816 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15817
15818 static void vl_api_ipsec_sa_details_t_handler_json
15819   (vl_api_ipsec_sa_details_t * mp)
15820 {
15821   vat_main_t *vam = &vat_main;
15822   vat_json_node_t *node = NULL;
15823   struct in_addr src_ip4, dst_ip4;
15824   struct in6_addr src_ip6, dst_ip6;
15825
15826   if (VAT_JSON_ARRAY != vam->json_tree.type)
15827     {
15828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15829       vat_json_init_array (&vam->json_tree);
15830     }
15831   node = vat_json_array_add (&vam->json_tree);
15832
15833   vat_json_init_object (node);
15834   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15836   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15837   vat_json_object_add_uint (node, "proto", mp->protocol);
15838   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15839   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15840   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15841   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15842   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15843   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15844   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15845                              mp->crypto_key_len);
15846   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15847                              mp->integ_key_len);
15848   if (mp->is_tunnel_ip6)
15849     {
15850       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15851       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15852       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15853       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15854     }
15855   else
15856     {
15857       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15858       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15859       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15860       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15861     }
15862   vat_json_object_add_uint (node, "replay_window",
15863                             clib_net_to_host_u64 (mp->replay_window));
15864   vat_json_object_add_uint (node, "total_data_size",
15865                             clib_net_to_host_u64 (mp->total_data_size));
15866
15867 }
15868
15869 static int
15870 api_ipsec_sa_dump (vat_main_t * vam)
15871 {
15872   unformat_input_t *i = vam->input;
15873   vl_api_ipsec_sa_dump_t *mp;
15874   vl_api_control_ping_t *mp_ping;
15875   u32 sa_id = ~0;
15876   int ret;
15877
15878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15879     {
15880       if (unformat (i, "sa_id %d", &sa_id))
15881         ;
15882       else
15883         {
15884           clib_warning ("parse error '%U'", format_unformat_error, i);
15885           return -99;
15886         }
15887     }
15888
15889   M (IPSEC_SA_DUMP, mp);
15890
15891   mp->sa_id = ntohl (sa_id);
15892
15893   S (mp);
15894
15895   /* Use a control ping for synchronization */
15896   M (CONTROL_PING, mp_ping);
15897   S (mp_ping);
15898
15899   W (ret);
15900   return ret;
15901 }
15902
15903 static int
15904 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15905 {
15906   unformat_input_t *i = vam->input;
15907   vl_api_ipsec_tunnel_if_set_key_t *mp;
15908   u32 sw_if_index = ~0;
15909   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15910   u8 *key = 0;
15911   u32 alg = ~0;
15912   int ret;
15913
15914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15915     {
15916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15917         ;
15918       else
15919         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15920         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15921       else
15922         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15923         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15924       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15925         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15926       else
15927         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15928         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15929       else if (unformat (i, "%U", unformat_hex_string, &key))
15930         ;
15931       else
15932         {
15933           clib_warning ("parse error '%U'", format_unformat_error, i);
15934           return -99;
15935         }
15936     }
15937
15938   if (sw_if_index == ~0)
15939     {
15940       errmsg ("interface must be specified");
15941       return -99;
15942     }
15943
15944   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15945     {
15946       errmsg ("key type must be specified");
15947       return -99;
15948     }
15949
15950   if (alg == ~0)
15951     {
15952       errmsg ("algorithm must be specified");
15953       return -99;
15954     }
15955
15956   if (vec_len (key) == 0)
15957     {
15958       errmsg ("key must be specified");
15959       return -99;
15960     }
15961
15962   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15963
15964   mp->sw_if_index = htonl (sw_if_index);
15965   mp->alg = alg;
15966   mp->key_type = key_type;
15967   mp->key_len = vec_len (key);
15968   clib_memcpy (mp->key, key, vec_len (key));
15969
15970   S (mp);
15971   W (ret);
15972
15973   return ret;
15974 }
15975
15976 static int
15977 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15978 {
15979   unformat_input_t *i = vam->input;
15980   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15981   u32 sw_if_index = ~0;
15982   u32 sa_id = ~0;
15983   u8 is_outbound = (u8) ~ 0;
15984   int ret;
15985
15986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15987     {
15988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15989         ;
15990       else if (unformat (i, "sa_id %d", &sa_id))
15991         ;
15992       else if (unformat (i, "outbound"))
15993         is_outbound = 1;
15994       else if (unformat (i, "inbound"))
15995         is_outbound = 0;
15996       else
15997         {
15998           clib_warning ("parse error '%U'", format_unformat_error, i);
15999           return -99;
16000         }
16001     }
16002
16003   if (sw_if_index == ~0)
16004     {
16005       errmsg ("interface must be specified");
16006       return -99;
16007     }
16008
16009   if (sa_id == ~0)
16010     {
16011       errmsg ("SA ID must be specified");
16012       return -99;
16013     }
16014
16015   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16016
16017   mp->sw_if_index = htonl (sw_if_index);
16018   mp->sa_id = htonl (sa_id);
16019   mp->is_outbound = is_outbound;
16020
16021   S (mp);
16022   W (ret);
16023
16024   return ret;
16025 }
16026
16027 static int
16028 api_ikev2_profile_add_del (vat_main_t * vam)
16029 {
16030   unformat_input_t *i = vam->input;
16031   vl_api_ikev2_profile_add_del_t *mp;
16032   u8 is_add = 1;
16033   u8 *name = 0;
16034   int ret;
16035
16036   const char *valid_chars = "a-zA-Z0-9_";
16037
16038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16039     {
16040       if (unformat (i, "del"))
16041         is_add = 0;
16042       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16043         vec_add1 (name, 0);
16044       else
16045         {
16046           errmsg ("parse error '%U'", format_unformat_error, i);
16047           return -99;
16048         }
16049     }
16050
16051   if (!vec_len (name))
16052     {
16053       errmsg ("profile name must be specified");
16054       return -99;
16055     }
16056
16057   if (vec_len (name) > 64)
16058     {
16059       errmsg ("profile name too long");
16060       return -99;
16061     }
16062
16063   M (IKEV2_PROFILE_ADD_DEL, mp);
16064
16065   clib_memcpy (mp->name, name, vec_len (name));
16066   mp->is_add = is_add;
16067   vec_free (name);
16068
16069   S (mp);
16070   W (ret);
16071   return ret;
16072 }
16073
16074 static int
16075 api_ikev2_profile_set_auth (vat_main_t * vam)
16076 {
16077   unformat_input_t *i = vam->input;
16078   vl_api_ikev2_profile_set_auth_t *mp;
16079   u8 *name = 0;
16080   u8 *data = 0;
16081   u32 auth_method = 0;
16082   u8 is_hex = 0;
16083   int ret;
16084
16085   const char *valid_chars = "a-zA-Z0-9_";
16086
16087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16090         vec_add1 (name, 0);
16091       else if (unformat (i, "auth_method %U",
16092                          unformat_ikev2_auth_method, &auth_method))
16093         ;
16094       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16095         is_hex = 1;
16096       else if (unformat (i, "auth_data %v", &data))
16097         ;
16098       else
16099         {
16100           errmsg ("parse error '%U'", format_unformat_error, i);
16101           return -99;
16102         }
16103     }
16104
16105   if (!vec_len (name))
16106     {
16107       errmsg ("profile name must be specified");
16108       return -99;
16109     }
16110
16111   if (vec_len (name) > 64)
16112     {
16113       errmsg ("profile name too long");
16114       return -99;
16115     }
16116
16117   if (!vec_len (data))
16118     {
16119       errmsg ("auth_data must be specified");
16120       return -99;
16121     }
16122
16123   if (!auth_method)
16124     {
16125       errmsg ("auth_method must be specified");
16126       return -99;
16127     }
16128
16129   M (IKEV2_PROFILE_SET_AUTH, mp);
16130
16131   mp->is_hex = is_hex;
16132   mp->auth_method = (u8) auth_method;
16133   mp->data_len = vec_len (data);
16134   clib_memcpy (mp->name, name, vec_len (name));
16135   clib_memcpy (mp->data, data, vec_len (data));
16136   vec_free (name);
16137   vec_free (data);
16138
16139   S (mp);
16140   W (ret);
16141   return ret;
16142 }
16143
16144 static int
16145 api_ikev2_profile_set_id (vat_main_t * vam)
16146 {
16147   unformat_input_t *i = vam->input;
16148   vl_api_ikev2_profile_set_id_t *mp;
16149   u8 *name = 0;
16150   u8 *data = 0;
16151   u8 is_local = 0;
16152   u32 id_type = 0;
16153   ip4_address_t ip4;
16154   int ret;
16155
16156   const char *valid_chars = "a-zA-Z0-9_";
16157
16158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16159     {
16160       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16161         vec_add1 (name, 0);
16162       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16163         ;
16164       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16165         {
16166           data = vec_new (u8, 4);
16167           clib_memcpy (data, ip4.as_u8, 4);
16168         }
16169       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16170         ;
16171       else if (unformat (i, "id_data %v", &data))
16172         ;
16173       else if (unformat (i, "local"))
16174         is_local = 1;
16175       else if (unformat (i, "remote"))
16176         is_local = 0;
16177       else
16178         {
16179           errmsg ("parse error '%U'", format_unformat_error, i);
16180           return -99;
16181         }
16182     }
16183
16184   if (!vec_len (name))
16185     {
16186       errmsg ("profile name must be specified");
16187       return -99;
16188     }
16189
16190   if (vec_len (name) > 64)
16191     {
16192       errmsg ("profile name too long");
16193       return -99;
16194     }
16195
16196   if (!vec_len (data))
16197     {
16198       errmsg ("id_data must be specified");
16199       return -99;
16200     }
16201
16202   if (!id_type)
16203     {
16204       errmsg ("id_type must be specified");
16205       return -99;
16206     }
16207
16208   M (IKEV2_PROFILE_SET_ID, mp);
16209
16210   mp->is_local = is_local;
16211   mp->id_type = (u8) id_type;
16212   mp->data_len = vec_len (data);
16213   clib_memcpy (mp->name, name, vec_len (name));
16214   clib_memcpy (mp->data, data, vec_len (data));
16215   vec_free (name);
16216   vec_free (data);
16217
16218   S (mp);
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_ikev2_profile_set_ts (vat_main_t * vam)
16225 {
16226   unformat_input_t *i = vam->input;
16227   vl_api_ikev2_profile_set_ts_t *mp;
16228   u8 *name = 0;
16229   u8 is_local = 0;
16230   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16231   ip4_address_t start_addr, end_addr;
16232
16233   const char *valid_chars = "a-zA-Z0-9_";
16234   int ret;
16235
16236   start_addr.as_u32 = 0;
16237   end_addr.as_u32 = (u32) ~ 0;
16238
16239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16240     {
16241       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16242         vec_add1 (name, 0);
16243       else if (unformat (i, "protocol %d", &proto))
16244         ;
16245       else if (unformat (i, "start_port %d", &start_port))
16246         ;
16247       else if (unformat (i, "end_port %d", &end_port))
16248         ;
16249       else
16250         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16251         ;
16252       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16253         ;
16254       else if (unformat (i, "local"))
16255         is_local = 1;
16256       else if (unformat (i, "remote"))
16257         is_local = 0;
16258       else
16259         {
16260           errmsg ("parse error '%U'", format_unformat_error, i);
16261           return -99;
16262         }
16263     }
16264
16265   if (!vec_len (name))
16266     {
16267       errmsg ("profile name must be specified");
16268       return -99;
16269     }
16270
16271   if (vec_len (name) > 64)
16272     {
16273       errmsg ("profile name too long");
16274       return -99;
16275     }
16276
16277   M (IKEV2_PROFILE_SET_TS, mp);
16278
16279   mp->is_local = is_local;
16280   mp->proto = (u8) proto;
16281   mp->start_port = (u16) start_port;
16282   mp->end_port = (u16) end_port;
16283   mp->start_addr = start_addr.as_u32;
16284   mp->end_addr = end_addr.as_u32;
16285   clib_memcpy (mp->name, name, vec_len (name));
16286   vec_free (name);
16287
16288   S (mp);
16289   W (ret);
16290   return ret;
16291 }
16292
16293 static int
16294 api_ikev2_set_local_key (vat_main_t * vam)
16295 {
16296   unformat_input_t *i = vam->input;
16297   vl_api_ikev2_set_local_key_t *mp;
16298   u8 *file = 0;
16299   int ret;
16300
16301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16302     {
16303       if (unformat (i, "file %v", &file))
16304         vec_add1 (file, 0);
16305       else
16306         {
16307           errmsg ("parse error '%U'", format_unformat_error, i);
16308           return -99;
16309         }
16310     }
16311
16312   if (!vec_len (file))
16313     {
16314       errmsg ("RSA key file must be specified");
16315       return -99;
16316     }
16317
16318   if (vec_len (file) > 256)
16319     {
16320       errmsg ("file name too long");
16321       return -99;
16322     }
16323
16324   M (IKEV2_SET_LOCAL_KEY, mp);
16325
16326   clib_memcpy (mp->key_file, file, vec_len (file));
16327   vec_free (file);
16328
16329   S (mp);
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_ikev2_set_responder (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_ikev2_set_responder_t *mp;
16339   int ret;
16340   u8 *name = 0;
16341   u32 sw_if_index = ~0;
16342   ip4_address_t address;
16343
16344   const char *valid_chars = "a-zA-Z0-9_";
16345
16346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16347     {
16348       if (unformat
16349           (i, "%U interface %d address %U", unformat_token, valid_chars,
16350            &name, &sw_if_index, unformat_ip4_address, &address))
16351         vec_add1 (name, 0);
16352       else
16353         {
16354           errmsg ("parse error '%U'", format_unformat_error, i);
16355           return -99;
16356         }
16357     }
16358
16359   if (!vec_len (name))
16360     {
16361       errmsg ("profile name must be specified");
16362       return -99;
16363     }
16364
16365   if (vec_len (name) > 64)
16366     {
16367       errmsg ("profile name too long");
16368       return -99;
16369     }
16370
16371   M (IKEV2_SET_RESPONDER, mp);
16372
16373   clib_memcpy (mp->name, name, vec_len (name));
16374   vec_free (name);
16375
16376   mp->sw_if_index = sw_if_index;
16377   clib_memcpy (mp->address, &address, sizeof (address));
16378
16379   S (mp);
16380   W (ret);
16381   return ret;
16382 }
16383
16384 static int
16385 api_ikev2_set_ike_transforms (vat_main_t * vam)
16386 {
16387   unformat_input_t *i = vam->input;
16388   vl_api_ikev2_set_ike_transforms_t *mp;
16389   int ret;
16390   u8 *name = 0;
16391   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16392
16393   const char *valid_chars = "a-zA-Z0-9_";
16394
16395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16396     {
16397       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16398                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16399         vec_add1 (name, 0);
16400       else
16401         {
16402           errmsg ("parse error '%U'", format_unformat_error, i);
16403           return -99;
16404         }
16405     }
16406
16407   if (!vec_len (name))
16408     {
16409       errmsg ("profile name must be specified");
16410       return -99;
16411     }
16412
16413   if (vec_len (name) > 64)
16414     {
16415       errmsg ("profile name too long");
16416       return -99;
16417     }
16418
16419   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16420
16421   clib_memcpy (mp->name, name, vec_len (name));
16422   vec_free (name);
16423   mp->crypto_alg = crypto_alg;
16424   mp->crypto_key_size = crypto_key_size;
16425   mp->integ_alg = integ_alg;
16426   mp->dh_group = dh_group;
16427
16428   S (mp);
16429   W (ret);
16430   return ret;
16431 }
16432
16433
16434 static int
16435 api_ikev2_set_esp_transforms (vat_main_t * vam)
16436 {
16437   unformat_input_t *i = vam->input;
16438   vl_api_ikev2_set_esp_transforms_t *mp;
16439   int ret;
16440   u8 *name = 0;
16441   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16442
16443   const char *valid_chars = "a-zA-Z0-9_";
16444
16445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16446     {
16447       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16448                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16449         vec_add1 (name, 0);
16450       else
16451         {
16452           errmsg ("parse error '%U'", format_unformat_error, i);
16453           return -99;
16454         }
16455     }
16456
16457   if (!vec_len (name))
16458     {
16459       errmsg ("profile name must be specified");
16460       return -99;
16461     }
16462
16463   if (vec_len (name) > 64)
16464     {
16465       errmsg ("profile name too long");
16466       return -99;
16467     }
16468
16469   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16470
16471   clib_memcpy (mp->name, name, vec_len (name));
16472   vec_free (name);
16473   mp->crypto_alg = crypto_alg;
16474   mp->crypto_key_size = crypto_key_size;
16475   mp->integ_alg = integ_alg;
16476   mp->dh_group = dh_group;
16477
16478   S (mp);
16479   W (ret);
16480   return ret;
16481 }
16482
16483 static int
16484 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16485 {
16486   unformat_input_t *i = vam->input;
16487   vl_api_ikev2_set_sa_lifetime_t *mp;
16488   int ret;
16489   u8 *name = 0;
16490   u64 lifetime, lifetime_maxdata;
16491   u32 lifetime_jitter, handover;
16492
16493   const char *valid_chars = "a-zA-Z0-9_";
16494
16495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16496     {
16497       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16498                     &lifetime, &lifetime_jitter, &handover,
16499                     &lifetime_maxdata))
16500         vec_add1 (name, 0);
16501       else
16502         {
16503           errmsg ("parse error '%U'", format_unformat_error, i);
16504           return -99;
16505         }
16506     }
16507
16508   if (!vec_len (name))
16509     {
16510       errmsg ("profile name must be specified");
16511       return -99;
16512     }
16513
16514   if (vec_len (name) > 64)
16515     {
16516       errmsg ("profile name too long");
16517       return -99;
16518     }
16519
16520   M (IKEV2_SET_SA_LIFETIME, mp);
16521
16522   clib_memcpy (mp->name, name, vec_len (name));
16523   vec_free (name);
16524   mp->lifetime = lifetime;
16525   mp->lifetime_jitter = lifetime_jitter;
16526   mp->handover = handover;
16527   mp->lifetime_maxdata = lifetime_maxdata;
16528
16529   S (mp);
16530   W (ret);
16531   return ret;
16532 }
16533
16534 static int
16535 api_ikev2_initiate_sa_init (vat_main_t * vam)
16536 {
16537   unformat_input_t *i = vam->input;
16538   vl_api_ikev2_initiate_sa_init_t *mp;
16539   int ret;
16540   u8 *name = 0;
16541
16542   const char *valid_chars = "a-zA-Z0-9_";
16543
16544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16545     {
16546       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16547         vec_add1 (name, 0);
16548       else
16549         {
16550           errmsg ("parse error '%U'", format_unformat_error, i);
16551           return -99;
16552         }
16553     }
16554
16555   if (!vec_len (name))
16556     {
16557       errmsg ("profile name must be specified");
16558       return -99;
16559     }
16560
16561   if (vec_len (name) > 64)
16562     {
16563       errmsg ("profile name too long");
16564       return -99;
16565     }
16566
16567   M (IKEV2_INITIATE_SA_INIT, mp);
16568
16569   clib_memcpy (mp->name, name, vec_len (name));
16570   vec_free (name);
16571
16572   S (mp);
16573   W (ret);
16574   return ret;
16575 }
16576
16577 static int
16578 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16579 {
16580   unformat_input_t *i = vam->input;
16581   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16582   int ret;
16583   u64 ispi;
16584
16585
16586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16587     {
16588       if (unformat (i, "%lx", &ispi))
16589         ;
16590       else
16591         {
16592           errmsg ("parse error '%U'", format_unformat_error, i);
16593           return -99;
16594         }
16595     }
16596
16597   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16598
16599   mp->ispi = ispi;
16600
16601   S (mp);
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static int
16607 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16608 {
16609   unformat_input_t *i = vam->input;
16610   vl_api_ikev2_initiate_del_child_sa_t *mp;
16611   int ret;
16612   u32 ispi;
16613
16614
16615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (i, "%x", &ispi))
16618         ;
16619       else
16620         {
16621           errmsg ("parse error '%U'", format_unformat_error, i);
16622           return -99;
16623         }
16624     }
16625
16626   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16627
16628   mp->ispi = ispi;
16629
16630   S (mp);
16631   W (ret);
16632   return ret;
16633 }
16634
16635 static int
16636 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16637 {
16638   unformat_input_t *i = vam->input;
16639   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16640   int ret;
16641   u32 ispi;
16642
16643
16644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16645     {
16646       if (unformat (i, "%x", &ispi))
16647         ;
16648       else
16649         {
16650           errmsg ("parse error '%U'", format_unformat_error, i);
16651           return -99;
16652         }
16653     }
16654
16655   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16656
16657   mp->ispi = ispi;
16658
16659   S (mp);
16660   W (ret);
16661   return ret;
16662 }
16663
16664 static int
16665 api_get_first_msg_id (vat_main_t * vam)
16666 {
16667   vl_api_get_first_msg_id_t *mp;
16668   unformat_input_t *i = vam->input;
16669   u8 *name;
16670   u8 name_set = 0;
16671   int ret;
16672
16673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (i, "client %s", &name))
16676         name_set = 1;
16677       else
16678         break;
16679     }
16680
16681   if (name_set == 0)
16682     {
16683       errmsg ("missing client name");
16684       return -99;
16685     }
16686   vec_add1 (name, 0);
16687
16688   if (vec_len (name) > 63)
16689     {
16690       errmsg ("client name too long");
16691       return -99;
16692     }
16693
16694   M (GET_FIRST_MSG_ID, mp);
16695   clib_memcpy (mp->name, name, vec_len (name));
16696   S (mp);
16697   W (ret);
16698   return ret;
16699 }
16700
16701 static int
16702 api_cop_interface_enable_disable (vat_main_t * vam)
16703 {
16704   unformat_input_t *line_input = vam->input;
16705   vl_api_cop_interface_enable_disable_t *mp;
16706   u32 sw_if_index = ~0;
16707   u8 enable_disable = 1;
16708   int ret;
16709
16710   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16711     {
16712       if (unformat (line_input, "disable"))
16713         enable_disable = 0;
16714       if (unformat (line_input, "enable"))
16715         enable_disable = 1;
16716       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16717                          vam, &sw_if_index))
16718         ;
16719       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16720         ;
16721       else
16722         break;
16723     }
16724
16725   if (sw_if_index == ~0)
16726     {
16727       errmsg ("missing interface name or sw_if_index");
16728       return -99;
16729     }
16730
16731   /* Construct the API message */
16732   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16733   mp->sw_if_index = ntohl (sw_if_index);
16734   mp->enable_disable = enable_disable;
16735
16736   /* send it... */
16737   S (mp);
16738   /* Wait for the reply */
16739   W (ret);
16740   return ret;
16741 }
16742
16743 static int
16744 api_cop_whitelist_enable_disable (vat_main_t * vam)
16745 {
16746   unformat_input_t *line_input = vam->input;
16747   vl_api_cop_whitelist_enable_disable_t *mp;
16748   u32 sw_if_index = ~0;
16749   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16750   u32 fib_id = 0;
16751   int ret;
16752
16753   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16754     {
16755       if (unformat (line_input, "ip4"))
16756         ip4 = 1;
16757       else if (unformat (line_input, "ip6"))
16758         ip6 = 1;
16759       else if (unformat (line_input, "default"))
16760         default_cop = 1;
16761       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16762                          vam, &sw_if_index))
16763         ;
16764       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16765         ;
16766       else if (unformat (line_input, "fib-id %d", &fib_id))
16767         ;
16768       else
16769         break;
16770     }
16771
16772   if (sw_if_index == ~0)
16773     {
16774       errmsg ("missing interface name or sw_if_index");
16775       return -99;
16776     }
16777
16778   /* Construct the API message */
16779   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16780   mp->sw_if_index = ntohl (sw_if_index);
16781   mp->fib_id = ntohl (fib_id);
16782   mp->ip4 = ip4;
16783   mp->ip6 = ip6;
16784   mp->default_cop = default_cop;
16785
16786   /* send it... */
16787   S (mp);
16788   /* Wait for the reply */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 static int
16794 api_get_node_graph (vat_main_t * vam)
16795 {
16796   vl_api_get_node_graph_t *mp;
16797   int ret;
16798
16799   M (GET_NODE_GRAPH, mp);
16800
16801   /* send it... */
16802   S (mp);
16803   /* Wait for the reply */
16804   W (ret);
16805   return ret;
16806 }
16807
16808 /* *INDENT-OFF* */
16809 /** Used for parsing LISP eids */
16810 typedef CLIB_PACKED(struct{
16811   u8 addr[16];   /**< eid address */
16812   u32 len;       /**< prefix length if IP */
16813   u8 type;      /**< type of eid */
16814 }) lisp_eid_vat_t;
16815 /* *INDENT-ON* */
16816
16817 static uword
16818 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16819 {
16820   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16821
16822   memset (a, 0, sizeof (a[0]));
16823
16824   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16825     {
16826       a->type = 0;              /* ipv4 type */
16827     }
16828   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16829     {
16830       a->type = 1;              /* ipv6 type */
16831     }
16832   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16833     {
16834       a->type = 2;              /* mac type */
16835     }
16836   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16837     {
16838       a->type = 3;              /* NSH type */
16839       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16840       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16841     }
16842   else
16843     {
16844       return 0;
16845     }
16846
16847   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16848     {
16849       return 0;
16850     }
16851
16852   return 1;
16853 }
16854
16855 static int
16856 lisp_eid_size_vat (u8 type)
16857 {
16858   switch (type)
16859     {
16860     case 0:
16861       return 4;
16862     case 1:
16863       return 16;
16864     case 2:
16865       return 6;
16866     case 3:
16867       return 5;
16868     }
16869   return 0;
16870 }
16871
16872 static void
16873 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16874 {
16875   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16876 }
16877
16878 static int
16879 api_one_add_del_locator_set (vat_main_t * vam)
16880 {
16881   unformat_input_t *input = vam->input;
16882   vl_api_one_add_del_locator_set_t *mp;
16883   u8 is_add = 1;
16884   u8 *locator_set_name = NULL;
16885   u8 locator_set_name_set = 0;
16886   vl_api_local_locator_t locator, *locators = 0;
16887   u32 sw_if_index, priority, weight;
16888   u32 data_len = 0;
16889
16890   int ret;
16891   /* Parse args required to build the message */
16892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16893     {
16894       if (unformat (input, "del"))
16895         {
16896           is_add = 0;
16897         }
16898       else if (unformat (input, "locator-set %s", &locator_set_name))
16899         {
16900           locator_set_name_set = 1;
16901         }
16902       else if (unformat (input, "sw_if_index %u p %u w %u",
16903                          &sw_if_index, &priority, &weight))
16904         {
16905           locator.sw_if_index = htonl (sw_if_index);
16906           locator.priority = priority;
16907           locator.weight = weight;
16908           vec_add1 (locators, locator);
16909         }
16910       else
16911         if (unformat
16912             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16913              &sw_if_index, &priority, &weight))
16914         {
16915           locator.sw_if_index = htonl (sw_if_index);
16916           locator.priority = priority;
16917           locator.weight = weight;
16918           vec_add1 (locators, locator);
16919         }
16920       else
16921         break;
16922     }
16923
16924   if (locator_set_name_set == 0)
16925     {
16926       errmsg ("missing locator-set name");
16927       vec_free (locators);
16928       return -99;
16929     }
16930
16931   if (vec_len (locator_set_name) > 64)
16932     {
16933       errmsg ("locator-set name too long");
16934       vec_free (locator_set_name);
16935       vec_free (locators);
16936       return -99;
16937     }
16938   vec_add1 (locator_set_name, 0);
16939
16940   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16941
16942   /* Construct the API message */
16943   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16944
16945   mp->is_add = is_add;
16946   clib_memcpy (mp->locator_set_name, locator_set_name,
16947                vec_len (locator_set_name));
16948   vec_free (locator_set_name);
16949
16950   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16951   if (locators)
16952     clib_memcpy (mp->locators, locators, data_len);
16953   vec_free (locators);
16954
16955   /* send it... */
16956   S (mp);
16957
16958   /* Wait for a reply... */
16959   W (ret);
16960   return ret;
16961 }
16962
16963 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16964
16965 static int
16966 api_one_add_del_locator (vat_main_t * vam)
16967 {
16968   unformat_input_t *input = vam->input;
16969   vl_api_one_add_del_locator_t *mp;
16970   u32 tmp_if_index = ~0;
16971   u32 sw_if_index = ~0;
16972   u8 sw_if_index_set = 0;
16973   u8 sw_if_index_if_name_set = 0;
16974   u32 priority = ~0;
16975   u8 priority_set = 0;
16976   u32 weight = ~0;
16977   u8 weight_set = 0;
16978   u8 is_add = 1;
16979   u8 *locator_set_name = NULL;
16980   u8 locator_set_name_set = 0;
16981   int ret;
16982
16983   /* Parse args required to build the message */
16984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16985     {
16986       if (unformat (input, "del"))
16987         {
16988           is_add = 0;
16989         }
16990       else if (unformat (input, "locator-set %s", &locator_set_name))
16991         {
16992           locator_set_name_set = 1;
16993         }
16994       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16995                          &tmp_if_index))
16996         {
16997           sw_if_index_if_name_set = 1;
16998           sw_if_index = tmp_if_index;
16999         }
17000       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17001         {
17002           sw_if_index_set = 1;
17003           sw_if_index = tmp_if_index;
17004         }
17005       else if (unformat (input, "p %d", &priority))
17006         {
17007           priority_set = 1;
17008         }
17009       else if (unformat (input, "w %d", &weight))
17010         {
17011           weight_set = 1;
17012         }
17013       else
17014         break;
17015     }
17016
17017   if (locator_set_name_set == 0)
17018     {
17019       errmsg ("missing locator-set name");
17020       return -99;
17021     }
17022
17023   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17024     {
17025       errmsg ("missing sw_if_index");
17026       vec_free (locator_set_name);
17027       return -99;
17028     }
17029
17030   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17031     {
17032       errmsg ("cannot use both params interface name and sw_if_index");
17033       vec_free (locator_set_name);
17034       return -99;
17035     }
17036
17037   if (priority_set == 0)
17038     {
17039       errmsg ("missing locator-set priority");
17040       vec_free (locator_set_name);
17041       return -99;
17042     }
17043
17044   if (weight_set == 0)
17045     {
17046       errmsg ("missing locator-set weight");
17047       vec_free (locator_set_name);
17048       return -99;
17049     }
17050
17051   if (vec_len (locator_set_name) > 64)
17052     {
17053       errmsg ("locator-set name too long");
17054       vec_free (locator_set_name);
17055       return -99;
17056     }
17057   vec_add1 (locator_set_name, 0);
17058
17059   /* Construct the API message */
17060   M (ONE_ADD_DEL_LOCATOR, mp);
17061
17062   mp->is_add = is_add;
17063   mp->sw_if_index = ntohl (sw_if_index);
17064   mp->priority = priority;
17065   mp->weight = weight;
17066   clib_memcpy (mp->locator_set_name, locator_set_name,
17067                vec_len (locator_set_name));
17068   vec_free (locator_set_name);
17069
17070   /* send it... */
17071   S (mp);
17072
17073   /* Wait for a reply... */
17074   W (ret);
17075   return ret;
17076 }
17077
17078 #define api_lisp_add_del_locator api_one_add_del_locator
17079
17080 uword
17081 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17082 {
17083   u32 *key_id = va_arg (*args, u32 *);
17084   u8 *s = 0;
17085
17086   if (unformat (input, "%s", &s))
17087     {
17088       if (!strcmp ((char *) s, "sha1"))
17089         key_id[0] = HMAC_SHA_1_96;
17090       else if (!strcmp ((char *) s, "sha256"))
17091         key_id[0] = HMAC_SHA_256_128;
17092       else
17093         {
17094           clib_warning ("invalid key_id: '%s'", s);
17095           key_id[0] = HMAC_NO_KEY;
17096         }
17097     }
17098   else
17099     return 0;
17100
17101   vec_free (s);
17102   return 1;
17103 }
17104
17105 static int
17106 api_one_add_del_local_eid (vat_main_t * vam)
17107 {
17108   unformat_input_t *input = vam->input;
17109   vl_api_one_add_del_local_eid_t *mp;
17110   u8 is_add = 1;
17111   u8 eid_set = 0;
17112   lisp_eid_vat_t _eid, *eid = &_eid;
17113   u8 *locator_set_name = 0;
17114   u8 locator_set_name_set = 0;
17115   u32 vni = 0;
17116   u16 key_id = 0;
17117   u8 *key = 0;
17118   int ret;
17119
17120   /* Parse args required to build the message */
17121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17122     {
17123       if (unformat (input, "del"))
17124         {
17125           is_add = 0;
17126         }
17127       else if (unformat (input, "vni %d", &vni))
17128         {
17129           ;
17130         }
17131       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17132         {
17133           eid_set = 1;
17134         }
17135       else if (unformat (input, "locator-set %s", &locator_set_name))
17136         {
17137           locator_set_name_set = 1;
17138         }
17139       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17140         ;
17141       else if (unformat (input, "secret-key %_%v%_", &key))
17142         ;
17143       else
17144         break;
17145     }
17146
17147   if (locator_set_name_set == 0)
17148     {
17149       errmsg ("missing locator-set name");
17150       return -99;
17151     }
17152
17153   if (0 == eid_set)
17154     {
17155       errmsg ("EID address not set!");
17156       vec_free (locator_set_name);
17157       return -99;
17158     }
17159
17160   if (key && (0 == key_id))
17161     {
17162       errmsg ("invalid key_id!");
17163       return -99;
17164     }
17165
17166   if (vec_len (key) > 64)
17167     {
17168       errmsg ("key too long");
17169       vec_free (key);
17170       return -99;
17171     }
17172
17173   if (vec_len (locator_set_name) > 64)
17174     {
17175       errmsg ("locator-set name too long");
17176       vec_free (locator_set_name);
17177       return -99;
17178     }
17179   vec_add1 (locator_set_name, 0);
17180
17181   /* Construct the API message */
17182   M (ONE_ADD_DEL_LOCAL_EID, mp);
17183
17184   mp->is_add = is_add;
17185   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17186   mp->eid_type = eid->type;
17187   mp->prefix_len = eid->len;
17188   mp->vni = clib_host_to_net_u32 (vni);
17189   mp->key_id = clib_host_to_net_u16 (key_id);
17190   clib_memcpy (mp->locator_set_name, locator_set_name,
17191                vec_len (locator_set_name));
17192   clib_memcpy (mp->key, key, vec_len (key));
17193
17194   vec_free (locator_set_name);
17195   vec_free (key);
17196
17197   /* send it... */
17198   S (mp);
17199
17200   /* Wait for a reply... */
17201   W (ret);
17202   return ret;
17203 }
17204
17205 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17206
17207 static int
17208 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17209 {
17210   u32 dp_table = 0, vni = 0;;
17211   unformat_input_t *input = vam->input;
17212   vl_api_gpe_add_del_fwd_entry_t *mp;
17213   u8 is_add = 1;
17214   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17215   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17216   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17217   u32 action = ~0, w;
17218   ip4_address_t rmt_rloc4, lcl_rloc4;
17219   ip6_address_t rmt_rloc6, lcl_rloc6;
17220   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17221   int ret;
17222
17223   memset (&rloc, 0, sizeof (rloc));
17224
17225   /* Parse args required to build the message */
17226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (input, "del"))
17229         is_add = 0;
17230       else if (unformat (input, "add"))
17231         is_add = 1;
17232       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17233         {
17234           rmt_eid_set = 1;
17235         }
17236       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17237         {
17238           lcl_eid_set = 1;
17239         }
17240       else if (unformat (input, "vrf %d", &dp_table))
17241         ;
17242       else if (unformat (input, "bd %d", &dp_table))
17243         ;
17244       else if (unformat (input, "vni %d", &vni))
17245         ;
17246       else if (unformat (input, "w %d", &w))
17247         {
17248           if (!curr_rloc)
17249             {
17250               errmsg ("No RLOC configured for setting priority/weight!");
17251               return -99;
17252             }
17253           curr_rloc->weight = w;
17254         }
17255       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17256                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17257         {
17258           rloc.is_ip4 = 1;
17259
17260           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17261           rloc.weight = 0;
17262           vec_add1 (lcl_locs, rloc);
17263
17264           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17265           vec_add1 (rmt_locs, rloc);
17266           /* weight saved in rmt loc */
17267           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17268         }
17269       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17270                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17271         {
17272           rloc.is_ip4 = 0;
17273           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17274           rloc.weight = 0;
17275           vec_add1 (lcl_locs, rloc);
17276
17277           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17278           vec_add1 (rmt_locs, rloc);
17279           /* weight saved in rmt loc */
17280           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17281         }
17282       else if (unformat (input, "action %d", &action))
17283         {
17284           ;
17285         }
17286       else
17287         {
17288           clib_warning ("parse error '%U'", format_unformat_error, input);
17289           return -99;
17290         }
17291     }
17292
17293   if (!rmt_eid_set)
17294     {
17295       errmsg ("remote eid addresses not set");
17296       return -99;
17297     }
17298
17299   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17300     {
17301       errmsg ("eid types don't match");
17302       return -99;
17303     }
17304
17305   if (0 == rmt_locs && (u32) ~ 0 == action)
17306     {
17307       errmsg ("action not set for negative mapping");
17308       return -99;
17309     }
17310
17311   /* Construct the API message */
17312   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17313       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17314
17315   mp->is_add = is_add;
17316   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17317   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17318   mp->eid_type = rmt_eid->type;
17319   mp->dp_table = clib_host_to_net_u32 (dp_table);
17320   mp->vni = clib_host_to_net_u32 (vni);
17321   mp->rmt_len = rmt_eid->len;
17322   mp->lcl_len = lcl_eid->len;
17323   mp->action = action;
17324
17325   if (0 != rmt_locs && 0 != lcl_locs)
17326     {
17327       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17328       clib_memcpy (mp->locs, lcl_locs,
17329                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17330
17331       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17332       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17333                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17334     }
17335   vec_free (lcl_locs);
17336   vec_free (rmt_locs);
17337
17338   /* send it... */
17339   S (mp);
17340
17341   /* Wait for a reply... */
17342   W (ret);
17343   return ret;
17344 }
17345
17346 static int
17347 api_one_add_del_map_server (vat_main_t * vam)
17348 {
17349   unformat_input_t *input = vam->input;
17350   vl_api_one_add_del_map_server_t *mp;
17351   u8 is_add = 1;
17352   u8 ipv4_set = 0;
17353   u8 ipv6_set = 0;
17354   ip4_address_t ipv4;
17355   ip6_address_t ipv6;
17356   int ret;
17357
17358   /* Parse args required to build the message */
17359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17360     {
17361       if (unformat (input, "del"))
17362         {
17363           is_add = 0;
17364         }
17365       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17366         {
17367           ipv4_set = 1;
17368         }
17369       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17370         {
17371           ipv6_set = 1;
17372         }
17373       else
17374         break;
17375     }
17376
17377   if (ipv4_set && ipv6_set)
17378     {
17379       errmsg ("both eid v4 and v6 addresses set");
17380       return -99;
17381     }
17382
17383   if (!ipv4_set && !ipv6_set)
17384     {
17385       errmsg ("eid addresses not set");
17386       return -99;
17387     }
17388
17389   /* Construct the API message */
17390   M (ONE_ADD_DEL_MAP_SERVER, mp);
17391
17392   mp->is_add = is_add;
17393   if (ipv6_set)
17394     {
17395       mp->is_ipv6 = 1;
17396       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17397     }
17398   else
17399     {
17400       mp->is_ipv6 = 0;
17401       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17402     }
17403
17404   /* send it... */
17405   S (mp);
17406
17407   /* Wait for a reply... */
17408   W (ret);
17409   return ret;
17410 }
17411
17412 #define api_lisp_add_del_map_server api_one_add_del_map_server
17413
17414 static int
17415 api_one_add_del_map_resolver (vat_main_t * vam)
17416 {
17417   unformat_input_t *input = vam->input;
17418   vl_api_one_add_del_map_resolver_t *mp;
17419   u8 is_add = 1;
17420   u8 ipv4_set = 0;
17421   u8 ipv6_set = 0;
17422   ip4_address_t ipv4;
17423   ip6_address_t ipv6;
17424   int ret;
17425
17426   /* Parse args required to build the message */
17427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17428     {
17429       if (unformat (input, "del"))
17430         {
17431           is_add = 0;
17432         }
17433       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17434         {
17435           ipv4_set = 1;
17436         }
17437       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17438         {
17439           ipv6_set = 1;
17440         }
17441       else
17442         break;
17443     }
17444
17445   if (ipv4_set && ipv6_set)
17446     {
17447       errmsg ("both eid v4 and v6 addresses set");
17448       return -99;
17449     }
17450
17451   if (!ipv4_set && !ipv6_set)
17452     {
17453       errmsg ("eid addresses not set");
17454       return -99;
17455     }
17456
17457   /* Construct the API message */
17458   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17459
17460   mp->is_add = is_add;
17461   if (ipv6_set)
17462     {
17463       mp->is_ipv6 = 1;
17464       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17465     }
17466   else
17467     {
17468       mp->is_ipv6 = 0;
17469       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17470     }
17471
17472   /* send it... */
17473   S (mp);
17474
17475   /* Wait for a reply... */
17476   W (ret);
17477   return ret;
17478 }
17479
17480 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17481
17482 static int
17483 api_lisp_gpe_enable_disable (vat_main_t * vam)
17484 {
17485   unformat_input_t *input = vam->input;
17486   vl_api_gpe_enable_disable_t *mp;
17487   u8 is_set = 0;
17488   u8 is_en = 1;
17489   int ret;
17490
17491   /* Parse args required to build the message */
17492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (input, "enable"))
17495         {
17496           is_set = 1;
17497           is_en = 1;
17498         }
17499       else if (unformat (input, "disable"))
17500         {
17501           is_set = 1;
17502           is_en = 0;
17503         }
17504       else
17505         break;
17506     }
17507
17508   if (is_set == 0)
17509     {
17510       errmsg ("Value not set");
17511       return -99;
17512     }
17513
17514   /* Construct the API message */
17515   M (GPE_ENABLE_DISABLE, mp);
17516
17517   mp->is_en = is_en;
17518
17519   /* send it... */
17520   S (mp);
17521
17522   /* Wait for a reply... */
17523   W (ret);
17524   return ret;
17525 }
17526
17527 static int
17528 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17529 {
17530   unformat_input_t *input = vam->input;
17531   vl_api_one_rloc_probe_enable_disable_t *mp;
17532   u8 is_set = 0;
17533   u8 is_en = 0;
17534   int ret;
17535
17536   /* Parse args required to build the message */
17537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17538     {
17539       if (unformat (input, "enable"))
17540         {
17541           is_set = 1;
17542           is_en = 1;
17543         }
17544       else if (unformat (input, "disable"))
17545         is_set = 1;
17546       else
17547         break;
17548     }
17549
17550   if (!is_set)
17551     {
17552       errmsg ("Value not set");
17553       return -99;
17554     }
17555
17556   /* Construct the API message */
17557   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17558
17559   mp->is_enabled = is_en;
17560
17561   /* send it... */
17562   S (mp);
17563
17564   /* Wait for a reply... */
17565   W (ret);
17566   return ret;
17567 }
17568
17569 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17570
17571 static int
17572 api_one_map_register_enable_disable (vat_main_t * vam)
17573 {
17574   unformat_input_t *input = vam->input;
17575   vl_api_one_map_register_enable_disable_t *mp;
17576   u8 is_set = 0;
17577   u8 is_en = 0;
17578   int ret;
17579
17580   /* Parse args required to build the message */
17581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17582     {
17583       if (unformat (input, "enable"))
17584         {
17585           is_set = 1;
17586           is_en = 1;
17587         }
17588       else if (unformat (input, "disable"))
17589         is_set = 1;
17590       else
17591         break;
17592     }
17593
17594   if (!is_set)
17595     {
17596       errmsg ("Value not set");
17597       return -99;
17598     }
17599
17600   /* Construct the API message */
17601   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17602
17603   mp->is_enabled = is_en;
17604
17605   /* send it... */
17606   S (mp);
17607
17608   /* Wait for a reply... */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17614
17615 static int
17616 api_one_enable_disable (vat_main_t * vam)
17617 {
17618   unformat_input_t *input = vam->input;
17619   vl_api_one_enable_disable_t *mp;
17620   u8 is_set = 0;
17621   u8 is_en = 0;
17622   int ret;
17623
17624   /* Parse args required to build the message */
17625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17626     {
17627       if (unformat (input, "enable"))
17628         {
17629           is_set = 1;
17630           is_en = 1;
17631         }
17632       else if (unformat (input, "disable"))
17633         {
17634           is_set = 1;
17635         }
17636       else
17637         break;
17638     }
17639
17640   if (!is_set)
17641     {
17642       errmsg ("Value not set");
17643       return -99;
17644     }
17645
17646   /* Construct the API message */
17647   M (ONE_ENABLE_DISABLE, mp);
17648
17649   mp->is_en = is_en;
17650
17651   /* send it... */
17652   S (mp);
17653
17654   /* Wait for a reply... */
17655   W (ret);
17656   return ret;
17657 }
17658
17659 #define api_lisp_enable_disable api_one_enable_disable
17660
17661 static int
17662 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17663 {
17664   unformat_input_t *input = vam->input;
17665   vl_api_one_enable_disable_xtr_mode_t *mp;
17666   u8 is_set = 0;
17667   u8 is_en = 0;
17668   int ret;
17669
17670   /* Parse args required to build the message */
17671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17672     {
17673       if (unformat (input, "enable"))
17674         {
17675           is_set = 1;
17676           is_en = 1;
17677         }
17678       else if (unformat (input, "disable"))
17679         {
17680           is_set = 1;
17681         }
17682       else
17683         break;
17684     }
17685
17686   if (!is_set)
17687     {
17688       errmsg ("Value not set");
17689       return -99;
17690     }
17691
17692   /* Construct the API message */
17693   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17694
17695   mp->is_en = is_en;
17696
17697   /* send it... */
17698   S (mp);
17699
17700   /* Wait for a reply... */
17701   W (ret);
17702   return ret;
17703 }
17704
17705 static int
17706 api_one_show_xtr_mode (vat_main_t * vam)
17707 {
17708   vl_api_one_show_xtr_mode_t *mp;
17709   int ret;
17710
17711   /* Construct the API message */
17712   M (ONE_SHOW_XTR_MODE, mp);
17713
17714   /* send it... */
17715   S (mp);
17716
17717   /* Wait for a reply... */
17718   W (ret);
17719   return ret;
17720 }
17721
17722 static int
17723 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17724 {
17725   unformat_input_t *input = vam->input;
17726   vl_api_one_enable_disable_pitr_mode_t *mp;
17727   u8 is_set = 0;
17728   u8 is_en = 0;
17729   int ret;
17730
17731   /* Parse args required to build the message */
17732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17733     {
17734       if (unformat (input, "enable"))
17735         {
17736           is_set = 1;
17737           is_en = 1;
17738         }
17739       else if (unformat (input, "disable"))
17740         {
17741           is_set = 1;
17742         }
17743       else
17744         break;
17745     }
17746
17747   if (!is_set)
17748     {
17749       errmsg ("Value not set");
17750       return -99;
17751     }
17752
17753   /* Construct the API message */
17754   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17755
17756   mp->is_en = is_en;
17757
17758   /* send it... */
17759   S (mp);
17760
17761   /* Wait for a reply... */
17762   W (ret);
17763   return ret;
17764 }
17765
17766 static int
17767 api_one_show_pitr_mode (vat_main_t * vam)
17768 {
17769   vl_api_one_show_pitr_mode_t *mp;
17770   int ret;
17771
17772   /* Construct the API message */
17773   M (ONE_SHOW_PITR_MODE, mp);
17774
17775   /* send it... */
17776   S (mp);
17777
17778   /* Wait for a reply... */
17779   W (ret);
17780   return ret;
17781 }
17782
17783 static int
17784 api_one_enable_disable_petr_mode (vat_main_t * vam)
17785 {
17786   unformat_input_t *input = vam->input;
17787   vl_api_one_enable_disable_petr_mode_t *mp;
17788   u8 is_set = 0;
17789   u8 is_en = 0;
17790   int ret;
17791
17792   /* Parse args required to build the message */
17793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17794     {
17795       if (unformat (input, "enable"))
17796         {
17797           is_set = 1;
17798           is_en = 1;
17799         }
17800       else if (unformat (input, "disable"))
17801         {
17802           is_set = 1;
17803         }
17804       else
17805         break;
17806     }
17807
17808   if (!is_set)
17809     {
17810       errmsg ("Value not set");
17811       return -99;
17812     }
17813
17814   /* Construct the API message */
17815   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17816
17817   mp->is_en = is_en;
17818
17819   /* send it... */
17820   S (mp);
17821
17822   /* Wait for a reply... */
17823   W (ret);
17824   return ret;
17825 }
17826
17827 static int
17828 api_one_show_petr_mode (vat_main_t * vam)
17829 {
17830   vl_api_one_show_petr_mode_t *mp;
17831   int ret;
17832
17833   /* Construct the API message */
17834   M (ONE_SHOW_PETR_MODE, mp);
17835
17836   /* send it... */
17837   S (mp);
17838
17839   /* Wait for a reply... */
17840   W (ret);
17841   return ret;
17842 }
17843
17844 static int
17845 api_show_one_map_register_state (vat_main_t * vam)
17846 {
17847   vl_api_show_one_map_register_state_t *mp;
17848   int ret;
17849
17850   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17851
17852   /* send */
17853   S (mp);
17854
17855   /* wait for reply */
17856   W (ret);
17857   return ret;
17858 }
17859
17860 #define api_show_lisp_map_register_state api_show_one_map_register_state
17861
17862 static int
17863 api_show_one_rloc_probe_state (vat_main_t * vam)
17864 {
17865   vl_api_show_one_rloc_probe_state_t *mp;
17866   int ret;
17867
17868   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17869
17870   /* send */
17871   S (mp);
17872
17873   /* wait for reply */
17874   W (ret);
17875   return ret;
17876 }
17877
17878 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17879
17880 static int
17881 api_one_add_del_ndp_entry (vat_main_t * vam)
17882 {
17883   vl_api_one_add_del_ndp_entry_t *mp;
17884   unformat_input_t *input = vam->input;
17885   u8 is_add = 1;
17886   u8 mac_set = 0;
17887   u8 bd_set = 0;
17888   u8 ip_set = 0;
17889   u8 mac[6] = { 0, };
17890   u8 ip6[16] = { 0, };
17891   u32 bd = ~0;
17892   int ret;
17893
17894   /* Parse args required to build the message */
17895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17896     {
17897       if (unformat (input, "del"))
17898         is_add = 0;
17899       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17900         mac_set = 1;
17901       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17902         ip_set = 1;
17903       else if (unformat (input, "bd %d", &bd))
17904         bd_set = 1;
17905       else
17906         {
17907           errmsg ("parse error '%U'", format_unformat_error, input);
17908           return -99;
17909         }
17910     }
17911
17912   if (!bd_set || !ip_set || (!mac_set && is_add))
17913     {
17914       errmsg ("Missing BD, IP or MAC!");
17915       return -99;
17916     }
17917
17918   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17919   mp->is_add = is_add;
17920   clib_memcpy (mp->mac, mac, 6);
17921   mp->bd = clib_host_to_net_u32 (bd);
17922   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17923
17924   /* send */
17925   S (mp);
17926
17927   /* wait for reply */
17928   W (ret);
17929   return ret;
17930 }
17931
17932 static int
17933 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17934 {
17935   vl_api_one_add_del_l2_arp_entry_t *mp;
17936   unformat_input_t *input = vam->input;
17937   u8 is_add = 1;
17938   u8 mac_set = 0;
17939   u8 bd_set = 0;
17940   u8 ip_set = 0;
17941   u8 mac[6] = { 0, };
17942   u32 ip4 = 0, bd = ~0;
17943   int ret;
17944
17945   /* Parse args required to build the message */
17946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17947     {
17948       if (unformat (input, "del"))
17949         is_add = 0;
17950       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17951         mac_set = 1;
17952       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17953         ip_set = 1;
17954       else if (unformat (input, "bd %d", &bd))
17955         bd_set = 1;
17956       else
17957         {
17958           errmsg ("parse error '%U'", format_unformat_error, input);
17959           return -99;
17960         }
17961     }
17962
17963   if (!bd_set || !ip_set || (!mac_set && is_add))
17964     {
17965       errmsg ("Missing BD, IP or MAC!");
17966       return -99;
17967     }
17968
17969   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17970   mp->is_add = is_add;
17971   clib_memcpy (mp->mac, mac, 6);
17972   mp->bd = clib_host_to_net_u32 (bd);
17973   mp->ip4 = ip4;
17974
17975   /* send */
17976   S (mp);
17977
17978   /* wait for reply */
17979   W (ret);
17980   return ret;
17981 }
17982
17983 static int
17984 api_one_ndp_bd_get (vat_main_t * vam)
17985 {
17986   vl_api_one_ndp_bd_get_t *mp;
17987   int ret;
17988
17989   M (ONE_NDP_BD_GET, mp);
17990
17991   /* send */
17992   S (mp);
17993
17994   /* wait for reply */
17995   W (ret);
17996   return ret;
17997 }
17998
17999 static int
18000 api_one_ndp_entries_get (vat_main_t * vam)
18001 {
18002   vl_api_one_ndp_entries_get_t *mp;
18003   unformat_input_t *input = vam->input;
18004   u8 bd_set = 0;
18005   u32 bd = ~0;
18006   int ret;
18007
18008   /* Parse args required to build the message */
18009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18010     {
18011       if (unformat (input, "bd %d", &bd))
18012         bd_set = 1;
18013       else
18014         {
18015           errmsg ("parse error '%U'", format_unformat_error, input);
18016           return -99;
18017         }
18018     }
18019
18020   if (!bd_set)
18021     {
18022       errmsg ("Expected bridge domain!");
18023       return -99;
18024     }
18025
18026   M (ONE_NDP_ENTRIES_GET, mp);
18027   mp->bd = clib_host_to_net_u32 (bd);
18028
18029   /* send */
18030   S (mp);
18031
18032   /* wait for reply */
18033   W (ret);
18034   return ret;
18035 }
18036
18037 static int
18038 api_one_l2_arp_bd_get (vat_main_t * vam)
18039 {
18040   vl_api_one_l2_arp_bd_get_t *mp;
18041   int ret;
18042
18043   M (ONE_L2_ARP_BD_GET, mp);
18044
18045   /* send */
18046   S (mp);
18047
18048   /* wait for reply */
18049   W (ret);
18050   return ret;
18051 }
18052
18053 static int
18054 api_one_l2_arp_entries_get (vat_main_t * vam)
18055 {
18056   vl_api_one_l2_arp_entries_get_t *mp;
18057   unformat_input_t *input = vam->input;
18058   u8 bd_set = 0;
18059   u32 bd = ~0;
18060   int ret;
18061
18062   /* Parse args required to build the message */
18063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18064     {
18065       if (unformat (input, "bd %d", &bd))
18066         bd_set = 1;
18067       else
18068         {
18069           errmsg ("parse error '%U'", format_unformat_error, input);
18070           return -99;
18071         }
18072     }
18073
18074   if (!bd_set)
18075     {
18076       errmsg ("Expected bridge domain!");
18077       return -99;
18078     }
18079
18080   M (ONE_L2_ARP_ENTRIES_GET, mp);
18081   mp->bd = clib_host_to_net_u32 (bd);
18082
18083   /* send */
18084   S (mp);
18085
18086   /* wait for reply */
18087   W (ret);
18088   return ret;
18089 }
18090
18091 static int
18092 api_one_stats_enable_disable (vat_main_t * vam)
18093 {
18094   vl_api_one_stats_enable_disable_t *mp;
18095   unformat_input_t *input = vam->input;
18096   u8 is_set = 0;
18097   u8 is_en = 0;
18098   int ret;
18099
18100   /* Parse args required to build the message */
18101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18102     {
18103       if (unformat (input, "enable"))
18104         {
18105           is_set = 1;
18106           is_en = 1;
18107         }
18108       else if (unformat (input, "disable"))
18109         {
18110           is_set = 1;
18111         }
18112       else
18113         break;
18114     }
18115
18116   if (!is_set)
18117     {
18118       errmsg ("Value not set");
18119       return -99;
18120     }
18121
18122   M (ONE_STATS_ENABLE_DISABLE, mp);
18123   mp->is_en = is_en;
18124
18125   /* send */
18126   S (mp);
18127
18128   /* wait for reply */
18129   W (ret);
18130   return ret;
18131 }
18132
18133 static int
18134 api_show_one_stats_enable_disable (vat_main_t * vam)
18135 {
18136   vl_api_show_one_stats_enable_disable_t *mp;
18137   int ret;
18138
18139   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18140
18141   /* send */
18142   S (mp);
18143
18144   /* wait for reply */
18145   W (ret);
18146   return ret;
18147 }
18148
18149 static int
18150 api_show_one_map_request_mode (vat_main_t * vam)
18151 {
18152   vl_api_show_one_map_request_mode_t *mp;
18153   int ret;
18154
18155   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18156
18157   /* send */
18158   S (mp);
18159
18160   /* wait for reply */
18161   W (ret);
18162   return ret;
18163 }
18164
18165 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18166
18167 static int
18168 api_one_map_request_mode (vat_main_t * vam)
18169 {
18170   unformat_input_t *input = vam->input;
18171   vl_api_one_map_request_mode_t *mp;
18172   u8 mode = 0;
18173   int ret;
18174
18175   /* Parse args required to build the message */
18176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18177     {
18178       if (unformat (input, "dst-only"))
18179         mode = 0;
18180       else if (unformat (input, "src-dst"))
18181         mode = 1;
18182       else
18183         {
18184           errmsg ("parse error '%U'", format_unformat_error, input);
18185           return -99;
18186         }
18187     }
18188
18189   M (ONE_MAP_REQUEST_MODE, mp);
18190
18191   mp->mode = mode;
18192
18193   /* send */
18194   S (mp);
18195
18196   /* wait for reply */
18197   W (ret);
18198   return ret;
18199 }
18200
18201 #define api_lisp_map_request_mode api_one_map_request_mode
18202
18203 /**
18204  * Enable/disable ONE proxy ITR.
18205  *
18206  * @param vam vpp API test context
18207  * @return return code
18208  */
18209 static int
18210 api_one_pitr_set_locator_set (vat_main_t * vam)
18211 {
18212   u8 ls_name_set = 0;
18213   unformat_input_t *input = vam->input;
18214   vl_api_one_pitr_set_locator_set_t *mp;
18215   u8 is_add = 1;
18216   u8 *ls_name = 0;
18217   int ret;
18218
18219   /* Parse args required to build the message */
18220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18221     {
18222       if (unformat (input, "del"))
18223         is_add = 0;
18224       else if (unformat (input, "locator-set %s", &ls_name))
18225         ls_name_set = 1;
18226       else
18227         {
18228           errmsg ("parse error '%U'", format_unformat_error, input);
18229           return -99;
18230         }
18231     }
18232
18233   if (!ls_name_set)
18234     {
18235       errmsg ("locator-set name not set!");
18236       return -99;
18237     }
18238
18239   M (ONE_PITR_SET_LOCATOR_SET, mp);
18240
18241   mp->is_add = is_add;
18242   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18243   vec_free (ls_name);
18244
18245   /* send */
18246   S (mp);
18247
18248   /* wait for reply */
18249   W (ret);
18250   return ret;
18251 }
18252
18253 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18254
18255 static int
18256 api_one_nsh_set_locator_set (vat_main_t * vam)
18257 {
18258   u8 ls_name_set = 0;
18259   unformat_input_t *input = vam->input;
18260   vl_api_one_nsh_set_locator_set_t *mp;
18261   u8 is_add = 1;
18262   u8 *ls_name = 0;
18263   int ret;
18264
18265   /* Parse args required to build the message */
18266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18267     {
18268       if (unformat (input, "del"))
18269         is_add = 0;
18270       else if (unformat (input, "ls %s", &ls_name))
18271         ls_name_set = 1;
18272       else
18273         {
18274           errmsg ("parse error '%U'", format_unformat_error, input);
18275           return -99;
18276         }
18277     }
18278
18279   if (!ls_name_set && is_add)
18280     {
18281       errmsg ("locator-set name not set!");
18282       return -99;
18283     }
18284
18285   M (ONE_NSH_SET_LOCATOR_SET, mp);
18286
18287   mp->is_add = is_add;
18288   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18289   vec_free (ls_name);
18290
18291   /* send */
18292   S (mp);
18293
18294   /* wait for reply */
18295   W (ret);
18296   return ret;
18297 }
18298
18299 static int
18300 api_show_one_pitr (vat_main_t * vam)
18301 {
18302   vl_api_show_one_pitr_t *mp;
18303   int ret;
18304
18305   if (!vam->json_output)
18306     {
18307       print (vam->ofp, "%=20s", "lisp status:");
18308     }
18309
18310   M (SHOW_ONE_PITR, mp);
18311   /* send it... */
18312   S (mp);
18313
18314   /* Wait for a reply... */
18315   W (ret);
18316   return ret;
18317 }
18318
18319 #define api_show_lisp_pitr api_show_one_pitr
18320
18321 static int
18322 api_one_use_petr (vat_main_t * vam)
18323 {
18324   unformat_input_t *input = vam->input;
18325   vl_api_one_use_petr_t *mp;
18326   u8 is_add = 0;
18327   ip_address_t ip;
18328   int ret;
18329
18330   memset (&ip, 0, sizeof (ip));
18331
18332   /* Parse args required to build the message */
18333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18334     {
18335       if (unformat (input, "disable"))
18336         is_add = 0;
18337       else
18338         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18339         {
18340           is_add = 1;
18341           ip_addr_version (&ip) = IP4;
18342         }
18343       else
18344         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18345         {
18346           is_add = 1;
18347           ip_addr_version (&ip) = IP6;
18348         }
18349       else
18350         {
18351           errmsg ("parse error '%U'", format_unformat_error, input);
18352           return -99;
18353         }
18354     }
18355
18356   M (ONE_USE_PETR, mp);
18357
18358   mp->is_add = is_add;
18359   if (is_add)
18360     {
18361       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18362       if (mp->is_ip4)
18363         clib_memcpy (mp->address, &ip, 4);
18364       else
18365         clib_memcpy (mp->address, &ip, 16);
18366     }
18367
18368   /* send */
18369   S (mp);
18370
18371   /* wait for reply */
18372   W (ret);
18373   return ret;
18374 }
18375
18376 #define api_lisp_use_petr api_one_use_petr
18377
18378 static int
18379 api_show_one_nsh_mapping (vat_main_t * vam)
18380 {
18381   vl_api_show_one_use_petr_t *mp;
18382   int ret;
18383
18384   if (!vam->json_output)
18385     {
18386       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18387     }
18388
18389   M (SHOW_ONE_NSH_MAPPING, mp);
18390   /* send it... */
18391   S (mp);
18392
18393   /* Wait for a reply... */
18394   W (ret);
18395   return ret;
18396 }
18397
18398 static int
18399 api_show_one_use_petr (vat_main_t * vam)
18400 {
18401   vl_api_show_one_use_petr_t *mp;
18402   int ret;
18403
18404   if (!vam->json_output)
18405     {
18406       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18407     }
18408
18409   M (SHOW_ONE_USE_PETR, mp);
18410   /* send it... */
18411   S (mp);
18412
18413   /* Wait for a reply... */
18414   W (ret);
18415   return ret;
18416 }
18417
18418 #define api_show_lisp_use_petr api_show_one_use_petr
18419
18420 /**
18421  * Add/delete mapping between vni and vrf
18422  */
18423 static int
18424 api_one_eid_table_add_del_map (vat_main_t * vam)
18425 {
18426   unformat_input_t *input = vam->input;
18427   vl_api_one_eid_table_add_del_map_t *mp;
18428   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18429   u32 vni, vrf, bd_index;
18430   int ret;
18431
18432   /* Parse args required to build the message */
18433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18434     {
18435       if (unformat (input, "del"))
18436         is_add = 0;
18437       else if (unformat (input, "vrf %d", &vrf))
18438         vrf_set = 1;
18439       else if (unformat (input, "bd_index %d", &bd_index))
18440         bd_index_set = 1;
18441       else if (unformat (input, "vni %d", &vni))
18442         vni_set = 1;
18443       else
18444         break;
18445     }
18446
18447   if (!vni_set || (!vrf_set && !bd_index_set))
18448     {
18449       errmsg ("missing arguments!");
18450       return -99;
18451     }
18452
18453   if (vrf_set && bd_index_set)
18454     {
18455       errmsg ("error: both vrf and bd entered!");
18456       return -99;
18457     }
18458
18459   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18460
18461   mp->is_add = is_add;
18462   mp->vni = htonl (vni);
18463   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18464   mp->is_l2 = bd_index_set;
18465
18466   /* send */
18467   S (mp);
18468
18469   /* wait for reply */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18475
18476 uword
18477 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18478 {
18479   u32 *action = va_arg (*args, u32 *);
18480   u8 *s = 0;
18481
18482   if (unformat (input, "%s", &s))
18483     {
18484       if (!strcmp ((char *) s, "no-action"))
18485         action[0] = 0;
18486       else if (!strcmp ((char *) s, "natively-forward"))
18487         action[0] = 1;
18488       else if (!strcmp ((char *) s, "send-map-request"))
18489         action[0] = 2;
18490       else if (!strcmp ((char *) s, "drop"))
18491         action[0] = 3;
18492       else
18493         {
18494           clib_warning ("invalid action: '%s'", s);
18495           action[0] = 3;
18496         }
18497     }
18498   else
18499     return 0;
18500
18501   vec_free (s);
18502   return 1;
18503 }
18504
18505 /**
18506  * Add/del remote mapping to/from ONE control plane
18507  *
18508  * @param vam vpp API test context
18509  * @return return code
18510  */
18511 static int
18512 api_one_add_del_remote_mapping (vat_main_t * vam)
18513 {
18514   unformat_input_t *input = vam->input;
18515   vl_api_one_add_del_remote_mapping_t *mp;
18516   u32 vni = 0;
18517   lisp_eid_vat_t _eid, *eid = &_eid;
18518   lisp_eid_vat_t _seid, *seid = &_seid;
18519   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18520   u32 action = ~0, p, w, data_len;
18521   ip4_address_t rloc4;
18522   ip6_address_t rloc6;
18523   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18524   int ret;
18525
18526   memset (&rloc, 0, sizeof (rloc));
18527
18528   /* Parse args required to build the message */
18529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18530     {
18531       if (unformat (input, "del-all"))
18532         {
18533           del_all = 1;
18534         }
18535       else if (unformat (input, "del"))
18536         {
18537           is_add = 0;
18538         }
18539       else if (unformat (input, "add"))
18540         {
18541           is_add = 1;
18542         }
18543       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18544         {
18545           eid_set = 1;
18546         }
18547       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18548         {
18549           seid_set = 1;
18550         }
18551       else if (unformat (input, "vni %d", &vni))
18552         {
18553           ;
18554         }
18555       else if (unformat (input, "p %d w %d", &p, &w))
18556         {
18557           if (!curr_rloc)
18558             {
18559               errmsg ("No RLOC configured for setting priority/weight!");
18560               return -99;
18561             }
18562           curr_rloc->priority = p;
18563           curr_rloc->weight = w;
18564         }
18565       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18566         {
18567           rloc.is_ip4 = 1;
18568           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18569           vec_add1 (rlocs, rloc);
18570           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18571         }
18572       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18573         {
18574           rloc.is_ip4 = 0;
18575           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18576           vec_add1 (rlocs, rloc);
18577           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18578         }
18579       else if (unformat (input, "action %U",
18580                          unformat_negative_mapping_action, &action))
18581         {
18582           ;
18583         }
18584       else
18585         {
18586           clib_warning ("parse error '%U'", format_unformat_error, input);
18587           return -99;
18588         }
18589     }
18590
18591   if (0 == eid_set)
18592     {
18593       errmsg ("missing params!");
18594       return -99;
18595     }
18596
18597   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18598     {
18599       errmsg ("no action set for negative map-reply!");
18600       return -99;
18601     }
18602
18603   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18604
18605   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18606   mp->is_add = is_add;
18607   mp->vni = htonl (vni);
18608   mp->action = (u8) action;
18609   mp->is_src_dst = seid_set;
18610   mp->eid_len = eid->len;
18611   mp->seid_len = seid->len;
18612   mp->del_all = del_all;
18613   mp->eid_type = eid->type;
18614   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18615   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18616
18617   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18618   clib_memcpy (mp->rlocs, rlocs, data_len);
18619   vec_free (rlocs);
18620
18621   /* send it... */
18622   S (mp);
18623
18624   /* Wait for a reply... */
18625   W (ret);
18626   return ret;
18627 }
18628
18629 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18630
18631 /**
18632  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18633  * forwarding entries in data-plane accordingly.
18634  *
18635  * @param vam vpp API test context
18636  * @return return code
18637  */
18638 static int
18639 api_one_add_del_adjacency (vat_main_t * vam)
18640 {
18641   unformat_input_t *input = vam->input;
18642   vl_api_one_add_del_adjacency_t *mp;
18643   u32 vni = 0;
18644   ip4_address_t leid4, reid4;
18645   ip6_address_t leid6, reid6;
18646   u8 reid_mac[6] = { 0 };
18647   u8 leid_mac[6] = { 0 };
18648   u8 reid_type, leid_type;
18649   u32 leid_len = 0, reid_len = 0, len;
18650   u8 is_add = 1;
18651   int ret;
18652
18653   leid_type = reid_type = (u8) ~ 0;
18654
18655   /* Parse args required to build the message */
18656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18657     {
18658       if (unformat (input, "del"))
18659         {
18660           is_add = 0;
18661         }
18662       else if (unformat (input, "add"))
18663         {
18664           is_add = 1;
18665         }
18666       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18667                          &reid4, &len))
18668         {
18669           reid_type = 0;        /* ipv4 */
18670           reid_len = len;
18671         }
18672       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18673                          &reid6, &len))
18674         {
18675           reid_type = 1;        /* ipv6 */
18676           reid_len = len;
18677         }
18678       else if (unformat (input, "reid %U", unformat_ethernet_address,
18679                          reid_mac))
18680         {
18681           reid_type = 2;        /* mac */
18682         }
18683       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18684                          &leid4, &len))
18685         {
18686           leid_type = 0;        /* ipv4 */
18687           leid_len = len;
18688         }
18689       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18690                          &leid6, &len))
18691         {
18692           leid_type = 1;        /* ipv6 */
18693           leid_len = len;
18694         }
18695       else if (unformat (input, "leid %U", unformat_ethernet_address,
18696                          leid_mac))
18697         {
18698           leid_type = 2;        /* mac */
18699         }
18700       else if (unformat (input, "vni %d", &vni))
18701         {
18702           ;
18703         }
18704       else
18705         {
18706           errmsg ("parse error '%U'", format_unformat_error, input);
18707           return -99;
18708         }
18709     }
18710
18711   if ((u8) ~ 0 == reid_type)
18712     {
18713       errmsg ("missing params!");
18714       return -99;
18715     }
18716
18717   if (leid_type != reid_type)
18718     {
18719       errmsg ("remote and local EIDs are of different types!");
18720       return -99;
18721     }
18722
18723   M (ONE_ADD_DEL_ADJACENCY, mp);
18724   mp->is_add = is_add;
18725   mp->vni = htonl (vni);
18726   mp->leid_len = leid_len;
18727   mp->reid_len = reid_len;
18728   mp->eid_type = reid_type;
18729
18730   switch (mp->eid_type)
18731     {
18732     case 0:
18733       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18734       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18735       break;
18736     case 1:
18737       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18738       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18739       break;
18740     case 2:
18741       clib_memcpy (mp->leid, leid_mac, 6);
18742       clib_memcpy (mp->reid, reid_mac, 6);
18743       break;
18744     default:
18745       errmsg ("unknown EID type %d!", mp->eid_type);
18746       return 0;
18747     }
18748
18749   /* send it... */
18750   S (mp);
18751
18752   /* Wait for a reply... */
18753   W (ret);
18754   return ret;
18755 }
18756
18757 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18758
18759 uword
18760 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18761 {
18762   u32 *mode = va_arg (*args, u32 *);
18763
18764   if (unformat (input, "lisp"))
18765     *mode = 0;
18766   else if (unformat (input, "vxlan"))
18767     *mode = 1;
18768   else
18769     return 0;
18770
18771   return 1;
18772 }
18773
18774 static int
18775 api_gpe_get_encap_mode (vat_main_t * vam)
18776 {
18777   vl_api_gpe_get_encap_mode_t *mp;
18778   int ret;
18779
18780   /* Construct the API message */
18781   M (GPE_GET_ENCAP_MODE, mp);
18782
18783   /* send it... */
18784   S (mp);
18785
18786   /* Wait for a reply... */
18787   W (ret);
18788   return ret;
18789 }
18790
18791 static int
18792 api_gpe_set_encap_mode (vat_main_t * vam)
18793 {
18794   unformat_input_t *input = vam->input;
18795   vl_api_gpe_set_encap_mode_t *mp;
18796   int ret;
18797   u32 mode = 0;
18798
18799   /* Parse args required to build the message */
18800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18801     {
18802       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18803         ;
18804       else
18805         break;
18806     }
18807
18808   /* Construct the API message */
18809   M (GPE_SET_ENCAP_MODE, mp);
18810
18811   mp->mode = mode;
18812
18813   /* send it... */
18814   S (mp);
18815
18816   /* Wait for a reply... */
18817   W (ret);
18818   return ret;
18819 }
18820
18821 static int
18822 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18823 {
18824   unformat_input_t *input = vam->input;
18825   vl_api_gpe_add_del_iface_t *mp;
18826   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18827   u32 dp_table = 0, vni = 0;
18828   int ret;
18829
18830   /* Parse args required to build the message */
18831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18832     {
18833       if (unformat (input, "up"))
18834         {
18835           action_set = 1;
18836           is_add = 1;
18837         }
18838       else if (unformat (input, "down"))
18839         {
18840           action_set = 1;
18841           is_add = 0;
18842         }
18843       else if (unformat (input, "table_id %d", &dp_table))
18844         {
18845           dp_table_set = 1;
18846         }
18847       else if (unformat (input, "bd_id %d", &dp_table))
18848         {
18849           dp_table_set = 1;
18850           is_l2 = 1;
18851         }
18852       else if (unformat (input, "vni %d", &vni))
18853         {
18854           vni_set = 1;
18855         }
18856       else
18857         break;
18858     }
18859
18860   if (action_set == 0)
18861     {
18862       errmsg ("Action not set");
18863       return -99;
18864     }
18865   if (dp_table_set == 0 || vni_set == 0)
18866     {
18867       errmsg ("vni and dp_table must be set");
18868       return -99;
18869     }
18870
18871   /* Construct the API message */
18872   M (GPE_ADD_DEL_IFACE, mp);
18873
18874   mp->is_add = is_add;
18875   mp->dp_table = clib_host_to_net_u32 (dp_table);
18876   mp->is_l2 = is_l2;
18877   mp->vni = clib_host_to_net_u32 (vni);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 static int
18888 api_one_map_register_fallback_threshold (vat_main_t * vam)
18889 {
18890   unformat_input_t *input = vam->input;
18891   vl_api_one_map_register_fallback_threshold_t *mp;
18892   u32 value = 0;
18893   u8 is_set = 0;
18894   int ret;
18895
18896   /* Parse args required to build the message */
18897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18898     {
18899       if (unformat (input, "%u", &value))
18900         is_set = 1;
18901       else
18902         {
18903           clib_warning ("parse error '%U'", format_unformat_error, input);
18904           return -99;
18905         }
18906     }
18907
18908   if (!is_set)
18909     {
18910       errmsg ("fallback threshold value is missing!");
18911       return -99;
18912     }
18913
18914   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18915   mp->value = clib_host_to_net_u32 (value);
18916
18917   /* send it... */
18918   S (mp);
18919
18920   /* Wait for a reply... */
18921   W (ret);
18922   return ret;
18923 }
18924
18925 static int
18926 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18927 {
18928   vl_api_show_one_map_register_fallback_threshold_t *mp;
18929   int ret;
18930
18931   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18932
18933   /* send it... */
18934   S (mp);
18935
18936   /* Wait for a reply... */
18937   W (ret);
18938   return ret;
18939 }
18940
18941 uword
18942 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18943 {
18944   u32 *proto = va_arg (*args, u32 *);
18945
18946   if (unformat (input, "udp"))
18947     *proto = 1;
18948   else if (unformat (input, "api"))
18949     *proto = 2;
18950   else
18951     return 0;
18952
18953   return 1;
18954 }
18955
18956 static int
18957 api_one_set_transport_protocol (vat_main_t * vam)
18958 {
18959   unformat_input_t *input = vam->input;
18960   vl_api_one_set_transport_protocol_t *mp;
18961   u8 is_set = 0;
18962   u32 protocol = 0;
18963   int ret;
18964
18965   /* Parse args required to build the message */
18966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18967     {
18968       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18969         is_set = 1;
18970       else
18971         {
18972           clib_warning ("parse error '%U'", format_unformat_error, input);
18973           return -99;
18974         }
18975     }
18976
18977   if (!is_set)
18978     {
18979       errmsg ("Transport protocol missing!");
18980       return -99;
18981     }
18982
18983   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18984   mp->protocol = (u8) protocol;
18985
18986   /* send it... */
18987   S (mp);
18988
18989   /* Wait for a reply... */
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_one_get_transport_protocol (vat_main_t * vam)
18996 {
18997   vl_api_one_get_transport_protocol_t *mp;
18998   int ret;
18999
19000   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19001
19002   /* send it... */
19003   S (mp);
19004
19005   /* Wait for a reply... */
19006   W (ret);
19007   return ret;
19008 }
19009
19010 static int
19011 api_one_map_register_set_ttl (vat_main_t * vam)
19012 {
19013   unformat_input_t *input = vam->input;
19014   vl_api_one_map_register_set_ttl_t *mp;
19015   u32 ttl = 0;
19016   u8 is_set = 0;
19017   int ret;
19018
19019   /* Parse args required to build the message */
19020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19021     {
19022       if (unformat (input, "%u", &ttl))
19023         is_set = 1;
19024       else
19025         {
19026           clib_warning ("parse error '%U'", format_unformat_error, input);
19027           return -99;
19028         }
19029     }
19030
19031   if (!is_set)
19032     {
19033       errmsg ("TTL value missing!");
19034       return -99;
19035     }
19036
19037   M (ONE_MAP_REGISTER_SET_TTL, mp);
19038   mp->ttl = clib_host_to_net_u32 (ttl);
19039
19040   /* send it... */
19041   S (mp);
19042
19043   /* Wait for a reply... */
19044   W (ret);
19045   return ret;
19046 }
19047
19048 static int
19049 api_show_one_map_register_ttl (vat_main_t * vam)
19050 {
19051   vl_api_show_one_map_register_ttl_t *mp;
19052   int ret;
19053
19054   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19055
19056   /* send it... */
19057   S (mp);
19058
19059   /* Wait for a reply... */
19060   W (ret);
19061   return ret;
19062 }
19063
19064 /**
19065  * Add/del map request itr rlocs from ONE control plane and updates
19066  *
19067  * @param vam vpp API test context
19068  * @return return code
19069  */
19070 static int
19071 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19072 {
19073   unformat_input_t *input = vam->input;
19074   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19075   u8 *locator_set_name = 0;
19076   u8 locator_set_name_set = 0;
19077   u8 is_add = 1;
19078   int ret;
19079
19080   /* Parse args required to build the message */
19081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19082     {
19083       if (unformat (input, "del"))
19084         {
19085           is_add = 0;
19086         }
19087       else if (unformat (input, "%_%v%_", &locator_set_name))
19088         {
19089           locator_set_name_set = 1;
19090         }
19091       else
19092         {
19093           clib_warning ("parse error '%U'", format_unformat_error, input);
19094           return -99;
19095         }
19096     }
19097
19098   if (is_add && !locator_set_name_set)
19099     {
19100       errmsg ("itr-rloc is not set!");
19101       return -99;
19102     }
19103
19104   if (is_add && vec_len (locator_set_name) > 64)
19105     {
19106       errmsg ("itr-rloc locator-set name too long");
19107       vec_free (locator_set_name);
19108       return -99;
19109     }
19110
19111   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19112   mp->is_add = is_add;
19113   if (is_add)
19114     {
19115       clib_memcpy (mp->locator_set_name, locator_set_name,
19116                    vec_len (locator_set_name));
19117     }
19118   else
19119     {
19120       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19121     }
19122   vec_free (locator_set_name);
19123
19124   /* send it... */
19125   S (mp);
19126
19127   /* Wait for a reply... */
19128   W (ret);
19129   return ret;
19130 }
19131
19132 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19133
19134 static int
19135 api_one_locator_dump (vat_main_t * vam)
19136 {
19137   unformat_input_t *input = vam->input;
19138   vl_api_one_locator_dump_t *mp;
19139   vl_api_control_ping_t *mp_ping;
19140   u8 is_index_set = 0, is_name_set = 0;
19141   u8 *ls_name = 0;
19142   u32 ls_index = ~0;
19143   int ret;
19144
19145   /* Parse args required to build the message */
19146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19147     {
19148       if (unformat (input, "ls_name %_%v%_", &ls_name))
19149         {
19150           is_name_set = 1;
19151         }
19152       else if (unformat (input, "ls_index %d", &ls_index))
19153         {
19154           is_index_set = 1;
19155         }
19156       else
19157         {
19158           errmsg ("parse error '%U'", format_unformat_error, input);
19159           return -99;
19160         }
19161     }
19162
19163   if (!is_index_set && !is_name_set)
19164     {
19165       errmsg ("error: expected one of index or name!");
19166       return -99;
19167     }
19168
19169   if (is_index_set && is_name_set)
19170     {
19171       errmsg ("error: only one param expected!");
19172       return -99;
19173     }
19174
19175   if (vec_len (ls_name) > 62)
19176     {
19177       errmsg ("error: locator set name too long!");
19178       return -99;
19179     }
19180
19181   if (!vam->json_output)
19182     {
19183       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19184     }
19185
19186   M (ONE_LOCATOR_DUMP, mp);
19187   mp->is_index_set = is_index_set;
19188
19189   if (is_index_set)
19190     mp->ls_index = clib_host_to_net_u32 (ls_index);
19191   else
19192     {
19193       vec_add1 (ls_name, 0);
19194       strncpy ((char *) mp->ls_name, (char *) ls_name,
19195                sizeof (mp->ls_name) - 1);
19196     }
19197
19198   /* send it... */
19199   S (mp);
19200
19201   /* Use a control ping for synchronization */
19202   MPING (CONTROL_PING, mp_ping);
19203   S (mp_ping);
19204
19205   /* Wait for a reply... */
19206   W (ret);
19207   return ret;
19208 }
19209
19210 #define api_lisp_locator_dump api_one_locator_dump
19211
19212 static int
19213 api_one_locator_set_dump (vat_main_t * vam)
19214 {
19215   vl_api_one_locator_set_dump_t *mp;
19216   vl_api_control_ping_t *mp_ping;
19217   unformat_input_t *input = vam->input;
19218   u8 filter = 0;
19219   int ret;
19220
19221   /* Parse args required to build the message */
19222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19223     {
19224       if (unformat (input, "local"))
19225         {
19226           filter = 1;
19227         }
19228       else if (unformat (input, "remote"))
19229         {
19230           filter = 2;
19231         }
19232       else
19233         {
19234           errmsg ("parse error '%U'", format_unformat_error, input);
19235           return -99;
19236         }
19237     }
19238
19239   if (!vam->json_output)
19240     {
19241       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19242     }
19243
19244   M (ONE_LOCATOR_SET_DUMP, mp);
19245
19246   mp->filter = filter;
19247
19248   /* send it... */
19249   S (mp);
19250
19251   /* Use a control ping for synchronization */
19252   MPING (CONTROL_PING, mp_ping);
19253   S (mp_ping);
19254
19255   /* Wait for a reply... */
19256   W (ret);
19257   return ret;
19258 }
19259
19260 #define api_lisp_locator_set_dump api_one_locator_set_dump
19261
19262 static int
19263 api_one_eid_table_map_dump (vat_main_t * vam)
19264 {
19265   u8 is_l2 = 0;
19266   u8 mode_set = 0;
19267   unformat_input_t *input = vam->input;
19268   vl_api_one_eid_table_map_dump_t *mp;
19269   vl_api_control_ping_t *mp_ping;
19270   int ret;
19271
19272   /* Parse args required to build the message */
19273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19274     {
19275       if (unformat (input, "l2"))
19276         {
19277           is_l2 = 1;
19278           mode_set = 1;
19279         }
19280       else if (unformat (input, "l3"))
19281         {
19282           is_l2 = 0;
19283           mode_set = 1;
19284         }
19285       else
19286         {
19287           errmsg ("parse error '%U'", format_unformat_error, input);
19288           return -99;
19289         }
19290     }
19291
19292   if (!mode_set)
19293     {
19294       errmsg ("expected one of 'l2' or 'l3' parameter!");
19295       return -99;
19296     }
19297
19298   if (!vam->json_output)
19299     {
19300       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19301     }
19302
19303   M (ONE_EID_TABLE_MAP_DUMP, mp);
19304   mp->is_l2 = is_l2;
19305
19306   /* send it... */
19307   S (mp);
19308
19309   /* Use a control ping for synchronization */
19310   MPING (CONTROL_PING, mp_ping);
19311   S (mp_ping);
19312
19313   /* Wait for a reply... */
19314   W (ret);
19315   return ret;
19316 }
19317
19318 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19319
19320 static int
19321 api_one_eid_table_vni_dump (vat_main_t * vam)
19322 {
19323   vl_api_one_eid_table_vni_dump_t *mp;
19324   vl_api_control_ping_t *mp_ping;
19325   int ret;
19326
19327   if (!vam->json_output)
19328     {
19329       print (vam->ofp, "VNI");
19330     }
19331
19332   M (ONE_EID_TABLE_VNI_DUMP, mp);
19333
19334   /* send it... */
19335   S (mp);
19336
19337   /* Use a control ping for synchronization */
19338   MPING (CONTROL_PING, mp_ping);
19339   S (mp_ping);
19340
19341   /* Wait for a reply... */
19342   W (ret);
19343   return ret;
19344 }
19345
19346 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19347
19348 static int
19349 api_one_eid_table_dump (vat_main_t * vam)
19350 {
19351   unformat_input_t *i = vam->input;
19352   vl_api_one_eid_table_dump_t *mp;
19353   vl_api_control_ping_t *mp_ping;
19354   struct in_addr ip4;
19355   struct in6_addr ip6;
19356   u8 mac[6];
19357   u8 eid_type = ~0, eid_set = 0;
19358   u32 prefix_length = ~0, t, vni = 0;
19359   u8 filter = 0;
19360   int ret;
19361   lisp_nsh_api_t nsh;
19362
19363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19364     {
19365       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19366         {
19367           eid_set = 1;
19368           eid_type = 0;
19369           prefix_length = t;
19370         }
19371       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19372         {
19373           eid_set = 1;
19374           eid_type = 1;
19375           prefix_length = t;
19376         }
19377       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19378         {
19379           eid_set = 1;
19380           eid_type = 2;
19381         }
19382       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19383         {
19384           eid_set = 1;
19385           eid_type = 3;
19386         }
19387       else if (unformat (i, "vni %d", &t))
19388         {
19389           vni = t;
19390         }
19391       else if (unformat (i, "local"))
19392         {
19393           filter = 1;
19394         }
19395       else if (unformat (i, "remote"))
19396         {
19397           filter = 2;
19398         }
19399       else
19400         {
19401           errmsg ("parse error '%U'", format_unformat_error, i);
19402           return -99;
19403         }
19404     }
19405
19406   if (!vam->json_output)
19407     {
19408       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19409              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19410     }
19411
19412   M (ONE_EID_TABLE_DUMP, mp);
19413
19414   mp->filter = filter;
19415   if (eid_set)
19416     {
19417       mp->eid_set = 1;
19418       mp->vni = htonl (vni);
19419       mp->eid_type = eid_type;
19420       switch (eid_type)
19421         {
19422         case 0:
19423           mp->prefix_length = prefix_length;
19424           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19425           break;
19426         case 1:
19427           mp->prefix_length = prefix_length;
19428           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19429           break;
19430         case 2:
19431           clib_memcpy (mp->eid, mac, sizeof (mac));
19432           break;
19433         case 3:
19434           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19435           break;
19436         default:
19437           errmsg ("unknown EID type %d!", eid_type);
19438           return -99;
19439         }
19440     }
19441
19442   /* send it... */
19443   S (mp);
19444
19445   /* Use a control ping for synchronization */
19446   MPING (CONTROL_PING, mp_ping);
19447   S (mp_ping);
19448
19449   /* Wait for a reply... */
19450   W (ret);
19451   return ret;
19452 }
19453
19454 #define api_lisp_eid_table_dump api_one_eid_table_dump
19455
19456 static int
19457 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19458 {
19459   unformat_input_t *i = vam->input;
19460   vl_api_gpe_fwd_entries_get_t *mp;
19461   u8 vni_set = 0;
19462   u32 vni = ~0;
19463   int ret;
19464
19465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19466     {
19467       if (unformat (i, "vni %d", &vni))
19468         {
19469           vni_set = 1;
19470         }
19471       else
19472         {
19473           errmsg ("parse error '%U'", format_unformat_error, i);
19474           return -99;
19475         }
19476     }
19477
19478   if (!vni_set)
19479     {
19480       errmsg ("vni not set!");
19481       return -99;
19482     }
19483
19484   if (!vam->json_output)
19485     {
19486       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19487              "leid", "reid");
19488     }
19489
19490   M (GPE_FWD_ENTRIES_GET, mp);
19491   mp->vni = clib_host_to_net_u32 (vni);
19492
19493   /* send it... */
19494   S (mp);
19495
19496   /* Wait for a reply... */
19497   W (ret);
19498   return ret;
19499 }
19500
19501 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19502 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19503 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19504 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19505 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19506 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19507 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19508 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19509
19510 static int
19511 api_one_adjacencies_get (vat_main_t * vam)
19512 {
19513   unformat_input_t *i = vam->input;
19514   vl_api_one_adjacencies_get_t *mp;
19515   u8 vni_set = 0;
19516   u32 vni = ~0;
19517   int ret;
19518
19519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19520     {
19521       if (unformat (i, "vni %d", &vni))
19522         {
19523           vni_set = 1;
19524         }
19525       else
19526         {
19527           errmsg ("parse error '%U'", format_unformat_error, i);
19528           return -99;
19529         }
19530     }
19531
19532   if (!vni_set)
19533     {
19534       errmsg ("vni not set!");
19535       return -99;
19536     }
19537
19538   if (!vam->json_output)
19539     {
19540       print (vam->ofp, "%s %40s", "leid", "reid");
19541     }
19542
19543   M (ONE_ADJACENCIES_GET, mp);
19544   mp->vni = clib_host_to_net_u32 (vni);
19545
19546   /* send it... */
19547   S (mp);
19548
19549   /* Wait for a reply... */
19550   W (ret);
19551   return ret;
19552 }
19553
19554 #define api_lisp_adjacencies_get api_one_adjacencies_get
19555
19556 static int
19557 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19558 {
19559   unformat_input_t *i = vam->input;
19560   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19561   int ret;
19562   u8 ip_family_set = 0, is_ip4 = 1;
19563
19564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19565     {
19566       if (unformat (i, "ip4"))
19567         {
19568           ip_family_set = 1;
19569           is_ip4 = 1;
19570         }
19571       else if (unformat (i, "ip6"))
19572         {
19573           ip_family_set = 1;
19574           is_ip4 = 0;
19575         }
19576       else
19577         {
19578           errmsg ("parse error '%U'", format_unformat_error, i);
19579           return -99;
19580         }
19581     }
19582
19583   if (!ip_family_set)
19584     {
19585       errmsg ("ip family not set!");
19586       return -99;
19587     }
19588
19589   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19590   mp->is_ip4 = is_ip4;
19591
19592   /* send it... */
19593   S (mp);
19594
19595   /* Wait for a reply... */
19596   W (ret);
19597   return ret;
19598 }
19599
19600 static int
19601 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19602 {
19603   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19604   int ret;
19605
19606   if (!vam->json_output)
19607     {
19608       print (vam->ofp, "VNIs");
19609     }
19610
19611   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19612
19613   /* send it... */
19614   S (mp);
19615
19616   /* Wait for a reply... */
19617   W (ret);
19618   return ret;
19619 }
19620
19621 static int
19622 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19623 {
19624   unformat_input_t *i = vam->input;
19625   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19626   int ret = 0;
19627   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19628   struct in_addr ip4;
19629   struct in6_addr ip6;
19630   u32 table_id = 0, nh_sw_if_index = ~0;
19631
19632   memset (&ip4, 0, sizeof (ip4));
19633   memset (&ip6, 0, sizeof (ip6));
19634
19635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19636     {
19637       if (unformat (i, "del"))
19638         is_add = 0;
19639       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19640                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19641         {
19642           ip_set = 1;
19643           is_ip4 = 1;
19644         }
19645       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19646                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19647         {
19648           ip_set = 1;
19649           is_ip4 = 0;
19650         }
19651       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19652         {
19653           ip_set = 1;
19654           is_ip4 = 1;
19655           nh_sw_if_index = ~0;
19656         }
19657       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19658         {
19659           ip_set = 1;
19660           is_ip4 = 0;
19661           nh_sw_if_index = ~0;
19662         }
19663       else if (unformat (i, "table %d", &table_id))
19664         ;
19665       else
19666         {
19667           errmsg ("parse error '%U'", format_unformat_error, i);
19668           return -99;
19669         }
19670     }
19671
19672   if (!ip_set)
19673     {
19674       errmsg ("nh addr not set!");
19675       return -99;
19676     }
19677
19678   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19679   mp->is_add = is_add;
19680   mp->table_id = clib_host_to_net_u32 (table_id);
19681   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19682   mp->is_ip4 = is_ip4;
19683   if (is_ip4)
19684     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19685   else
19686     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19687
19688   /* send it... */
19689   S (mp);
19690
19691   /* Wait for a reply... */
19692   W (ret);
19693   return ret;
19694 }
19695
19696 static int
19697 api_one_map_server_dump (vat_main_t * vam)
19698 {
19699   vl_api_one_map_server_dump_t *mp;
19700   vl_api_control_ping_t *mp_ping;
19701   int ret;
19702
19703   if (!vam->json_output)
19704     {
19705       print (vam->ofp, "%=20s", "Map server");
19706     }
19707
19708   M (ONE_MAP_SERVER_DUMP, mp);
19709   /* send it... */
19710   S (mp);
19711
19712   /* Use a control ping for synchronization */
19713   MPING (CONTROL_PING, mp_ping);
19714   S (mp_ping);
19715
19716   /* Wait for a reply... */
19717   W (ret);
19718   return ret;
19719 }
19720
19721 #define api_lisp_map_server_dump api_one_map_server_dump
19722
19723 static int
19724 api_one_map_resolver_dump (vat_main_t * vam)
19725 {
19726   vl_api_one_map_resolver_dump_t *mp;
19727   vl_api_control_ping_t *mp_ping;
19728   int ret;
19729
19730   if (!vam->json_output)
19731     {
19732       print (vam->ofp, "%=20s", "Map resolver");
19733     }
19734
19735   M (ONE_MAP_RESOLVER_DUMP, mp);
19736   /* send it... */
19737   S (mp);
19738
19739   /* Use a control ping for synchronization */
19740   MPING (CONTROL_PING, mp_ping);
19741   S (mp_ping);
19742
19743   /* Wait for a reply... */
19744   W (ret);
19745   return ret;
19746 }
19747
19748 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19749
19750 static int
19751 api_one_stats_flush (vat_main_t * vam)
19752 {
19753   vl_api_one_stats_flush_t *mp;
19754   int ret = 0;
19755
19756   M (ONE_STATS_FLUSH, mp);
19757   S (mp);
19758   W (ret);
19759   return ret;
19760 }
19761
19762 static int
19763 api_one_stats_dump (vat_main_t * vam)
19764 {
19765   vl_api_one_stats_dump_t *mp;
19766   vl_api_control_ping_t *mp_ping;
19767   int ret;
19768
19769   M (ONE_STATS_DUMP, mp);
19770   /* send it... */
19771   S (mp);
19772
19773   /* Use a control ping for synchronization */
19774   MPING (CONTROL_PING, mp_ping);
19775   S (mp_ping);
19776
19777   /* Wait for a reply... */
19778   W (ret);
19779   return ret;
19780 }
19781
19782 static int
19783 api_show_one_status (vat_main_t * vam)
19784 {
19785   vl_api_show_one_status_t *mp;
19786   int ret;
19787
19788   if (!vam->json_output)
19789     {
19790       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19791     }
19792
19793   M (SHOW_ONE_STATUS, mp);
19794   /* send it... */
19795   S (mp);
19796   /* Wait for a reply... */
19797   W (ret);
19798   return ret;
19799 }
19800
19801 #define api_show_lisp_status api_show_one_status
19802
19803 static int
19804 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19805 {
19806   vl_api_gpe_fwd_entry_path_dump_t *mp;
19807   vl_api_control_ping_t *mp_ping;
19808   unformat_input_t *i = vam->input;
19809   u32 fwd_entry_index = ~0;
19810   int ret;
19811
19812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19813     {
19814       if (unformat (i, "index %d", &fwd_entry_index))
19815         ;
19816       else
19817         break;
19818     }
19819
19820   if (~0 == fwd_entry_index)
19821     {
19822       errmsg ("no index specified!");
19823       return -99;
19824     }
19825
19826   if (!vam->json_output)
19827     {
19828       print (vam->ofp, "first line");
19829     }
19830
19831   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19832
19833   /* send it... */
19834   S (mp);
19835   /* Use a control ping for synchronization */
19836   MPING (CONTROL_PING, mp_ping);
19837   S (mp_ping);
19838
19839   /* Wait for a reply... */
19840   W (ret);
19841   return ret;
19842 }
19843
19844 static int
19845 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19846 {
19847   vl_api_one_get_map_request_itr_rlocs_t *mp;
19848   int ret;
19849
19850   if (!vam->json_output)
19851     {
19852       print (vam->ofp, "%=20s", "itr-rlocs:");
19853     }
19854
19855   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19856   /* send it... */
19857   S (mp);
19858   /* Wait for a reply... */
19859   W (ret);
19860   return ret;
19861 }
19862
19863 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19864
19865 static int
19866 api_af_packet_create (vat_main_t * vam)
19867 {
19868   unformat_input_t *i = vam->input;
19869   vl_api_af_packet_create_t *mp;
19870   u8 *host_if_name = 0;
19871   u8 hw_addr[6];
19872   u8 random_hw_addr = 1;
19873   int ret;
19874
19875   memset (hw_addr, 0, sizeof (hw_addr));
19876
19877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19878     {
19879       if (unformat (i, "name %s", &host_if_name))
19880         vec_add1 (host_if_name, 0);
19881       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19882         random_hw_addr = 0;
19883       else
19884         break;
19885     }
19886
19887   if (!vec_len (host_if_name))
19888     {
19889       errmsg ("host-interface name must be specified");
19890       return -99;
19891     }
19892
19893   if (vec_len (host_if_name) > 64)
19894     {
19895       errmsg ("host-interface name too long");
19896       return -99;
19897     }
19898
19899   M (AF_PACKET_CREATE, mp);
19900
19901   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19902   clib_memcpy (mp->hw_addr, hw_addr, 6);
19903   mp->use_random_hw_addr = random_hw_addr;
19904   vec_free (host_if_name);
19905
19906   S (mp);
19907
19908   /* *INDENT-OFF* */
19909   W2 (ret,
19910       ({
19911         if (ret == 0)
19912           fprintf (vam->ofp ? vam->ofp : stderr,
19913                    " new sw_if_index = %d\n", vam->sw_if_index);
19914       }));
19915   /* *INDENT-ON* */
19916   return ret;
19917 }
19918
19919 static int
19920 api_af_packet_delete (vat_main_t * vam)
19921 {
19922   unformat_input_t *i = vam->input;
19923   vl_api_af_packet_delete_t *mp;
19924   u8 *host_if_name = 0;
19925   int ret;
19926
19927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19928     {
19929       if (unformat (i, "name %s", &host_if_name))
19930         vec_add1 (host_if_name, 0);
19931       else
19932         break;
19933     }
19934
19935   if (!vec_len (host_if_name))
19936     {
19937       errmsg ("host-interface name must be specified");
19938       return -99;
19939     }
19940
19941   if (vec_len (host_if_name) > 64)
19942     {
19943       errmsg ("host-interface name too long");
19944       return -99;
19945     }
19946
19947   M (AF_PACKET_DELETE, mp);
19948
19949   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19950   vec_free (host_if_name);
19951
19952   S (mp);
19953   W (ret);
19954   return ret;
19955 }
19956
19957 static void vl_api_af_packet_details_t_handler
19958   (vl_api_af_packet_details_t * mp)
19959 {
19960   vat_main_t *vam = &vat_main;
19961
19962   print (vam->ofp, "%-16s %d",
19963          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19964 }
19965
19966 static void vl_api_af_packet_details_t_handler_json
19967   (vl_api_af_packet_details_t * mp)
19968 {
19969   vat_main_t *vam = &vat_main;
19970   vat_json_node_t *node = NULL;
19971
19972   if (VAT_JSON_ARRAY != vam->json_tree.type)
19973     {
19974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19975       vat_json_init_array (&vam->json_tree);
19976     }
19977   node = vat_json_array_add (&vam->json_tree);
19978
19979   vat_json_init_object (node);
19980   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19981   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19982 }
19983
19984 static int
19985 api_af_packet_dump (vat_main_t * vam)
19986 {
19987   vl_api_af_packet_dump_t *mp;
19988   vl_api_control_ping_t *mp_ping;
19989   int ret;
19990
19991   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19992   /* Get list of tap interfaces */
19993   M (AF_PACKET_DUMP, mp);
19994   S (mp);
19995
19996   /* Use a control ping for synchronization */
19997   MPING (CONTROL_PING, mp_ping);
19998   S (mp_ping);
19999
20000   W (ret);
20001   return ret;
20002 }
20003
20004 static int
20005 api_policer_add_del (vat_main_t * vam)
20006 {
20007   unformat_input_t *i = vam->input;
20008   vl_api_policer_add_del_t *mp;
20009   u8 is_add = 1;
20010   u8 *name = 0;
20011   u32 cir = 0;
20012   u32 eir = 0;
20013   u64 cb = 0;
20014   u64 eb = 0;
20015   u8 rate_type = 0;
20016   u8 round_type = 0;
20017   u8 type = 0;
20018   u8 color_aware = 0;
20019   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20020   int ret;
20021
20022   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20023   conform_action.dscp = 0;
20024   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20025   exceed_action.dscp = 0;
20026   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20027   violate_action.dscp = 0;
20028
20029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20030     {
20031       if (unformat (i, "del"))
20032         is_add = 0;
20033       else if (unformat (i, "name %s", &name))
20034         vec_add1 (name, 0);
20035       else if (unformat (i, "cir %u", &cir))
20036         ;
20037       else if (unformat (i, "eir %u", &eir))
20038         ;
20039       else if (unformat (i, "cb %u", &cb))
20040         ;
20041       else if (unformat (i, "eb %u", &eb))
20042         ;
20043       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20044                          &rate_type))
20045         ;
20046       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20047                          &round_type))
20048         ;
20049       else if (unformat (i, "type %U", unformat_policer_type, &type))
20050         ;
20051       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20052                          &conform_action))
20053         ;
20054       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20055                          &exceed_action))
20056         ;
20057       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20058                          &violate_action))
20059         ;
20060       else if (unformat (i, "color-aware"))
20061         color_aware = 1;
20062       else
20063         break;
20064     }
20065
20066   if (!vec_len (name))
20067     {
20068       errmsg ("policer name must be specified");
20069       return -99;
20070     }
20071
20072   if (vec_len (name) > 64)
20073     {
20074       errmsg ("policer name too long");
20075       return -99;
20076     }
20077
20078   M (POLICER_ADD_DEL, mp);
20079
20080   clib_memcpy (mp->name, name, vec_len (name));
20081   vec_free (name);
20082   mp->is_add = is_add;
20083   mp->cir = ntohl (cir);
20084   mp->eir = ntohl (eir);
20085   mp->cb = clib_net_to_host_u64 (cb);
20086   mp->eb = clib_net_to_host_u64 (eb);
20087   mp->rate_type = rate_type;
20088   mp->round_type = round_type;
20089   mp->type = type;
20090   mp->conform_action_type = conform_action.action_type;
20091   mp->conform_dscp = conform_action.dscp;
20092   mp->exceed_action_type = exceed_action.action_type;
20093   mp->exceed_dscp = exceed_action.dscp;
20094   mp->violate_action_type = violate_action.action_type;
20095   mp->violate_dscp = violate_action.dscp;
20096   mp->color_aware = color_aware;
20097
20098   S (mp);
20099   W (ret);
20100   return ret;
20101 }
20102
20103 static int
20104 api_policer_dump (vat_main_t * vam)
20105 {
20106   unformat_input_t *i = vam->input;
20107   vl_api_policer_dump_t *mp;
20108   vl_api_control_ping_t *mp_ping;
20109   u8 *match_name = 0;
20110   u8 match_name_valid = 0;
20111   int ret;
20112
20113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20114     {
20115       if (unformat (i, "name %s", &match_name))
20116         {
20117           vec_add1 (match_name, 0);
20118           match_name_valid = 1;
20119         }
20120       else
20121         break;
20122     }
20123
20124   M (POLICER_DUMP, mp);
20125   mp->match_name_valid = match_name_valid;
20126   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20127   vec_free (match_name);
20128   /* send it... */
20129   S (mp);
20130
20131   /* Use a control ping for synchronization */
20132   MPING (CONTROL_PING, mp_ping);
20133   S (mp_ping);
20134
20135   /* Wait for a reply... */
20136   W (ret);
20137   return ret;
20138 }
20139
20140 static int
20141 api_policer_classify_set_interface (vat_main_t * vam)
20142 {
20143   unformat_input_t *i = vam->input;
20144   vl_api_policer_classify_set_interface_t *mp;
20145   u32 sw_if_index;
20146   int sw_if_index_set;
20147   u32 ip4_table_index = ~0;
20148   u32 ip6_table_index = ~0;
20149   u32 l2_table_index = ~0;
20150   u8 is_add = 1;
20151   int ret;
20152
20153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20154     {
20155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20156         sw_if_index_set = 1;
20157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20158         sw_if_index_set = 1;
20159       else if (unformat (i, "del"))
20160         is_add = 0;
20161       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20162         ;
20163       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20164         ;
20165       else if (unformat (i, "l2-table %d", &l2_table_index))
20166         ;
20167       else
20168         {
20169           clib_warning ("parse error '%U'", format_unformat_error, i);
20170           return -99;
20171         }
20172     }
20173
20174   if (sw_if_index_set == 0)
20175     {
20176       errmsg ("missing interface name or sw_if_index");
20177       return -99;
20178     }
20179
20180   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20181
20182   mp->sw_if_index = ntohl (sw_if_index);
20183   mp->ip4_table_index = ntohl (ip4_table_index);
20184   mp->ip6_table_index = ntohl (ip6_table_index);
20185   mp->l2_table_index = ntohl (l2_table_index);
20186   mp->is_add = is_add;
20187
20188   S (mp);
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static int
20194 api_policer_classify_dump (vat_main_t * vam)
20195 {
20196   unformat_input_t *i = vam->input;
20197   vl_api_policer_classify_dump_t *mp;
20198   vl_api_control_ping_t *mp_ping;
20199   u8 type = POLICER_CLASSIFY_N_TABLES;
20200   int ret;
20201
20202   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20203     ;
20204   else
20205     {
20206       errmsg ("classify table type must be specified");
20207       return -99;
20208     }
20209
20210   if (!vam->json_output)
20211     {
20212       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20213     }
20214
20215   M (POLICER_CLASSIFY_DUMP, mp);
20216   mp->type = type;
20217   /* send it... */
20218   S (mp);
20219
20220   /* Use a control ping for synchronization */
20221   MPING (CONTROL_PING, mp_ping);
20222   S (mp_ping);
20223
20224   /* Wait for a reply... */
20225   W (ret);
20226   return ret;
20227 }
20228
20229 static int
20230 api_netmap_create (vat_main_t * vam)
20231 {
20232   unformat_input_t *i = vam->input;
20233   vl_api_netmap_create_t *mp;
20234   u8 *if_name = 0;
20235   u8 hw_addr[6];
20236   u8 random_hw_addr = 1;
20237   u8 is_pipe = 0;
20238   u8 is_master = 0;
20239   int ret;
20240
20241   memset (hw_addr, 0, sizeof (hw_addr));
20242
20243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20244     {
20245       if (unformat (i, "name %s", &if_name))
20246         vec_add1 (if_name, 0);
20247       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20248         random_hw_addr = 0;
20249       else if (unformat (i, "pipe"))
20250         is_pipe = 1;
20251       else if (unformat (i, "master"))
20252         is_master = 1;
20253       else if (unformat (i, "slave"))
20254         is_master = 0;
20255       else
20256         break;
20257     }
20258
20259   if (!vec_len (if_name))
20260     {
20261       errmsg ("interface name must be specified");
20262       return -99;
20263     }
20264
20265   if (vec_len (if_name) > 64)
20266     {
20267       errmsg ("interface name too long");
20268       return -99;
20269     }
20270
20271   M (NETMAP_CREATE, mp);
20272
20273   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20274   clib_memcpy (mp->hw_addr, hw_addr, 6);
20275   mp->use_random_hw_addr = random_hw_addr;
20276   mp->is_pipe = is_pipe;
20277   mp->is_master = is_master;
20278   vec_free (if_name);
20279
20280   S (mp);
20281   W (ret);
20282   return ret;
20283 }
20284
20285 static int
20286 api_netmap_delete (vat_main_t * vam)
20287 {
20288   unformat_input_t *i = vam->input;
20289   vl_api_netmap_delete_t *mp;
20290   u8 *if_name = 0;
20291   int ret;
20292
20293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20294     {
20295       if (unformat (i, "name %s", &if_name))
20296         vec_add1 (if_name, 0);
20297       else
20298         break;
20299     }
20300
20301   if (!vec_len (if_name))
20302     {
20303       errmsg ("interface name must be specified");
20304       return -99;
20305     }
20306
20307   if (vec_len (if_name) > 64)
20308     {
20309       errmsg ("interface name too long");
20310       return -99;
20311     }
20312
20313   M (NETMAP_DELETE, mp);
20314
20315   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20316   vec_free (if_name);
20317
20318   S (mp);
20319   W (ret);
20320   return ret;
20321 }
20322
20323 static void
20324 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20325 {
20326   if (fp->afi == IP46_TYPE_IP6)
20327     print (vam->ofp,
20328            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20329            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20330            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20331            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20332            format_ip6_address, fp->next_hop);
20333   else if (fp->afi == IP46_TYPE_IP4)
20334     print (vam->ofp,
20335            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20336            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20337            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20338            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20339            format_ip4_address, fp->next_hop);
20340 }
20341
20342 static void
20343 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20344                                  vl_api_fib_path_t * fp)
20345 {
20346   struct in_addr ip4;
20347   struct in6_addr ip6;
20348
20349   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20350   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20351   vat_json_object_add_uint (node, "is_local", fp->is_local);
20352   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20353   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20354   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20355   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20356   if (fp->afi == IP46_TYPE_IP4)
20357     {
20358       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20359       vat_json_object_add_ip4 (node, "next_hop", ip4);
20360     }
20361   else if (fp->afi == IP46_TYPE_IP6)
20362     {
20363       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20364       vat_json_object_add_ip6 (node, "next_hop", ip6);
20365     }
20366 }
20367
20368 static void
20369 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20370 {
20371   vat_main_t *vam = &vat_main;
20372   int count = ntohl (mp->mt_count);
20373   vl_api_fib_path_t *fp;
20374   i32 i;
20375
20376   print (vam->ofp, "[%d]: sw_if_index %d via:",
20377          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20378   fp = mp->mt_paths;
20379   for (i = 0; i < count; i++)
20380     {
20381       vl_api_mpls_fib_path_print (vam, fp);
20382       fp++;
20383     }
20384
20385   print (vam->ofp, "");
20386 }
20387
20388 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20389 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20390
20391 static void
20392 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20393 {
20394   vat_main_t *vam = &vat_main;
20395   vat_json_node_t *node = NULL;
20396   int count = ntohl (mp->mt_count);
20397   vl_api_fib_path_t *fp;
20398   i32 i;
20399
20400   if (VAT_JSON_ARRAY != vam->json_tree.type)
20401     {
20402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20403       vat_json_init_array (&vam->json_tree);
20404     }
20405   node = vat_json_array_add (&vam->json_tree);
20406
20407   vat_json_init_object (node);
20408   vat_json_object_add_uint (node, "tunnel_index",
20409                             ntohl (mp->mt_tunnel_index));
20410   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20411
20412   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20413
20414   fp = mp->mt_paths;
20415   for (i = 0; i < count; i++)
20416     {
20417       vl_api_mpls_fib_path_json_print (node, fp);
20418       fp++;
20419     }
20420 }
20421
20422 static int
20423 api_mpls_tunnel_dump (vat_main_t * vam)
20424 {
20425   vl_api_mpls_tunnel_dump_t *mp;
20426   vl_api_control_ping_t *mp_ping;
20427   u32 sw_if_index = ~0;
20428   int ret;
20429
20430   /* Parse args required to build the message */
20431   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20432     {
20433       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20434         ;
20435     }
20436
20437   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20438
20439   M (MPLS_TUNNEL_DUMP, mp);
20440   mp->sw_if_index = htonl (sw_if_index);
20441   S (mp);
20442
20443   /* Use a control ping for synchronization */
20444   MPING (CONTROL_PING, mp_ping);
20445   S (mp_ping);
20446
20447   W (ret);
20448   return ret;
20449 }
20450
20451 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20452 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20453
20454
20455 static void
20456 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20457 {
20458   vat_main_t *vam = &vat_main;
20459   int count = ntohl (mp->count);
20460   vl_api_fib_path_t *fp;
20461   int i;
20462
20463   print (vam->ofp,
20464          "table-id %d, label %u, ess_bit %u",
20465          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20466   fp = mp->path;
20467   for (i = 0; i < count; i++)
20468     {
20469       vl_api_mpls_fib_path_print (vam, fp);
20470       fp++;
20471     }
20472 }
20473
20474 static void vl_api_mpls_fib_details_t_handler_json
20475   (vl_api_mpls_fib_details_t * mp)
20476 {
20477   vat_main_t *vam = &vat_main;
20478   int count = ntohl (mp->count);
20479   vat_json_node_t *node = NULL;
20480   vl_api_fib_path_t *fp;
20481   int i;
20482
20483   if (VAT_JSON_ARRAY != vam->json_tree.type)
20484     {
20485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20486       vat_json_init_array (&vam->json_tree);
20487     }
20488   node = vat_json_array_add (&vam->json_tree);
20489
20490   vat_json_init_object (node);
20491   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20492   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20493   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20494   vat_json_object_add_uint (node, "path_count", count);
20495   fp = mp->path;
20496   for (i = 0; i < count; i++)
20497     {
20498       vl_api_mpls_fib_path_json_print (node, fp);
20499       fp++;
20500     }
20501 }
20502
20503 static int
20504 api_mpls_fib_dump (vat_main_t * vam)
20505 {
20506   vl_api_mpls_fib_dump_t *mp;
20507   vl_api_control_ping_t *mp_ping;
20508   int ret;
20509
20510   M (MPLS_FIB_DUMP, mp);
20511   S (mp);
20512
20513   /* Use a control ping for synchronization */
20514   MPING (CONTROL_PING, mp_ping);
20515   S (mp_ping);
20516
20517   W (ret);
20518   return ret;
20519 }
20520
20521 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20522 #define vl_api_ip_fib_details_t_print vl_noop_handler
20523
20524 static void
20525 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20526 {
20527   vat_main_t *vam = &vat_main;
20528   int count = ntohl (mp->count);
20529   vl_api_fib_path_t *fp;
20530   int i;
20531
20532   print (vam->ofp,
20533          "table-id %d, prefix %U/%d stats-index %d",
20534          ntohl (mp->table_id), format_ip4_address, mp->address,
20535          mp->address_length, ntohl (mp->stats_index));
20536   fp = mp->path;
20537   for (i = 0; i < count; i++)
20538     {
20539       if (fp->afi == IP46_TYPE_IP6)
20540         print (vam->ofp,
20541                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20542                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20543                "next_hop_table %d",
20544                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20545                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20546                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20547       else if (fp->afi == IP46_TYPE_IP4)
20548         print (vam->ofp,
20549                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20550                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20551                "next_hop_table %d",
20552                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20553                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20554                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20555       fp++;
20556     }
20557 }
20558
20559 static void vl_api_ip_fib_details_t_handler_json
20560   (vl_api_ip_fib_details_t * mp)
20561 {
20562   vat_main_t *vam = &vat_main;
20563   int count = ntohl (mp->count);
20564   vat_json_node_t *node = NULL;
20565   struct in_addr ip4;
20566   struct in6_addr ip6;
20567   vl_api_fib_path_t *fp;
20568   int i;
20569
20570   if (VAT_JSON_ARRAY != vam->json_tree.type)
20571     {
20572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20573       vat_json_init_array (&vam->json_tree);
20574     }
20575   node = vat_json_array_add (&vam->json_tree);
20576
20577   vat_json_init_object (node);
20578   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20579   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20580   vat_json_object_add_ip4 (node, "prefix", ip4);
20581   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20582   vat_json_object_add_uint (node, "path_count", count);
20583   fp = mp->path;
20584   for (i = 0; i < count; i++)
20585     {
20586       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20587       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20588       vat_json_object_add_uint (node, "is_local", fp->is_local);
20589       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20590       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20591       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20592       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20593       if (fp->afi == IP46_TYPE_IP4)
20594         {
20595           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20596           vat_json_object_add_ip4 (node, "next_hop", ip4);
20597         }
20598       else if (fp->afi == IP46_TYPE_IP6)
20599         {
20600           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20601           vat_json_object_add_ip6 (node, "next_hop", ip6);
20602         }
20603     }
20604 }
20605
20606 static int
20607 api_ip_fib_dump (vat_main_t * vam)
20608 {
20609   vl_api_ip_fib_dump_t *mp;
20610   vl_api_control_ping_t *mp_ping;
20611   int ret;
20612
20613   M (IP_FIB_DUMP, mp);
20614   S (mp);
20615
20616   /* Use a control ping for synchronization */
20617   MPING (CONTROL_PING, mp_ping);
20618   S (mp_ping);
20619
20620   W (ret);
20621   return ret;
20622 }
20623
20624 static int
20625 api_ip_mfib_dump (vat_main_t * vam)
20626 {
20627   vl_api_ip_mfib_dump_t *mp;
20628   vl_api_control_ping_t *mp_ping;
20629   int ret;
20630
20631   M (IP_MFIB_DUMP, mp);
20632   S (mp);
20633
20634   /* Use a control ping for synchronization */
20635   MPING (CONTROL_PING, mp_ping);
20636   S (mp_ping);
20637
20638   W (ret);
20639   return ret;
20640 }
20641
20642 static void vl_api_ip_neighbor_details_t_handler
20643   (vl_api_ip_neighbor_details_t * mp)
20644 {
20645   vat_main_t *vam = &vat_main;
20646
20647   print (vam->ofp, "%c %U %U",
20648          (mp->is_static) ? 'S' : 'D',
20649          format_ethernet_address, &mp->mac_address,
20650          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20651          &mp->ip_address);
20652 }
20653
20654 static void vl_api_ip_neighbor_details_t_handler_json
20655   (vl_api_ip_neighbor_details_t * mp)
20656 {
20657
20658   vat_main_t *vam = &vat_main;
20659   vat_json_node_t *node;
20660   struct in_addr ip4;
20661   struct in6_addr ip6;
20662
20663   if (VAT_JSON_ARRAY != vam->json_tree.type)
20664     {
20665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20666       vat_json_init_array (&vam->json_tree);
20667     }
20668   node = vat_json_array_add (&vam->json_tree);
20669
20670   vat_json_init_object (node);
20671   vat_json_object_add_string_copy (node, "flag",
20672                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20673                                    "dynamic");
20674
20675   vat_json_object_add_string_copy (node, "link_layer",
20676                                    format (0, "%U", format_ethernet_address,
20677                                            &mp->mac_address));
20678
20679   if (mp->is_ipv6)
20680     {
20681       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20682       vat_json_object_add_ip6 (node, "ip_address", ip6);
20683     }
20684   else
20685     {
20686       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20687       vat_json_object_add_ip4 (node, "ip_address", ip4);
20688     }
20689 }
20690
20691 static int
20692 api_ip_neighbor_dump (vat_main_t * vam)
20693 {
20694   unformat_input_t *i = vam->input;
20695   vl_api_ip_neighbor_dump_t *mp;
20696   vl_api_control_ping_t *mp_ping;
20697   u8 is_ipv6 = 0;
20698   u32 sw_if_index = ~0;
20699   int ret;
20700
20701   /* Parse args required to build the message */
20702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20703     {
20704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20705         ;
20706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20707         ;
20708       else if (unformat (i, "ip6"))
20709         is_ipv6 = 1;
20710       else
20711         break;
20712     }
20713
20714   if (sw_if_index == ~0)
20715     {
20716       errmsg ("missing interface name or sw_if_index");
20717       return -99;
20718     }
20719
20720   M (IP_NEIGHBOR_DUMP, mp);
20721   mp->is_ipv6 = (u8) is_ipv6;
20722   mp->sw_if_index = ntohl (sw_if_index);
20723   S (mp);
20724
20725   /* Use a control ping for synchronization */
20726   MPING (CONTROL_PING, mp_ping);
20727   S (mp_ping);
20728
20729   W (ret);
20730   return ret;
20731 }
20732
20733 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20734 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20735
20736 static void
20737 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20738 {
20739   vat_main_t *vam = &vat_main;
20740   int count = ntohl (mp->count);
20741   vl_api_fib_path_t *fp;
20742   int i;
20743
20744   print (vam->ofp,
20745          "table-id %d, prefix %U/%d stats-index %d",
20746          ntohl (mp->table_id), format_ip6_address, mp->address,
20747          mp->address_length, ntohl (mp->stats_index));
20748   fp = mp->path;
20749   for (i = 0; i < count; i++)
20750     {
20751       if (fp->afi == IP46_TYPE_IP6)
20752         print (vam->ofp,
20753                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20754                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20755                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20756                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20757                format_ip6_address, fp->next_hop);
20758       else if (fp->afi == IP46_TYPE_IP4)
20759         print (vam->ofp,
20760                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20761                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20762                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20763                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20764                format_ip4_address, fp->next_hop);
20765       fp++;
20766     }
20767 }
20768
20769 static void vl_api_ip6_fib_details_t_handler_json
20770   (vl_api_ip6_fib_details_t * mp)
20771 {
20772   vat_main_t *vam = &vat_main;
20773   int count = ntohl (mp->count);
20774   vat_json_node_t *node = NULL;
20775   struct in_addr ip4;
20776   struct in6_addr ip6;
20777   vl_api_fib_path_t *fp;
20778   int i;
20779
20780   if (VAT_JSON_ARRAY != vam->json_tree.type)
20781     {
20782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20783       vat_json_init_array (&vam->json_tree);
20784     }
20785   node = vat_json_array_add (&vam->json_tree);
20786
20787   vat_json_init_object (node);
20788   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20789   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20790   vat_json_object_add_ip6 (node, "prefix", ip6);
20791   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20792   vat_json_object_add_uint (node, "path_count", count);
20793   fp = mp->path;
20794   for (i = 0; i < count; i++)
20795     {
20796       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20797       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20798       vat_json_object_add_uint (node, "is_local", fp->is_local);
20799       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20800       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20801       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20802       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20803       if (fp->afi == IP46_TYPE_IP4)
20804         {
20805           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20806           vat_json_object_add_ip4 (node, "next_hop", ip4);
20807         }
20808       else if (fp->afi == IP46_TYPE_IP6)
20809         {
20810           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20811           vat_json_object_add_ip6 (node, "next_hop", ip6);
20812         }
20813     }
20814 }
20815
20816 static int
20817 api_ip6_fib_dump (vat_main_t * vam)
20818 {
20819   vl_api_ip6_fib_dump_t *mp;
20820   vl_api_control_ping_t *mp_ping;
20821   int ret;
20822
20823   M (IP6_FIB_DUMP, mp);
20824   S (mp);
20825
20826   /* Use a control ping for synchronization */
20827   MPING (CONTROL_PING, mp_ping);
20828   S (mp_ping);
20829
20830   W (ret);
20831   return ret;
20832 }
20833
20834 static int
20835 api_ip6_mfib_dump (vat_main_t * vam)
20836 {
20837   vl_api_ip6_mfib_dump_t *mp;
20838   vl_api_control_ping_t *mp_ping;
20839   int ret;
20840
20841   M (IP6_MFIB_DUMP, mp);
20842   S (mp);
20843
20844   /* Use a control ping for synchronization */
20845   MPING (CONTROL_PING, mp_ping);
20846   S (mp_ping);
20847
20848   W (ret);
20849   return ret;
20850 }
20851
20852 int
20853 api_classify_table_ids (vat_main_t * vam)
20854 {
20855   vl_api_classify_table_ids_t *mp;
20856   int ret;
20857
20858   /* Construct the API message */
20859   M (CLASSIFY_TABLE_IDS, mp);
20860   mp->context = 0;
20861
20862   S (mp);
20863   W (ret);
20864   return ret;
20865 }
20866
20867 int
20868 api_classify_table_by_interface (vat_main_t * vam)
20869 {
20870   unformat_input_t *input = vam->input;
20871   vl_api_classify_table_by_interface_t *mp;
20872
20873   u32 sw_if_index = ~0;
20874   int ret;
20875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20876     {
20877       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20878         ;
20879       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20880         ;
20881       else
20882         break;
20883     }
20884   if (sw_if_index == ~0)
20885     {
20886       errmsg ("missing interface name or sw_if_index");
20887       return -99;
20888     }
20889
20890   /* Construct the API message */
20891   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20892   mp->context = 0;
20893   mp->sw_if_index = ntohl (sw_if_index);
20894
20895   S (mp);
20896   W (ret);
20897   return ret;
20898 }
20899
20900 int
20901 api_classify_table_info (vat_main_t * vam)
20902 {
20903   unformat_input_t *input = vam->input;
20904   vl_api_classify_table_info_t *mp;
20905
20906   u32 table_id = ~0;
20907   int ret;
20908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20909     {
20910       if (unformat (input, "table_id %d", &table_id))
20911         ;
20912       else
20913         break;
20914     }
20915   if (table_id == ~0)
20916     {
20917       errmsg ("missing table id");
20918       return -99;
20919     }
20920
20921   /* Construct the API message */
20922   M (CLASSIFY_TABLE_INFO, mp);
20923   mp->context = 0;
20924   mp->table_id = ntohl (table_id);
20925
20926   S (mp);
20927   W (ret);
20928   return ret;
20929 }
20930
20931 int
20932 api_classify_session_dump (vat_main_t * vam)
20933 {
20934   unformat_input_t *input = vam->input;
20935   vl_api_classify_session_dump_t *mp;
20936   vl_api_control_ping_t *mp_ping;
20937
20938   u32 table_id = ~0;
20939   int ret;
20940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20941     {
20942       if (unformat (input, "table_id %d", &table_id))
20943         ;
20944       else
20945         break;
20946     }
20947   if (table_id == ~0)
20948     {
20949       errmsg ("missing table id");
20950       return -99;
20951     }
20952
20953   /* Construct the API message */
20954   M (CLASSIFY_SESSION_DUMP, mp);
20955   mp->context = 0;
20956   mp->table_id = ntohl (table_id);
20957   S (mp);
20958
20959   /* Use a control ping for synchronization */
20960   MPING (CONTROL_PING, mp_ping);
20961   S (mp_ping);
20962
20963   W (ret);
20964   return ret;
20965 }
20966
20967 static void
20968 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20969 {
20970   vat_main_t *vam = &vat_main;
20971
20972   print (vam->ofp, "collector_address %U, collector_port %d, "
20973          "src_address %U, vrf_id %d, path_mtu %u, "
20974          "template_interval %u, udp_checksum %d",
20975          format_ip4_address, mp->collector_address,
20976          ntohs (mp->collector_port),
20977          format_ip4_address, mp->src_address,
20978          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20979          ntohl (mp->template_interval), mp->udp_checksum);
20980
20981   vam->retval = 0;
20982   vam->result_ready = 1;
20983 }
20984
20985 static void
20986   vl_api_ipfix_exporter_details_t_handler_json
20987   (vl_api_ipfix_exporter_details_t * mp)
20988 {
20989   vat_main_t *vam = &vat_main;
20990   vat_json_node_t node;
20991   struct in_addr collector_address;
20992   struct in_addr src_address;
20993
20994   vat_json_init_object (&node);
20995   clib_memcpy (&collector_address, &mp->collector_address,
20996                sizeof (collector_address));
20997   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20998   vat_json_object_add_uint (&node, "collector_port",
20999                             ntohs (mp->collector_port));
21000   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21001   vat_json_object_add_ip4 (&node, "src_address", src_address);
21002   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21003   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21004   vat_json_object_add_uint (&node, "template_interval",
21005                             ntohl (mp->template_interval));
21006   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21007
21008   vat_json_print (vam->ofp, &node);
21009   vat_json_free (&node);
21010   vam->retval = 0;
21011   vam->result_ready = 1;
21012 }
21013
21014 int
21015 api_ipfix_exporter_dump (vat_main_t * vam)
21016 {
21017   vl_api_ipfix_exporter_dump_t *mp;
21018   int ret;
21019
21020   /* Construct the API message */
21021   M (IPFIX_EXPORTER_DUMP, mp);
21022   mp->context = 0;
21023
21024   S (mp);
21025   W (ret);
21026   return ret;
21027 }
21028
21029 static int
21030 api_ipfix_classify_stream_dump (vat_main_t * vam)
21031 {
21032   vl_api_ipfix_classify_stream_dump_t *mp;
21033   int ret;
21034
21035   /* Construct the API message */
21036   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21037   mp->context = 0;
21038
21039   S (mp);
21040   W (ret);
21041   return ret;
21042   /* NOTREACHED */
21043   return 0;
21044 }
21045
21046 static void
21047   vl_api_ipfix_classify_stream_details_t_handler
21048   (vl_api_ipfix_classify_stream_details_t * mp)
21049 {
21050   vat_main_t *vam = &vat_main;
21051   print (vam->ofp, "domain_id %d, src_port %d",
21052          ntohl (mp->domain_id), ntohs (mp->src_port));
21053   vam->retval = 0;
21054   vam->result_ready = 1;
21055 }
21056
21057 static void
21058   vl_api_ipfix_classify_stream_details_t_handler_json
21059   (vl_api_ipfix_classify_stream_details_t * mp)
21060 {
21061   vat_main_t *vam = &vat_main;
21062   vat_json_node_t node;
21063
21064   vat_json_init_object (&node);
21065   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21066   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21067
21068   vat_json_print (vam->ofp, &node);
21069   vat_json_free (&node);
21070   vam->retval = 0;
21071   vam->result_ready = 1;
21072 }
21073
21074 static int
21075 api_ipfix_classify_table_dump (vat_main_t * vam)
21076 {
21077   vl_api_ipfix_classify_table_dump_t *mp;
21078   vl_api_control_ping_t *mp_ping;
21079   int ret;
21080
21081   if (!vam->json_output)
21082     {
21083       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21084              "transport_protocol");
21085     }
21086
21087   /* Construct the API message */
21088   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21089
21090   /* send it... */
21091   S (mp);
21092
21093   /* Use a control ping for synchronization */
21094   MPING (CONTROL_PING, mp_ping);
21095   S (mp_ping);
21096
21097   W (ret);
21098   return ret;
21099 }
21100
21101 static void
21102   vl_api_ipfix_classify_table_details_t_handler
21103   (vl_api_ipfix_classify_table_details_t * mp)
21104 {
21105   vat_main_t *vam = &vat_main;
21106   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21107          mp->transport_protocol);
21108 }
21109
21110 static void
21111   vl_api_ipfix_classify_table_details_t_handler_json
21112   (vl_api_ipfix_classify_table_details_t * mp)
21113 {
21114   vat_json_node_t *node = NULL;
21115   vat_main_t *vam = &vat_main;
21116
21117   if (VAT_JSON_ARRAY != vam->json_tree.type)
21118     {
21119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21120       vat_json_init_array (&vam->json_tree);
21121     }
21122
21123   node = vat_json_array_add (&vam->json_tree);
21124   vat_json_init_object (node);
21125
21126   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21127   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21128   vat_json_object_add_uint (node, "transport_protocol",
21129                             mp->transport_protocol);
21130 }
21131
21132 static int
21133 api_sw_interface_span_enable_disable (vat_main_t * vam)
21134 {
21135   unformat_input_t *i = vam->input;
21136   vl_api_sw_interface_span_enable_disable_t *mp;
21137   u32 src_sw_if_index = ~0;
21138   u32 dst_sw_if_index = ~0;
21139   u8 state = 3;
21140   int ret;
21141   u8 is_l2 = 0;
21142
21143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21144     {
21145       if (unformat
21146           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21147         ;
21148       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21149         ;
21150       else
21151         if (unformat
21152             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21153         ;
21154       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21155         ;
21156       else if (unformat (i, "disable"))
21157         state = 0;
21158       else if (unformat (i, "rx"))
21159         state = 1;
21160       else if (unformat (i, "tx"))
21161         state = 2;
21162       else if (unformat (i, "both"))
21163         state = 3;
21164       else if (unformat (i, "l2"))
21165         is_l2 = 1;
21166       else
21167         break;
21168     }
21169
21170   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21171
21172   mp->sw_if_index_from = htonl (src_sw_if_index);
21173   mp->sw_if_index_to = htonl (dst_sw_if_index);
21174   mp->state = state;
21175   mp->is_l2 = is_l2;
21176
21177   S (mp);
21178   W (ret);
21179   return ret;
21180 }
21181
21182 static void
21183 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21184                                             * mp)
21185 {
21186   vat_main_t *vam = &vat_main;
21187   u8 *sw_if_from_name = 0;
21188   u8 *sw_if_to_name = 0;
21189   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21190   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21191   char *states[] = { "none", "rx", "tx", "both" };
21192   hash_pair_t *p;
21193
21194   /* *INDENT-OFF* */
21195   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21196   ({
21197     if ((u32) p->value[0] == sw_if_index_from)
21198       {
21199         sw_if_from_name = (u8 *)(p->key);
21200         if (sw_if_to_name)
21201           break;
21202       }
21203     if ((u32) p->value[0] == sw_if_index_to)
21204       {
21205         sw_if_to_name = (u8 *)(p->key);
21206         if (sw_if_from_name)
21207           break;
21208       }
21209   }));
21210   /* *INDENT-ON* */
21211   print (vam->ofp, "%20s => %20s (%s) %s",
21212          sw_if_from_name, sw_if_to_name, states[mp->state],
21213          mp->is_l2 ? "l2" : "device");
21214 }
21215
21216 static void
21217   vl_api_sw_interface_span_details_t_handler_json
21218   (vl_api_sw_interface_span_details_t * mp)
21219 {
21220   vat_main_t *vam = &vat_main;
21221   vat_json_node_t *node = NULL;
21222   u8 *sw_if_from_name = 0;
21223   u8 *sw_if_to_name = 0;
21224   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21225   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21226   hash_pair_t *p;
21227
21228   /* *INDENT-OFF* */
21229   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21230   ({
21231     if ((u32) p->value[0] == sw_if_index_from)
21232       {
21233         sw_if_from_name = (u8 *)(p->key);
21234         if (sw_if_to_name)
21235           break;
21236       }
21237     if ((u32) p->value[0] == sw_if_index_to)
21238       {
21239         sw_if_to_name = (u8 *)(p->key);
21240         if (sw_if_from_name)
21241           break;
21242       }
21243   }));
21244   /* *INDENT-ON* */
21245
21246   if (VAT_JSON_ARRAY != vam->json_tree.type)
21247     {
21248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21249       vat_json_init_array (&vam->json_tree);
21250     }
21251   node = vat_json_array_add (&vam->json_tree);
21252
21253   vat_json_init_object (node);
21254   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21255   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21256   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21257   if (0 != sw_if_to_name)
21258     {
21259       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21260     }
21261   vat_json_object_add_uint (node, "state", mp->state);
21262   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21263 }
21264
21265 static int
21266 api_sw_interface_span_dump (vat_main_t * vam)
21267 {
21268   unformat_input_t *input = vam->input;
21269   vl_api_sw_interface_span_dump_t *mp;
21270   vl_api_control_ping_t *mp_ping;
21271   u8 is_l2 = 0;
21272   int ret;
21273
21274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21275     {
21276       if (unformat (input, "l2"))
21277         is_l2 = 1;
21278       else
21279         break;
21280     }
21281
21282   M (SW_INTERFACE_SPAN_DUMP, mp);
21283   mp->is_l2 = is_l2;
21284   S (mp);
21285
21286   /* Use a control ping for synchronization */
21287   MPING (CONTROL_PING, mp_ping);
21288   S (mp_ping);
21289
21290   W (ret);
21291   return ret;
21292 }
21293
21294 int
21295 api_pg_create_interface (vat_main_t * vam)
21296 {
21297   unformat_input_t *input = vam->input;
21298   vl_api_pg_create_interface_t *mp;
21299
21300   u32 if_id = ~0;
21301   int ret;
21302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21303     {
21304       if (unformat (input, "if_id %d", &if_id))
21305         ;
21306       else
21307         break;
21308     }
21309   if (if_id == ~0)
21310     {
21311       errmsg ("missing pg interface index");
21312       return -99;
21313     }
21314
21315   /* Construct the API message */
21316   M (PG_CREATE_INTERFACE, mp);
21317   mp->context = 0;
21318   mp->interface_id = ntohl (if_id);
21319
21320   S (mp);
21321   W (ret);
21322   return ret;
21323 }
21324
21325 int
21326 api_pg_capture (vat_main_t * vam)
21327 {
21328   unformat_input_t *input = vam->input;
21329   vl_api_pg_capture_t *mp;
21330
21331   u32 if_id = ~0;
21332   u8 enable = 1;
21333   u32 count = 1;
21334   u8 pcap_file_set = 0;
21335   u8 *pcap_file = 0;
21336   int ret;
21337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21338     {
21339       if (unformat (input, "if_id %d", &if_id))
21340         ;
21341       else if (unformat (input, "pcap %s", &pcap_file))
21342         pcap_file_set = 1;
21343       else if (unformat (input, "count %d", &count))
21344         ;
21345       else if (unformat (input, "disable"))
21346         enable = 0;
21347       else
21348         break;
21349     }
21350   if (if_id == ~0)
21351     {
21352       errmsg ("missing pg interface index");
21353       return -99;
21354     }
21355   if (pcap_file_set > 0)
21356     {
21357       if (vec_len (pcap_file) > 255)
21358         {
21359           errmsg ("pcap file name is too long");
21360           return -99;
21361         }
21362     }
21363
21364   u32 name_len = vec_len (pcap_file);
21365   /* Construct the API message */
21366   M (PG_CAPTURE, mp);
21367   mp->context = 0;
21368   mp->interface_id = ntohl (if_id);
21369   mp->is_enabled = enable;
21370   mp->count = ntohl (count);
21371   mp->pcap_name_length = ntohl (name_len);
21372   if (pcap_file_set != 0)
21373     {
21374       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21375     }
21376   vec_free (pcap_file);
21377
21378   S (mp);
21379   W (ret);
21380   return ret;
21381 }
21382
21383 int
21384 api_pg_enable_disable (vat_main_t * vam)
21385 {
21386   unformat_input_t *input = vam->input;
21387   vl_api_pg_enable_disable_t *mp;
21388
21389   u8 enable = 1;
21390   u8 stream_name_set = 0;
21391   u8 *stream_name = 0;
21392   int ret;
21393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21394     {
21395       if (unformat (input, "stream %s", &stream_name))
21396         stream_name_set = 1;
21397       else if (unformat (input, "disable"))
21398         enable = 0;
21399       else
21400         break;
21401     }
21402
21403   if (stream_name_set > 0)
21404     {
21405       if (vec_len (stream_name) > 255)
21406         {
21407           errmsg ("stream name too long");
21408           return -99;
21409         }
21410     }
21411
21412   u32 name_len = vec_len (stream_name);
21413   /* Construct the API message */
21414   M (PG_ENABLE_DISABLE, mp);
21415   mp->context = 0;
21416   mp->is_enabled = enable;
21417   if (stream_name_set != 0)
21418     {
21419       mp->stream_name_length = ntohl (name_len);
21420       clib_memcpy (mp->stream_name, stream_name, name_len);
21421     }
21422   vec_free (stream_name);
21423
21424   S (mp);
21425   W (ret);
21426   return ret;
21427 }
21428
21429 int
21430 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21431 {
21432   unformat_input_t *input = vam->input;
21433   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21434
21435   u16 *low_ports = 0;
21436   u16 *high_ports = 0;
21437   u16 this_low;
21438   u16 this_hi;
21439   ip4_address_t ip4_addr;
21440   ip6_address_t ip6_addr;
21441   u32 length;
21442   u32 tmp, tmp2;
21443   u8 prefix_set = 0;
21444   u32 vrf_id = ~0;
21445   u8 is_add = 1;
21446   u8 is_ipv6 = 0;
21447   int ret;
21448
21449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21450     {
21451       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21452         {
21453           prefix_set = 1;
21454         }
21455       else
21456         if (unformat
21457             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21458         {
21459           prefix_set = 1;
21460           is_ipv6 = 1;
21461         }
21462       else if (unformat (input, "vrf %d", &vrf_id))
21463         ;
21464       else if (unformat (input, "del"))
21465         is_add = 0;
21466       else if (unformat (input, "port %d", &tmp))
21467         {
21468           if (tmp == 0 || tmp > 65535)
21469             {
21470               errmsg ("port %d out of range", tmp);
21471               return -99;
21472             }
21473           this_low = tmp;
21474           this_hi = this_low + 1;
21475           vec_add1 (low_ports, this_low);
21476           vec_add1 (high_ports, this_hi);
21477         }
21478       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21479         {
21480           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21481             {
21482               errmsg ("incorrect range parameters");
21483               return -99;
21484             }
21485           this_low = tmp;
21486           /* Note: in debug CLI +1 is added to high before
21487              passing to real fn that does "the work"
21488              (ip_source_and_port_range_check_add_del).
21489              This fn is a wrapper around the binary API fn a
21490              control plane will call, which expects this increment
21491              to have occurred. Hence letting the binary API control
21492              plane fn do the increment for consistency between VAT
21493              and other control planes.
21494            */
21495           this_hi = tmp2;
21496           vec_add1 (low_ports, this_low);
21497           vec_add1 (high_ports, this_hi);
21498         }
21499       else
21500         break;
21501     }
21502
21503   if (prefix_set == 0)
21504     {
21505       errmsg ("<address>/<mask> not specified");
21506       return -99;
21507     }
21508
21509   if (vrf_id == ~0)
21510     {
21511       errmsg ("VRF ID required, not specified");
21512       return -99;
21513     }
21514
21515   if (vrf_id == 0)
21516     {
21517       errmsg
21518         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21519       return -99;
21520     }
21521
21522   if (vec_len (low_ports) == 0)
21523     {
21524       errmsg ("At least one port or port range required");
21525       return -99;
21526     }
21527
21528   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21529
21530   mp->is_add = is_add;
21531
21532   if (is_ipv6)
21533     {
21534       mp->is_ipv6 = 1;
21535       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21536     }
21537   else
21538     {
21539       mp->is_ipv6 = 0;
21540       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21541     }
21542
21543   mp->mask_length = length;
21544   mp->number_of_ranges = vec_len (low_ports);
21545
21546   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21547   vec_free (low_ports);
21548
21549   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21550   vec_free (high_ports);
21551
21552   mp->vrf_id = ntohl (vrf_id);
21553
21554   S (mp);
21555   W (ret);
21556   return ret;
21557 }
21558
21559 int
21560 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21561 {
21562   unformat_input_t *input = vam->input;
21563   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21564   u32 sw_if_index = ~0;
21565   int vrf_set = 0;
21566   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21567   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21568   u8 is_add = 1;
21569   int ret;
21570
21571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21572     {
21573       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21574         ;
21575       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21576         ;
21577       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21578         vrf_set = 1;
21579       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21580         vrf_set = 1;
21581       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21582         vrf_set = 1;
21583       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21584         vrf_set = 1;
21585       else if (unformat (input, "del"))
21586         is_add = 0;
21587       else
21588         break;
21589     }
21590
21591   if (sw_if_index == ~0)
21592     {
21593       errmsg ("Interface required but not specified");
21594       return -99;
21595     }
21596
21597   if (vrf_set == 0)
21598     {
21599       errmsg ("VRF ID required but not specified");
21600       return -99;
21601     }
21602
21603   if (tcp_out_vrf_id == 0
21604       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21605     {
21606       errmsg
21607         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21608       return -99;
21609     }
21610
21611   /* Construct the API message */
21612   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21613
21614   mp->sw_if_index = ntohl (sw_if_index);
21615   mp->is_add = is_add;
21616   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21617   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21618   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21619   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21620
21621   /* send it... */
21622   S (mp);
21623
21624   /* Wait for a reply... */
21625   W (ret);
21626   return ret;
21627 }
21628
21629 static int
21630 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21631 {
21632   unformat_input_t *i = vam->input;
21633   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21634   u32 local_sa_id = 0;
21635   u32 remote_sa_id = 0;
21636   ip4_address_t src_address;
21637   ip4_address_t dst_address;
21638   u8 is_add = 1;
21639   int ret;
21640
21641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21642     {
21643       if (unformat (i, "local_sa %d", &local_sa_id))
21644         ;
21645       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21646         ;
21647       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21648         ;
21649       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21650         ;
21651       else if (unformat (i, "del"))
21652         is_add = 0;
21653       else
21654         {
21655           clib_warning ("parse error '%U'", format_unformat_error, i);
21656           return -99;
21657         }
21658     }
21659
21660   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21661
21662   mp->local_sa_id = ntohl (local_sa_id);
21663   mp->remote_sa_id = ntohl (remote_sa_id);
21664   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21665   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21666   mp->is_add = is_add;
21667
21668   S (mp);
21669   W (ret);
21670   return ret;
21671 }
21672
21673 static int
21674 api_punt (vat_main_t * vam)
21675 {
21676   unformat_input_t *i = vam->input;
21677   vl_api_punt_t *mp;
21678   u32 ipv = ~0;
21679   u32 protocol = ~0;
21680   u32 port = ~0;
21681   int is_add = 1;
21682   int ret;
21683
21684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21685     {
21686       if (unformat (i, "ip %d", &ipv))
21687         ;
21688       else if (unformat (i, "protocol %d", &protocol))
21689         ;
21690       else if (unformat (i, "port %d", &port))
21691         ;
21692       else if (unformat (i, "del"))
21693         is_add = 0;
21694       else
21695         {
21696           clib_warning ("parse error '%U'", format_unformat_error, i);
21697           return -99;
21698         }
21699     }
21700
21701   M (PUNT, mp);
21702
21703   mp->is_add = (u8) is_add;
21704   mp->ipv = (u8) ipv;
21705   mp->l4_protocol = (u8) protocol;
21706   mp->l4_port = htons ((u16) port);
21707
21708   S (mp);
21709   W (ret);
21710   return ret;
21711 }
21712
21713 static void vl_api_ipsec_gre_tunnel_details_t_handler
21714   (vl_api_ipsec_gre_tunnel_details_t * mp)
21715 {
21716   vat_main_t *vam = &vat_main;
21717
21718   print (vam->ofp, "%11d%15U%15U%14d%14d",
21719          ntohl (mp->sw_if_index),
21720          format_ip4_address, &mp->src_address,
21721          format_ip4_address, &mp->dst_address,
21722          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21723 }
21724
21725 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21726   (vl_api_ipsec_gre_tunnel_details_t * mp)
21727 {
21728   vat_main_t *vam = &vat_main;
21729   vat_json_node_t *node = NULL;
21730   struct in_addr ip4;
21731
21732   if (VAT_JSON_ARRAY != vam->json_tree.type)
21733     {
21734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21735       vat_json_init_array (&vam->json_tree);
21736     }
21737   node = vat_json_array_add (&vam->json_tree);
21738
21739   vat_json_init_object (node);
21740   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21741   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21742   vat_json_object_add_ip4 (node, "src_address", ip4);
21743   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21744   vat_json_object_add_ip4 (node, "dst_address", ip4);
21745   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21746   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21747 }
21748
21749 static int
21750 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21751 {
21752   unformat_input_t *i = vam->input;
21753   vl_api_ipsec_gre_tunnel_dump_t *mp;
21754   vl_api_control_ping_t *mp_ping;
21755   u32 sw_if_index;
21756   u8 sw_if_index_set = 0;
21757   int ret;
21758
21759   /* Parse args required to build the message */
21760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21761     {
21762       if (unformat (i, "sw_if_index %d", &sw_if_index))
21763         sw_if_index_set = 1;
21764       else
21765         break;
21766     }
21767
21768   if (sw_if_index_set == 0)
21769     {
21770       sw_if_index = ~0;
21771     }
21772
21773   if (!vam->json_output)
21774     {
21775       print (vam->ofp, "%11s%15s%15s%14s%14s",
21776              "sw_if_index", "src_address", "dst_address",
21777              "local_sa_id", "remote_sa_id");
21778     }
21779
21780   /* Get list of gre-tunnel interfaces */
21781   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21782
21783   mp->sw_if_index = htonl (sw_if_index);
21784
21785   S (mp);
21786
21787   /* Use a control ping for synchronization */
21788   MPING (CONTROL_PING, mp_ping);
21789   S (mp_ping);
21790
21791   W (ret);
21792   return ret;
21793 }
21794
21795 static int
21796 api_delete_subif (vat_main_t * vam)
21797 {
21798   unformat_input_t *i = vam->input;
21799   vl_api_delete_subif_t *mp;
21800   u32 sw_if_index = ~0;
21801   int ret;
21802
21803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21804     {
21805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21806         ;
21807       if (unformat (i, "sw_if_index %d", &sw_if_index))
21808         ;
21809       else
21810         break;
21811     }
21812
21813   if (sw_if_index == ~0)
21814     {
21815       errmsg ("missing sw_if_index");
21816       return -99;
21817     }
21818
21819   /* Construct the API message */
21820   M (DELETE_SUBIF, mp);
21821   mp->sw_if_index = ntohl (sw_if_index);
21822
21823   S (mp);
21824   W (ret);
21825   return ret;
21826 }
21827
21828 #define foreach_pbb_vtr_op      \
21829 _("disable",  L2_VTR_DISABLED)  \
21830 _("pop",  L2_VTR_POP_2)         \
21831 _("push",  L2_VTR_PUSH_2)
21832
21833 static int
21834 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21835 {
21836   unformat_input_t *i = vam->input;
21837   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21838   u32 sw_if_index = ~0, vtr_op = ~0;
21839   u16 outer_tag = ~0;
21840   u8 dmac[6], smac[6];
21841   u8 dmac_set = 0, smac_set = 0;
21842   u16 vlanid = 0;
21843   u32 sid = ~0;
21844   u32 tmp;
21845   int ret;
21846
21847   /* Shut up coverity */
21848   memset (dmac, 0, sizeof (dmac));
21849   memset (smac, 0, sizeof (smac));
21850
21851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21852     {
21853       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21854         ;
21855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21856         ;
21857       else if (unformat (i, "vtr_op %d", &vtr_op))
21858         ;
21859 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21860       foreach_pbb_vtr_op
21861 #undef _
21862         else if (unformat (i, "translate_pbb_stag"))
21863         {
21864           if (unformat (i, "%d", &tmp))
21865             {
21866               vtr_op = L2_VTR_TRANSLATE_2_1;
21867               outer_tag = tmp;
21868             }
21869           else
21870             {
21871               errmsg
21872                 ("translate_pbb_stag operation requires outer tag definition");
21873               return -99;
21874             }
21875         }
21876       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21877         dmac_set++;
21878       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21879         smac_set++;
21880       else if (unformat (i, "sid %d", &sid))
21881         ;
21882       else if (unformat (i, "vlanid %d", &tmp))
21883         vlanid = tmp;
21884       else
21885         {
21886           clib_warning ("parse error '%U'", format_unformat_error, i);
21887           return -99;
21888         }
21889     }
21890
21891   if ((sw_if_index == ~0) || (vtr_op == ~0))
21892     {
21893       errmsg ("missing sw_if_index or vtr operation");
21894       return -99;
21895     }
21896   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21897       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21898     {
21899       errmsg
21900         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21901       return -99;
21902     }
21903
21904   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21905   mp->sw_if_index = ntohl (sw_if_index);
21906   mp->vtr_op = ntohl (vtr_op);
21907   mp->outer_tag = ntohs (outer_tag);
21908   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21909   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21910   mp->b_vlanid = ntohs (vlanid);
21911   mp->i_sid = ntohl (sid);
21912
21913   S (mp);
21914   W (ret);
21915   return ret;
21916 }
21917
21918 static int
21919 api_flow_classify_set_interface (vat_main_t * vam)
21920 {
21921   unformat_input_t *i = vam->input;
21922   vl_api_flow_classify_set_interface_t *mp;
21923   u32 sw_if_index;
21924   int sw_if_index_set;
21925   u32 ip4_table_index = ~0;
21926   u32 ip6_table_index = ~0;
21927   u8 is_add = 1;
21928   int ret;
21929
21930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21931     {
21932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21933         sw_if_index_set = 1;
21934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21935         sw_if_index_set = 1;
21936       else if (unformat (i, "del"))
21937         is_add = 0;
21938       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21939         ;
21940       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21941         ;
21942       else
21943         {
21944           clib_warning ("parse error '%U'", format_unformat_error, i);
21945           return -99;
21946         }
21947     }
21948
21949   if (sw_if_index_set == 0)
21950     {
21951       errmsg ("missing interface name or sw_if_index");
21952       return -99;
21953     }
21954
21955   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21956
21957   mp->sw_if_index = ntohl (sw_if_index);
21958   mp->ip4_table_index = ntohl (ip4_table_index);
21959   mp->ip6_table_index = ntohl (ip6_table_index);
21960   mp->is_add = is_add;
21961
21962   S (mp);
21963   W (ret);
21964   return ret;
21965 }
21966
21967 static int
21968 api_flow_classify_dump (vat_main_t * vam)
21969 {
21970   unformat_input_t *i = vam->input;
21971   vl_api_flow_classify_dump_t *mp;
21972   vl_api_control_ping_t *mp_ping;
21973   u8 type = FLOW_CLASSIFY_N_TABLES;
21974   int ret;
21975
21976   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21977     ;
21978   else
21979     {
21980       errmsg ("classify table type must be specified");
21981       return -99;
21982     }
21983
21984   if (!vam->json_output)
21985     {
21986       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21987     }
21988
21989   M (FLOW_CLASSIFY_DUMP, mp);
21990   mp->type = type;
21991   /* send it... */
21992   S (mp);
21993
21994   /* Use a control ping for synchronization */
21995   MPING (CONTROL_PING, mp_ping);
21996   S (mp_ping);
21997
21998   /* Wait for a reply... */
21999   W (ret);
22000   return ret;
22001 }
22002
22003 static int
22004 api_feature_enable_disable (vat_main_t * vam)
22005 {
22006   unformat_input_t *i = vam->input;
22007   vl_api_feature_enable_disable_t *mp;
22008   u8 *arc_name = 0;
22009   u8 *feature_name = 0;
22010   u32 sw_if_index = ~0;
22011   u8 enable = 1;
22012   int ret;
22013
22014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22015     {
22016       if (unformat (i, "arc_name %s", &arc_name))
22017         ;
22018       else if (unformat (i, "feature_name %s", &feature_name))
22019         ;
22020       else
22021         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22022         ;
22023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22024         ;
22025       else if (unformat (i, "disable"))
22026         enable = 0;
22027       else
22028         break;
22029     }
22030
22031   if (arc_name == 0)
22032     {
22033       errmsg ("missing arc name");
22034       return -99;
22035     }
22036   if (vec_len (arc_name) > 63)
22037     {
22038       errmsg ("arc name too long");
22039     }
22040
22041   if (feature_name == 0)
22042     {
22043       errmsg ("missing feature name");
22044       return -99;
22045     }
22046   if (vec_len (feature_name) > 63)
22047     {
22048       errmsg ("feature name too long");
22049     }
22050
22051   if (sw_if_index == ~0)
22052     {
22053       errmsg ("missing interface name or sw_if_index");
22054       return -99;
22055     }
22056
22057   /* Construct the API message */
22058   M (FEATURE_ENABLE_DISABLE, mp);
22059   mp->sw_if_index = ntohl (sw_if_index);
22060   mp->enable = enable;
22061   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22062   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22063   vec_free (arc_name);
22064   vec_free (feature_name);
22065
22066   S (mp);
22067   W (ret);
22068   return ret;
22069 }
22070
22071 static int
22072 api_sw_interface_tag_add_del (vat_main_t * vam)
22073 {
22074   unformat_input_t *i = vam->input;
22075   vl_api_sw_interface_tag_add_del_t *mp;
22076   u32 sw_if_index = ~0;
22077   u8 *tag = 0;
22078   u8 enable = 1;
22079   int ret;
22080
22081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22082     {
22083       if (unformat (i, "tag %s", &tag))
22084         ;
22085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22086         ;
22087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22088         ;
22089       else if (unformat (i, "del"))
22090         enable = 0;
22091       else
22092         break;
22093     }
22094
22095   if (sw_if_index == ~0)
22096     {
22097       errmsg ("missing interface name or sw_if_index");
22098       return -99;
22099     }
22100
22101   if (enable && (tag == 0))
22102     {
22103       errmsg ("no tag specified");
22104       return -99;
22105     }
22106
22107   /* Construct the API message */
22108   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22109   mp->sw_if_index = ntohl (sw_if_index);
22110   mp->is_add = enable;
22111   if (enable)
22112     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22113   vec_free (tag);
22114
22115   S (mp);
22116   W (ret);
22117   return ret;
22118 }
22119
22120 static void vl_api_l2_xconnect_details_t_handler
22121   (vl_api_l2_xconnect_details_t * mp)
22122 {
22123   vat_main_t *vam = &vat_main;
22124
22125   print (vam->ofp, "%15d%15d",
22126          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22127 }
22128
22129 static void vl_api_l2_xconnect_details_t_handler_json
22130   (vl_api_l2_xconnect_details_t * mp)
22131 {
22132   vat_main_t *vam = &vat_main;
22133   vat_json_node_t *node = NULL;
22134
22135   if (VAT_JSON_ARRAY != vam->json_tree.type)
22136     {
22137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22138       vat_json_init_array (&vam->json_tree);
22139     }
22140   node = vat_json_array_add (&vam->json_tree);
22141
22142   vat_json_init_object (node);
22143   vat_json_object_add_uint (node, "rx_sw_if_index",
22144                             ntohl (mp->rx_sw_if_index));
22145   vat_json_object_add_uint (node, "tx_sw_if_index",
22146                             ntohl (mp->tx_sw_if_index));
22147 }
22148
22149 static int
22150 api_l2_xconnect_dump (vat_main_t * vam)
22151 {
22152   vl_api_l2_xconnect_dump_t *mp;
22153   vl_api_control_ping_t *mp_ping;
22154   int ret;
22155
22156   if (!vam->json_output)
22157     {
22158       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22159     }
22160
22161   M (L2_XCONNECT_DUMP, mp);
22162
22163   S (mp);
22164
22165   /* Use a control ping for synchronization */
22166   MPING (CONTROL_PING, mp_ping);
22167   S (mp_ping);
22168
22169   W (ret);
22170   return ret;
22171 }
22172
22173 static int
22174 api_hw_interface_set_mtu (vat_main_t * vam)
22175 {
22176   unformat_input_t *i = vam->input;
22177   vl_api_hw_interface_set_mtu_t *mp;
22178   u32 sw_if_index = ~0;
22179   u32 mtu = 0;
22180   int ret;
22181
22182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22183     {
22184       if (unformat (i, "mtu %d", &mtu))
22185         ;
22186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22187         ;
22188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22189         ;
22190       else
22191         break;
22192     }
22193
22194   if (sw_if_index == ~0)
22195     {
22196       errmsg ("missing interface name or sw_if_index");
22197       return -99;
22198     }
22199
22200   if (mtu == 0)
22201     {
22202       errmsg ("no mtu specified");
22203       return -99;
22204     }
22205
22206   /* Construct the API message */
22207   M (HW_INTERFACE_SET_MTU, mp);
22208   mp->sw_if_index = ntohl (sw_if_index);
22209   mp->mtu = ntohs ((u16) mtu);
22210
22211   S (mp);
22212   W (ret);
22213   return ret;
22214 }
22215
22216 static int
22217 api_p2p_ethernet_add (vat_main_t * vam)
22218 {
22219   unformat_input_t *i = vam->input;
22220   vl_api_p2p_ethernet_add_t *mp;
22221   u32 parent_if_index = ~0;
22222   u32 sub_id = ~0;
22223   u8 remote_mac[6];
22224   u8 mac_set = 0;
22225   int ret;
22226
22227   memset (remote_mac, 0, sizeof (remote_mac));
22228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22229     {
22230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22231         ;
22232       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22233         ;
22234       else
22235         if (unformat
22236             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22237         mac_set++;
22238       else if (unformat (i, "sub_id %d", &sub_id))
22239         ;
22240       else
22241         {
22242           clib_warning ("parse error '%U'", format_unformat_error, i);
22243           return -99;
22244         }
22245     }
22246
22247   if (parent_if_index == ~0)
22248     {
22249       errmsg ("missing interface name or sw_if_index");
22250       return -99;
22251     }
22252   if (mac_set == 0)
22253     {
22254       errmsg ("missing remote mac address");
22255       return -99;
22256     }
22257   if (sub_id == ~0)
22258     {
22259       errmsg ("missing sub-interface id");
22260       return -99;
22261     }
22262
22263   M (P2P_ETHERNET_ADD, mp);
22264   mp->parent_if_index = ntohl (parent_if_index);
22265   mp->subif_id = ntohl (sub_id);
22266   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22267
22268   S (mp);
22269   W (ret);
22270   return ret;
22271 }
22272
22273 static int
22274 api_p2p_ethernet_del (vat_main_t * vam)
22275 {
22276   unformat_input_t *i = vam->input;
22277   vl_api_p2p_ethernet_del_t *mp;
22278   u32 parent_if_index = ~0;
22279   u8 remote_mac[6];
22280   u8 mac_set = 0;
22281   int ret;
22282
22283   memset (remote_mac, 0, sizeof (remote_mac));
22284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22285     {
22286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22287         ;
22288       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22289         ;
22290       else
22291         if (unformat
22292             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22293         mac_set++;
22294       else
22295         {
22296           clib_warning ("parse error '%U'", format_unformat_error, i);
22297           return -99;
22298         }
22299     }
22300
22301   if (parent_if_index == ~0)
22302     {
22303       errmsg ("missing interface name or sw_if_index");
22304       return -99;
22305     }
22306   if (mac_set == 0)
22307     {
22308       errmsg ("missing remote mac address");
22309       return -99;
22310     }
22311
22312   M (P2P_ETHERNET_DEL, mp);
22313   mp->parent_if_index = ntohl (parent_if_index);
22314   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22315
22316   S (mp);
22317   W (ret);
22318   return ret;
22319 }
22320
22321 static int
22322 api_lldp_config (vat_main_t * vam)
22323 {
22324   unformat_input_t *i = vam->input;
22325   vl_api_lldp_config_t *mp;
22326   int tx_hold = 0;
22327   int tx_interval = 0;
22328   u8 *sys_name = NULL;
22329   int ret;
22330
22331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22332     {
22333       if (unformat (i, "system-name %s", &sys_name))
22334         ;
22335       else if (unformat (i, "tx-hold %d", &tx_hold))
22336         ;
22337       else if (unformat (i, "tx-interval %d", &tx_interval))
22338         ;
22339       else
22340         {
22341           clib_warning ("parse error '%U'", format_unformat_error, i);
22342           return -99;
22343         }
22344     }
22345
22346   vec_add1 (sys_name, 0);
22347
22348   M (LLDP_CONFIG, mp);
22349   mp->tx_hold = htonl (tx_hold);
22350   mp->tx_interval = htonl (tx_interval);
22351   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22352   vec_free (sys_name);
22353
22354   S (mp);
22355   W (ret);
22356   return ret;
22357 }
22358
22359 static int
22360 api_sw_interface_set_lldp (vat_main_t * vam)
22361 {
22362   unformat_input_t *i = vam->input;
22363   vl_api_sw_interface_set_lldp_t *mp;
22364   u32 sw_if_index = ~0;
22365   u32 enable = 1;
22366   u8 *port_desc = NULL, *mgmt_oid = NULL;
22367   ip4_address_t ip4_addr;
22368   ip6_address_t ip6_addr;
22369   int ret;
22370
22371   memset (&ip4_addr, 0, sizeof (ip4_addr));
22372   memset (&ip6_addr, 0, sizeof (ip6_addr));
22373
22374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22375     {
22376       if (unformat (i, "disable"))
22377         enable = 0;
22378       else
22379         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22380         ;
22381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22382         ;
22383       else if (unformat (i, "port-desc %s", &port_desc))
22384         ;
22385       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22386         ;
22387       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22388         ;
22389       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22390         ;
22391       else
22392         break;
22393     }
22394
22395   if (sw_if_index == ~0)
22396     {
22397       errmsg ("missing interface name or sw_if_index");
22398       return -99;
22399     }
22400
22401   /* Construct the API message */
22402   vec_add1 (port_desc, 0);
22403   vec_add1 (mgmt_oid, 0);
22404   M (SW_INTERFACE_SET_LLDP, mp);
22405   mp->sw_if_index = ntohl (sw_if_index);
22406   mp->enable = enable;
22407   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22408   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22409   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22410   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22411   vec_free (port_desc);
22412   vec_free (mgmt_oid);
22413
22414   S (mp);
22415   W (ret);
22416   return ret;
22417 }
22418
22419 static int
22420 api_tcp_configure_src_addresses (vat_main_t * vam)
22421 {
22422   vl_api_tcp_configure_src_addresses_t *mp;
22423   unformat_input_t *i = vam->input;
22424   ip4_address_t v4first, v4last;
22425   ip6_address_t v6first, v6last;
22426   u8 range_set = 0;
22427   u32 vrf_id = 0;
22428   int ret;
22429
22430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22431     {
22432       if (unformat (i, "%U - %U",
22433                     unformat_ip4_address, &v4first,
22434                     unformat_ip4_address, &v4last))
22435         {
22436           if (range_set)
22437             {
22438               errmsg ("one range per message (range already set)");
22439               return -99;
22440             }
22441           range_set = 1;
22442         }
22443       else if (unformat (i, "%U - %U",
22444                          unformat_ip6_address, &v6first,
22445                          unformat_ip6_address, &v6last))
22446         {
22447           if (range_set)
22448             {
22449               errmsg ("one range per message (range already set)");
22450               return -99;
22451             }
22452           range_set = 2;
22453         }
22454       else if (unformat (i, "vrf %d", &vrf_id))
22455         ;
22456       else
22457         break;
22458     }
22459
22460   if (range_set == 0)
22461     {
22462       errmsg ("address range not set");
22463       return -99;
22464     }
22465
22466   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22467   mp->vrf_id = ntohl (vrf_id);
22468   /* ipv6? */
22469   if (range_set == 2)
22470     {
22471       mp->is_ipv6 = 1;
22472       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22473       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22474     }
22475   else
22476     {
22477       mp->is_ipv6 = 0;
22478       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22479       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22480     }
22481   S (mp);
22482   W (ret);
22483   return ret;
22484 }
22485
22486 static void vl_api_app_namespace_add_del_reply_t_handler
22487   (vl_api_app_namespace_add_del_reply_t * mp)
22488 {
22489   vat_main_t *vam = &vat_main;
22490   i32 retval = ntohl (mp->retval);
22491   if (vam->async_mode)
22492     {
22493       vam->async_errors += (retval < 0);
22494     }
22495   else
22496     {
22497       vam->retval = retval;
22498       if (retval == 0)
22499         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22500       vam->result_ready = 1;
22501     }
22502 }
22503
22504 static void vl_api_app_namespace_add_del_reply_t_handler_json
22505   (vl_api_app_namespace_add_del_reply_t * mp)
22506 {
22507   vat_main_t *vam = &vat_main;
22508   vat_json_node_t node;
22509
22510   vat_json_init_object (&node);
22511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22512   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22513
22514   vat_json_print (vam->ofp, &node);
22515   vat_json_free (&node);
22516
22517   vam->retval = ntohl (mp->retval);
22518   vam->result_ready = 1;
22519 }
22520
22521 static int
22522 api_app_namespace_add_del (vat_main_t * vam)
22523 {
22524   vl_api_app_namespace_add_del_t *mp;
22525   unformat_input_t *i = vam->input;
22526   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22527   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22528   u64 secret;
22529   int ret;
22530
22531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22532     {
22533       if (unformat (i, "id %_%v%_", &ns_id))
22534         ;
22535       else if (unformat (i, "secret %lu", &secret))
22536         secret_set = 1;
22537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22538         sw_if_index_set = 1;
22539       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22540         ;
22541       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22542         ;
22543       else
22544         break;
22545     }
22546   if (!ns_id || !secret_set || !sw_if_index_set)
22547     {
22548       errmsg ("namespace id, secret and sw_if_index must be set");
22549       return -99;
22550     }
22551   if (vec_len (ns_id) > 64)
22552     {
22553       errmsg ("namespace id too long");
22554       return -99;
22555     }
22556   M (APP_NAMESPACE_ADD_DEL, mp);
22557
22558   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22559   mp->namespace_id_len = vec_len (ns_id);
22560   mp->secret = clib_host_to_net_u64 (secret);
22561   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22562   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22563   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22564   vec_free (ns_id);
22565   S (mp);
22566   W (ret);
22567   return ret;
22568 }
22569
22570 static int
22571 api_sock_init_shm (vat_main_t * vam)
22572 {
22573 #if VPP_API_TEST_BUILTIN == 0
22574   unformat_input_t *i = vam->input;
22575   vl_api_shm_elem_config_t *config = 0;
22576   u64 size = 64 << 20;
22577   int rv;
22578
22579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22580     {
22581       if (unformat (i, "size %U", unformat_memory_size, &size))
22582         ;
22583       else
22584         break;
22585     }
22586
22587   /*
22588    * Canned custom ring allocator config.
22589    * Should probably parse all of this
22590    */
22591   vec_validate (config, 6);
22592   config[0].type = VL_API_VLIB_RING;
22593   config[0].size = 256;
22594   config[0].count = 32;
22595
22596   config[1].type = VL_API_VLIB_RING;
22597   config[1].size = 1024;
22598   config[1].count = 16;
22599
22600   config[2].type = VL_API_VLIB_RING;
22601   config[2].size = 4096;
22602   config[2].count = 2;
22603
22604   config[3].type = VL_API_CLIENT_RING;
22605   config[3].size = 256;
22606   config[3].count = 32;
22607
22608   config[4].type = VL_API_CLIENT_RING;
22609   config[4].size = 1024;
22610   config[4].count = 16;
22611
22612   config[5].type = VL_API_CLIENT_RING;
22613   config[5].size = 4096;
22614   config[5].count = 2;
22615
22616   config[6].type = VL_API_QUEUE;
22617   config[6].count = 128;
22618   config[6].size = sizeof (uword);
22619
22620   rv = vl_socket_client_init_shm (config);
22621   if (!rv)
22622     vam->client_index_invalid = 1;
22623   return rv;
22624 #else
22625   return -99;
22626 #endif
22627 }
22628
22629 static int
22630 api_dns_enable_disable (vat_main_t * vam)
22631 {
22632   unformat_input_t *line_input = vam->input;
22633   vl_api_dns_enable_disable_t *mp;
22634   u8 enable_disable = 1;
22635   int ret;
22636
22637   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22638     {
22639       if (unformat (line_input, "disable"))
22640         enable_disable = 0;
22641       if (unformat (line_input, "enable"))
22642         enable_disable = 1;
22643       else
22644         break;
22645     }
22646
22647   /* Construct the API message */
22648   M (DNS_ENABLE_DISABLE, mp);
22649   mp->enable = enable_disable;
22650
22651   /* send it... */
22652   S (mp);
22653   /* Wait for the reply */
22654   W (ret);
22655   return ret;
22656 }
22657
22658 static int
22659 api_dns_resolve_name (vat_main_t * vam)
22660 {
22661   unformat_input_t *line_input = vam->input;
22662   vl_api_dns_resolve_name_t *mp;
22663   u8 *name = 0;
22664   int ret;
22665
22666   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22667     {
22668       if (unformat (line_input, "%s", &name))
22669         ;
22670       else
22671         break;
22672     }
22673
22674   if (vec_len (name) > 127)
22675     {
22676       errmsg ("name too long");
22677       return -99;
22678     }
22679
22680   /* Construct the API message */
22681   M (DNS_RESOLVE_NAME, mp);
22682   memcpy (mp->name, name, vec_len (name));
22683   vec_free (name);
22684
22685   /* send it... */
22686   S (mp);
22687   /* Wait for the reply */
22688   W (ret);
22689   return ret;
22690 }
22691
22692 static int
22693 api_dns_resolve_ip (vat_main_t * vam)
22694 {
22695   unformat_input_t *line_input = vam->input;
22696   vl_api_dns_resolve_ip_t *mp;
22697   int is_ip6 = -1;
22698   ip4_address_t addr4;
22699   ip6_address_t addr6;
22700   int ret;
22701
22702   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22703     {
22704       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22705         is_ip6 = 1;
22706       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22707         is_ip6 = 0;
22708       else
22709         break;
22710     }
22711
22712   if (is_ip6 == -1)
22713     {
22714       errmsg ("missing address");
22715       return -99;
22716     }
22717
22718   /* Construct the API message */
22719   M (DNS_RESOLVE_IP, mp);
22720   mp->is_ip6 = is_ip6;
22721   if (is_ip6)
22722     memcpy (mp->address, &addr6, sizeof (addr6));
22723   else
22724     memcpy (mp->address, &addr4, sizeof (addr4));
22725
22726   /* send it... */
22727   S (mp);
22728   /* Wait for the reply */
22729   W (ret);
22730   return ret;
22731 }
22732
22733 static int
22734 api_dns_name_server_add_del (vat_main_t * vam)
22735 {
22736   unformat_input_t *i = vam->input;
22737   vl_api_dns_name_server_add_del_t *mp;
22738   u8 is_add = 1;
22739   ip6_address_t ip6_server;
22740   ip4_address_t ip4_server;
22741   int ip6_set = 0;
22742   int ip4_set = 0;
22743   int ret = 0;
22744
22745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22746     {
22747       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22748         ip6_set = 1;
22749       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22750         ip4_set = 1;
22751       else if (unformat (i, "del"))
22752         is_add = 0;
22753       else
22754         {
22755           clib_warning ("parse error '%U'", format_unformat_error, i);
22756           return -99;
22757         }
22758     }
22759
22760   if (ip4_set && ip6_set)
22761     {
22762       errmsg ("Only one server address allowed per message");
22763       return -99;
22764     }
22765   if ((ip4_set + ip6_set) == 0)
22766     {
22767       errmsg ("Server address required");
22768       return -99;
22769     }
22770
22771   /* Construct the API message */
22772   M (DNS_NAME_SERVER_ADD_DEL, mp);
22773
22774   if (ip6_set)
22775     {
22776       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22777       mp->is_ip6 = 1;
22778     }
22779   else
22780     {
22781       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22782       mp->is_ip6 = 0;
22783     }
22784
22785   mp->is_add = is_add;
22786
22787   /* send it... */
22788   S (mp);
22789
22790   /* Wait for a reply, return good/bad news  */
22791   W (ret);
22792   return ret;
22793 }
22794
22795 static void
22796 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22797 {
22798   vat_main_t *vam = &vat_main;
22799
22800   if (mp->is_ip4)
22801     {
22802       print (vam->ofp,
22803              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22804              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22805              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22806              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22807              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22808              clib_net_to_host_u32 (mp->action_index), mp->tag);
22809     }
22810   else
22811     {
22812       print (vam->ofp,
22813              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22814              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22815              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22816              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22817              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22818              clib_net_to_host_u32 (mp->action_index), mp->tag);
22819     }
22820 }
22821
22822 static void
22823 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22824                                              mp)
22825 {
22826   vat_main_t *vam = &vat_main;
22827   vat_json_node_t *node = NULL;
22828   struct in6_addr ip6;
22829   struct in_addr ip4;
22830
22831   if (VAT_JSON_ARRAY != vam->json_tree.type)
22832     {
22833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22834       vat_json_init_array (&vam->json_tree);
22835     }
22836   node = vat_json_array_add (&vam->json_tree);
22837   vat_json_init_object (node);
22838
22839   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22840   vat_json_object_add_uint (node, "appns_index",
22841                             clib_net_to_host_u32 (mp->appns_index));
22842   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22843   vat_json_object_add_uint (node, "scope", mp->scope);
22844   vat_json_object_add_uint (node, "action_index",
22845                             clib_net_to_host_u32 (mp->action_index));
22846   vat_json_object_add_uint (node, "lcl_port",
22847                             clib_net_to_host_u16 (mp->lcl_port));
22848   vat_json_object_add_uint (node, "rmt_port",
22849                             clib_net_to_host_u16 (mp->rmt_port));
22850   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22851   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22852   vat_json_object_add_string_copy (node, "tag", mp->tag);
22853   if (mp->is_ip4)
22854     {
22855       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22856       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22857       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22858       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22859     }
22860   else
22861     {
22862       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22863       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22864       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22865       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22866     }
22867 }
22868
22869 static int
22870 api_session_rule_add_del (vat_main_t * vam)
22871 {
22872   vl_api_session_rule_add_del_t *mp;
22873   unformat_input_t *i = vam->input;
22874   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22875   u32 appns_index = 0, scope = 0;
22876   ip4_address_t lcl_ip4, rmt_ip4;
22877   ip6_address_t lcl_ip6, rmt_ip6;
22878   u8 is_ip4 = 1, conn_set = 0;
22879   u8 is_add = 1, *tag = 0;
22880   int ret;
22881
22882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22883     {
22884       if (unformat (i, "del"))
22885         is_add = 0;
22886       else if (unformat (i, "add"))
22887         ;
22888       else if (unformat (i, "proto tcp"))
22889         proto = 0;
22890       else if (unformat (i, "proto udp"))
22891         proto = 1;
22892       else if (unformat (i, "appns %d", &appns_index))
22893         ;
22894       else if (unformat (i, "scope %d", &scope))
22895         ;
22896       else if (unformat (i, "tag %_%v%_", &tag))
22897         ;
22898       else
22899         if (unformat
22900             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22901              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22902              &rmt_port))
22903         {
22904           is_ip4 = 1;
22905           conn_set = 1;
22906         }
22907       else
22908         if (unformat
22909             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22910              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22911              &rmt_port))
22912         {
22913           is_ip4 = 0;
22914           conn_set = 1;
22915         }
22916       else if (unformat (i, "action %d", &action))
22917         ;
22918       else
22919         break;
22920     }
22921   if (proto == ~0 || !conn_set || action == ~0)
22922     {
22923       errmsg ("transport proto, connection and action must be set");
22924       return -99;
22925     }
22926
22927   if (scope > 3)
22928     {
22929       errmsg ("scope should be 0-3");
22930       return -99;
22931     }
22932
22933   M (SESSION_RULE_ADD_DEL, mp);
22934
22935   mp->is_ip4 = is_ip4;
22936   mp->transport_proto = proto;
22937   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22938   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22939   mp->lcl_plen = lcl_plen;
22940   mp->rmt_plen = rmt_plen;
22941   mp->action_index = clib_host_to_net_u32 (action);
22942   mp->appns_index = clib_host_to_net_u32 (appns_index);
22943   mp->scope = scope;
22944   mp->is_add = is_add;
22945   if (is_ip4)
22946     {
22947       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22948       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22949     }
22950   else
22951     {
22952       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22953       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22954     }
22955   if (tag)
22956     {
22957       clib_memcpy (mp->tag, tag, vec_len (tag));
22958       vec_free (tag);
22959     }
22960
22961   S (mp);
22962   W (ret);
22963   return ret;
22964 }
22965
22966 static int
22967 api_session_rules_dump (vat_main_t * vam)
22968 {
22969   vl_api_session_rules_dump_t *mp;
22970   vl_api_control_ping_t *mp_ping;
22971   int ret;
22972
22973   if (!vam->json_output)
22974     {
22975       print (vam->ofp, "%=20s", "Session Rules");
22976     }
22977
22978   M (SESSION_RULES_DUMP, mp);
22979   /* send it... */
22980   S (mp);
22981
22982   /* Use a control ping for synchronization */
22983   MPING (CONTROL_PING, mp_ping);
22984   S (mp_ping);
22985
22986   /* Wait for a reply... */
22987   W (ret);
22988   return ret;
22989 }
22990
22991 static int
22992 api_ip_container_proxy_add_del (vat_main_t * vam)
22993 {
22994   vl_api_ip_container_proxy_add_del_t *mp;
22995   unformat_input_t *i = vam->input;
22996   u32 plen = ~0, sw_if_index = ~0;
22997   ip4_address_t ip4;
22998   ip6_address_t ip6;
22999   u8 is_ip4 = 1;
23000   u8 is_add = 1;
23001   int ret;
23002
23003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23004     {
23005       if (unformat (i, "del"))
23006         is_add = 0;
23007       else if (unformat (i, "add"))
23008         ;
23009       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23010         {
23011           is_ip4 = 1;
23012           plen = 32;
23013         }
23014       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23015         {
23016           is_ip4 = 0;
23017           plen = 128;
23018         }
23019       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23020         ;
23021       else
23022         break;
23023     }
23024   if (sw_if_index == ~0 || plen == ~0)
23025     {
23026       errmsg ("address and sw_if_index must be set");
23027       return -99;
23028     }
23029
23030   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23031
23032   mp->is_ip4 = is_ip4;
23033   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23034   mp->plen = plen;
23035   mp->is_add = is_add;
23036   if (is_ip4)
23037     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23038   else
23039     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23040
23041   S (mp);
23042   W (ret);
23043   return ret;
23044 }
23045
23046 static int
23047 api_qos_record_enable_disable (vat_main_t * vam)
23048 {
23049   unformat_input_t *i = vam->input;
23050   vl_api_qos_record_enable_disable_t *mp;
23051   u32 sw_if_index, qs = 0xff;
23052   u8 sw_if_index_set = 0;
23053   u8 enable = 1;
23054   int ret;
23055
23056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23057     {
23058       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23059         sw_if_index_set = 1;
23060       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23061         sw_if_index_set = 1;
23062       else if (unformat (i, "%U", unformat_qos_source, &qs))
23063         ;
23064       else if (unformat (i, "disable"))
23065         enable = 0;
23066       else
23067         {
23068           clib_warning ("parse error '%U'", format_unformat_error, i);
23069           return -99;
23070         }
23071     }
23072
23073   if (sw_if_index_set == 0)
23074     {
23075       errmsg ("missing interface name or sw_if_index");
23076       return -99;
23077     }
23078   if (qs == 0xff)
23079     {
23080       errmsg ("input location must be specified");
23081       return -99;
23082     }
23083
23084   M (QOS_RECORD_ENABLE_DISABLE, mp);
23085
23086   mp->sw_if_index = ntohl (sw_if_index);
23087   mp->input_source = qs;
23088   mp->enable = enable;
23089
23090   S (mp);
23091   W (ret);
23092   return ret;
23093 }
23094
23095
23096 static int
23097 q_or_quit (vat_main_t * vam)
23098 {
23099 #if VPP_API_TEST_BUILTIN == 0
23100   longjmp (vam->jump_buf, 1);
23101 #endif
23102   return 0;                     /* not so much */
23103 }
23104
23105 static int
23106 q (vat_main_t * vam)
23107 {
23108   return q_or_quit (vam);
23109 }
23110
23111 static int
23112 quit (vat_main_t * vam)
23113 {
23114   return q_or_quit (vam);
23115 }
23116
23117 static int
23118 comment (vat_main_t * vam)
23119 {
23120   return 0;
23121 }
23122
23123 static int
23124 statseg (vat_main_t * vam)
23125 {
23126   ssvm_private_t *ssvmp = &vam->stat_segment;
23127   ssvm_shared_header_t *shared_header = ssvmp->sh;
23128   vlib_counter_t **counters;
23129   u64 thread0_index1_packets;
23130   u64 thread0_index1_bytes;
23131   f64 vector_rate, input_rate;
23132   uword *p;
23133
23134   uword *counter_vector_by_name;
23135   if (vam->stat_segment_lockp == 0)
23136     {
23137       errmsg ("Stat segment not mapped...");
23138       return -99;
23139     }
23140
23141   /* look up "/if/rx for sw_if_index 1 as a test */
23142
23143   clib_spinlock_lock (vam->stat_segment_lockp);
23144
23145   counter_vector_by_name = (uword *) shared_header->opaque[1];
23146
23147   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23148   if (p == 0)
23149     {
23150       clib_spinlock_unlock (vam->stat_segment_lockp);
23151       errmsg ("/if/tx not found?");
23152       return -99;
23153     }
23154
23155   /* Fish per-thread vector of combined counters from shared memory */
23156   counters = (vlib_counter_t **) p[0];
23157
23158   if (vec_len (counters[0]) < 2)
23159     {
23160       clib_spinlock_unlock (vam->stat_segment_lockp);
23161       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23162       return -99;
23163     }
23164
23165   /* Read thread 0 sw_if_index 1 counter */
23166   thread0_index1_packets = counters[0][1].packets;
23167   thread0_index1_bytes = counters[0][1].bytes;
23168
23169   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23170   if (p == 0)
23171     {
23172       clib_spinlock_unlock (vam->stat_segment_lockp);
23173       errmsg ("vector_rate not found?");
23174       return -99;
23175     }
23176
23177   vector_rate = *(f64 *) (p[0]);
23178   p = hash_get_mem (counter_vector_by_name, "input_rate");
23179   if (p == 0)
23180     {
23181       clib_spinlock_unlock (vam->stat_segment_lockp);
23182       errmsg ("input_rate not found?");
23183       return -99;
23184     }
23185   input_rate = *(f64 *) (p[0]);
23186
23187   clib_spinlock_unlock (vam->stat_segment_lockp);
23188
23189   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23190          vector_rate, input_rate);
23191   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23192          thread0_index1_packets, thread0_index1_bytes);
23193
23194   return 0;
23195 }
23196
23197 static int
23198 cmd_cmp (void *a1, void *a2)
23199 {
23200   u8 **c1 = a1;
23201   u8 **c2 = a2;
23202
23203   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23204 }
23205
23206 static int
23207 help (vat_main_t * vam)
23208 {
23209   u8 **cmds = 0;
23210   u8 *name = 0;
23211   hash_pair_t *p;
23212   unformat_input_t *i = vam->input;
23213   int j;
23214
23215   if (unformat (i, "%s", &name))
23216     {
23217       uword *hs;
23218
23219       vec_add1 (name, 0);
23220
23221       hs = hash_get_mem (vam->help_by_name, name);
23222       if (hs)
23223         print (vam->ofp, "usage: %s %s", name, hs[0]);
23224       else
23225         print (vam->ofp, "No such msg / command '%s'", name);
23226       vec_free (name);
23227       return 0;
23228     }
23229
23230   print (vam->ofp, "Help is available for the following:");
23231
23232     /* *INDENT-OFF* */
23233     hash_foreach_pair (p, vam->function_by_name,
23234     ({
23235       vec_add1 (cmds, (u8 *)(p->key));
23236     }));
23237     /* *INDENT-ON* */
23238
23239   vec_sort_with_function (cmds, cmd_cmp);
23240
23241   for (j = 0; j < vec_len (cmds); j++)
23242     print (vam->ofp, "%s", cmds[j]);
23243
23244   vec_free (cmds);
23245   return 0;
23246 }
23247
23248 static int
23249 set (vat_main_t * vam)
23250 {
23251   u8 *name = 0, *value = 0;
23252   unformat_input_t *i = vam->input;
23253
23254   if (unformat (i, "%s", &name))
23255     {
23256       /* The input buffer is a vector, not a string. */
23257       value = vec_dup (i->buffer);
23258       vec_delete (value, i->index, 0);
23259       /* Almost certainly has a trailing newline */
23260       if (value[vec_len (value) - 1] == '\n')
23261         value[vec_len (value) - 1] = 0;
23262       /* Make sure it's a proper string, one way or the other */
23263       vec_add1 (value, 0);
23264       (void) clib_macro_set_value (&vam->macro_main,
23265                                    (char *) name, (char *) value);
23266     }
23267   else
23268     errmsg ("usage: set <name> <value>");
23269
23270   vec_free (name);
23271   vec_free (value);
23272   return 0;
23273 }
23274
23275 static int
23276 unset (vat_main_t * vam)
23277 {
23278   u8 *name = 0;
23279
23280   if (unformat (vam->input, "%s", &name))
23281     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23282       errmsg ("unset: %s wasn't set", name);
23283   vec_free (name);
23284   return 0;
23285 }
23286
23287 typedef struct
23288 {
23289   u8 *name;
23290   u8 *value;
23291 } macro_sort_t;
23292
23293
23294 static int
23295 macro_sort_cmp (void *a1, void *a2)
23296 {
23297   macro_sort_t *s1 = a1;
23298   macro_sort_t *s2 = a2;
23299
23300   return strcmp ((char *) (s1->name), (char *) (s2->name));
23301 }
23302
23303 static int
23304 dump_macro_table (vat_main_t * vam)
23305 {
23306   macro_sort_t *sort_me = 0, *sm;
23307   int i;
23308   hash_pair_t *p;
23309
23310     /* *INDENT-OFF* */
23311     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23312     ({
23313       vec_add2 (sort_me, sm, 1);
23314       sm->name = (u8 *)(p->key);
23315       sm->value = (u8 *) (p->value[0]);
23316     }));
23317     /* *INDENT-ON* */
23318
23319   vec_sort_with_function (sort_me, macro_sort_cmp);
23320
23321   if (vec_len (sort_me))
23322     print (vam->ofp, "%-15s%s", "Name", "Value");
23323   else
23324     print (vam->ofp, "The macro table is empty...");
23325
23326   for (i = 0; i < vec_len (sort_me); i++)
23327     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23328   return 0;
23329 }
23330
23331 static int
23332 dump_node_table (vat_main_t * vam)
23333 {
23334   int i, j;
23335   vlib_node_t *node, *next_node;
23336
23337   if (vec_len (vam->graph_nodes) == 0)
23338     {
23339       print (vam->ofp, "Node table empty, issue get_node_graph...");
23340       return 0;
23341     }
23342
23343   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23344     {
23345       node = vam->graph_nodes[0][i];
23346       print (vam->ofp, "[%d] %s", i, node->name);
23347       for (j = 0; j < vec_len (node->next_nodes); j++)
23348         {
23349           if (node->next_nodes[j] != ~0)
23350             {
23351               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23352               print (vam->ofp, "  [%d] %s", j, next_node->name);
23353             }
23354         }
23355     }
23356   return 0;
23357 }
23358
23359 static int
23360 value_sort_cmp (void *a1, void *a2)
23361 {
23362   name_sort_t *n1 = a1;
23363   name_sort_t *n2 = a2;
23364
23365   if (n1->value < n2->value)
23366     return -1;
23367   if (n1->value > n2->value)
23368     return 1;
23369   return 0;
23370 }
23371
23372
23373 static int
23374 dump_msg_api_table (vat_main_t * vam)
23375 {
23376   api_main_t *am = &api_main;
23377   name_sort_t *nses = 0, *ns;
23378   hash_pair_t *hp;
23379   int i;
23380
23381   /* *INDENT-OFF* */
23382   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23383   ({
23384     vec_add2 (nses, ns, 1);
23385     ns->name = (u8 *)(hp->key);
23386     ns->value = (u32) hp->value[0];
23387   }));
23388   /* *INDENT-ON* */
23389
23390   vec_sort_with_function (nses, value_sort_cmp);
23391
23392   for (i = 0; i < vec_len (nses); i++)
23393     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23394   vec_free (nses);
23395   return 0;
23396 }
23397
23398 static int
23399 get_msg_id (vat_main_t * vam)
23400 {
23401   u8 *name_and_crc;
23402   u32 message_index;
23403
23404   if (unformat (vam->input, "%s", &name_and_crc))
23405     {
23406       message_index = vl_msg_api_get_msg_index (name_and_crc);
23407       if (message_index == ~0)
23408         {
23409           print (vam->ofp, " '%s' not found", name_and_crc);
23410           return 0;
23411         }
23412       print (vam->ofp, " '%s' has message index %d",
23413              name_and_crc, message_index);
23414       return 0;
23415     }
23416   errmsg ("name_and_crc required...");
23417   return 0;
23418 }
23419
23420 static int
23421 search_node_table (vat_main_t * vam)
23422 {
23423   unformat_input_t *line_input = vam->input;
23424   u8 *node_to_find;
23425   int j;
23426   vlib_node_t *node, *next_node;
23427   uword *p;
23428
23429   if (vam->graph_node_index_by_name == 0)
23430     {
23431       print (vam->ofp, "Node table empty, issue get_node_graph...");
23432       return 0;
23433     }
23434
23435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23436     {
23437       if (unformat (line_input, "%s", &node_to_find))
23438         {
23439           vec_add1 (node_to_find, 0);
23440           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23441           if (p == 0)
23442             {
23443               print (vam->ofp, "%s not found...", node_to_find);
23444               goto out;
23445             }
23446           node = vam->graph_nodes[0][p[0]];
23447           print (vam->ofp, "[%d] %s", p[0], node->name);
23448           for (j = 0; j < vec_len (node->next_nodes); j++)
23449             {
23450               if (node->next_nodes[j] != ~0)
23451                 {
23452                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23453                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23454                 }
23455             }
23456         }
23457
23458       else
23459         {
23460           clib_warning ("parse error '%U'", format_unformat_error,
23461                         line_input);
23462           return -99;
23463         }
23464
23465     out:
23466       vec_free (node_to_find);
23467
23468     }
23469
23470   return 0;
23471 }
23472
23473
23474 static int
23475 script (vat_main_t * vam)
23476 {
23477 #if (VPP_API_TEST_BUILTIN==0)
23478   u8 *s = 0;
23479   char *save_current_file;
23480   unformat_input_t save_input;
23481   jmp_buf save_jump_buf;
23482   u32 save_line_number;
23483
23484   FILE *new_fp, *save_ifp;
23485
23486   if (unformat (vam->input, "%s", &s))
23487     {
23488       new_fp = fopen ((char *) s, "r");
23489       if (new_fp == 0)
23490         {
23491           errmsg ("Couldn't open script file %s", s);
23492           vec_free (s);
23493           return -99;
23494         }
23495     }
23496   else
23497     {
23498       errmsg ("Missing script name");
23499       return -99;
23500     }
23501
23502   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23503   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23504   save_ifp = vam->ifp;
23505   save_line_number = vam->input_line_number;
23506   save_current_file = (char *) vam->current_file;
23507
23508   vam->input_line_number = 0;
23509   vam->ifp = new_fp;
23510   vam->current_file = s;
23511   do_one_file (vam);
23512
23513   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23514   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23515   vam->ifp = save_ifp;
23516   vam->input_line_number = save_line_number;
23517   vam->current_file = (u8 *) save_current_file;
23518   vec_free (s);
23519
23520   return 0;
23521 #else
23522   clib_warning ("use the exec command...");
23523   return -99;
23524 #endif
23525 }
23526
23527 static int
23528 echo (vat_main_t * vam)
23529 {
23530   print (vam->ofp, "%v", vam->input->buffer);
23531   return 0;
23532 }
23533
23534 /* List of API message constructors, CLI names map to api_xxx */
23535 #define foreach_vpe_api_msg                                             \
23536 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23537 _(sw_interface_dump,"")                                                 \
23538 _(sw_interface_set_flags,                                               \
23539   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23540 _(sw_interface_add_del_address,                                         \
23541   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23542 _(sw_interface_set_rx_mode,                                             \
23543   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23544 _(sw_interface_set_rx_placement,                                        \
23545   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23546 _(sw_interface_rx_placement_dump,                                       \
23547   "[<intfc> | sw_if_index <id>]")                                         \
23548 _(sw_interface_set_table,                                               \
23549   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23550 _(sw_interface_set_mpls_enable,                                         \
23551   "<intfc> | sw_if_index [disable | dis]")                              \
23552 _(sw_interface_set_vpath,                                               \
23553   "<intfc> | sw_if_index <id> enable | disable")                        \
23554 _(sw_interface_set_vxlan_bypass,                                        \
23555   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23556 _(sw_interface_set_geneve_bypass,                                       \
23557   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23558 _(sw_interface_set_l2_xconnect,                                         \
23559   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23560   "enable | disable")                                                   \
23561 _(sw_interface_set_l2_bridge,                                           \
23562   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23563   "[shg <split-horizon-group>] [bvi]\n"                                 \
23564   "enable | disable")                                                   \
23565 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23566 _(bridge_domain_add_del,                                                \
23567   "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") \
23568 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23569 _(l2fib_add_del,                                                        \
23570   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23571 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23572 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23573 _(l2_flags,                                                             \
23574   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23575 _(bridge_flags,                                                         \
23576   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23577 _(tap_connect,                                                          \
23578   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23579 _(tap_modify,                                                           \
23580   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23581 _(tap_delete,                                                           \
23582   "<vpp-if-name> | sw_if_index <id>")                                   \
23583 _(sw_interface_tap_dump, "")                                            \
23584 _(tap_create_v2,                                                        \
23585   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23586 _(tap_delete_v2,                                                        \
23587   "<vpp-if-name> | sw_if_index <id>")                                   \
23588 _(sw_interface_tap_v2_dump, "")                                         \
23589 _(bond_create,                                                          \
23590   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23591   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23592 _(bond_delete,                                                          \
23593   "<vpp-if-name> | sw_if_index <id>")                                   \
23594 _(bond_enslave,                                                         \
23595   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23596 _(bond_detach_slave,                                                    \
23597   "sw_if_index <n>")                                                    \
23598 _(sw_interface_bond_dump, "")                                           \
23599 _(sw_interface_slave_dump,                                              \
23600   "<vpp-if-name> | sw_if_index <id>")                                   \
23601 _(ip_table_add_del,                                                     \
23602   "table <n> [ipv6] [add | del]\n")                                     \
23603 _(ip_add_del_route,                                                     \
23604   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23605   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23606   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23607   "[multipath] [count <n>]")                                            \
23608 _(ip_mroute_add_del,                                                    \
23609   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23610   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23611 _(mpls_table_add_del,                                                   \
23612   "table <n> [add | del]\n")                                            \
23613 _(mpls_route_add_del,                                                   \
23614   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23615   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23616   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23617   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23618   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23619 _(mpls_ip_bind_unbind,                                                  \
23620   "<label> <addr/len>")                                                 \
23621 _(mpls_tunnel_add_del,                                                  \
23622   " via <addr> [table-id <n>]\n"                                        \
23623   "sw_if_index <id>] [l2]  [del]")                                      \
23624 _(sr_mpls_policy_add,                                                   \
23625   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23626 _(sr_mpls_policy_del,                                                   \
23627   "bsid <id>")                                                          \
23628 _(bier_table_add_del,                                                   \
23629   "<label> <sub-domain> <set> <bsl> [del]")                             \
23630 _(bier_route_add_del,                                                   \
23631   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23632   "[<intfc> | sw_if_index <id>]"                                        \
23633   "[weight <n>] [del] [multipath]")                                     \
23634 _(proxy_arp_add_del,                                                    \
23635   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23636 _(proxy_arp_intfc_enable_disable,                                       \
23637   "<intfc> | sw_if_index <id> enable | disable")                        \
23638 _(sw_interface_set_unnumbered,                                          \
23639   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23640 _(ip_neighbor_add_del,                                                  \
23641   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23642   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23643 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23644 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23645   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23646   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23647   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23648 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23649 _(reset_fib, "vrf <n> [ipv6]")                                          \
23650 _(dhcp_proxy_config,                                                    \
23651   "svr <v46-address> src <v46-address>\n"                               \
23652    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23653 _(dhcp_proxy_set_vss,                                                   \
23654   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23655 _(dhcp_proxy_dump, "ip6")                                               \
23656 _(dhcp_client_config,                                                   \
23657   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23658 _(set_ip_flow_hash,                                                     \
23659   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23660 _(sw_interface_ip6_enable_disable,                                      \
23661   "<intfc> | sw_if_index <id> enable | disable")                        \
23662 _(sw_interface_ip6_set_link_local_address,                              \
23663   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23664 _(ip6nd_proxy_add_del,                                                  \
23665   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23666 _(ip6nd_proxy_dump, "")                                                 \
23667 _(sw_interface_ip6nd_ra_prefix,                                         \
23668   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23669   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23670   "[nolink] [isno]")                                                    \
23671 _(sw_interface_ip6nd_ra_config,                                         \
23672   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23673   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23674   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23675 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23676 _(l2_patch_add_del,                                                     \
23677   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23678   "enable | disable")                                                   \
23679 _(sr_localsid_add_del,                                                  \
23680   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23681   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23682 _(classify_add_del_table,                                               \
23683   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23684   " [del] [del-chain] mask <mask-value>\n"                              \
23685   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23686   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23687 _(classify_add_del_session,                                             \
23688   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23689   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23690   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23691   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23692 _(classify_set_interface_ip_table,                                      \
23693   "<intfc> | sw_if_index <nn> table <nn>")                              \
23694 _(classify_set_interface_l2_tables,                                     \
23695   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23696   "  [other-table <nn>]")                                               \
23697 _(get_node_index, "node <node-name")                                    \
23698 _(add_node_next, "node <node-name> next <next-node-name>")              \
23699 _(l2tpv3_create_tunnel,                                                 \
23700   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23701   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23702   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23703 _(l2tpv3_set_tunnel_cookies,                                            \
23704   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23705   "[new_remote_cookie <nn>]\n")                                         \
23706 _(l2tpv3_interface_enable_disable,                                      \
23707   "<intfc> | sw_if_index <nn> enable | disable")                        \
23708 _(l2tpv3_set_lookup_key,                                                \
23709   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23710 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23711 _(vxlan_offload_rx,                                                     \
23712   "hw { <interface name> | hw_if_index <nn>} "                          \
23713   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23714 _(vxlan_add_del_tunnel,                                                 \
23715   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23716   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23717   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23718 _(geneve_add_del_tunnel,                                                \
23719   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23720   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23721   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23722 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23723 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23724 _(gre_add_del_tunnel,                                                   \
23725   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23726   "[teb | erspan <session-id>] [del]")                                  \
23727 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23728 _(l2_fib_clear_table, "")                                               \
23729 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23730 _(l2_interface_vlan_tag_rewrite,                                        \
23731   "<intfc> | sw_if_index <nn> \n"                                       \
23732   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23733   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23734 _(create_vhost_user_if,                                                 \
23735         "socket <filename> [server] [renumber <dev_instance>] "         \
23736         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23737         "[mac <mac_address>]")                                          \
23738 _(modify_vhost_user_if,                                                 \
23739         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23740         "[server] [renumber <dev_instance>]")                           \
23741 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23742 _(sw_interface_vhost_user_dump, "")                                     \
23743 _(show_version, "")                                                     \
23744 _(vxlan_gpe_add_del_tunnel,                                             \
23745   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23746   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23747   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23748   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23749 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23750 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23751 _(interface_name_renumber,                                              \
23752   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23753 _(input_acl_set_interface,                                              \
23754   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23755   "  [l2-table <nn>] [del]")                                            \
23756 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23757 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23758   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23759 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23760 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23761 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23762 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23763 _(ip_dump, "ipv4 | ipv6")                                               \
23764 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23765 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23766   "  spid_id <n> ")                                                     \
23767 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23768   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23769   "  integ_alg <alg> integ_key <hex>")                                  \
23770 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23771   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23772   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23773   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23774 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23775 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23776   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23777   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23778   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23779   "  [instance <n>]")     \
23780 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23781 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23782   "  <alg> <hex>\n")                                                    \
23783 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23784 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23785 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23786   "(auth_data 0x<data> | auth_data <data>)")                            \
23787 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23788   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23789 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23790   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23791   "(local|remote)")                                                     \
23792 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23793 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23794 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23795 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23796 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23797 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23798 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23799 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23800 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23801 _(delete_loopback,"sw_if_index <nn>")                                   \
23802 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23803 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23804 _(want_interface_events,  "enable|disable")                             \
23805 _(want_stats,"enable|disable")                                          \
23806 _(get_first_msg_id, "client <name>")                                    \
23807 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23808 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23809   "fib-id <nn> [ip4][ip6][default]")                                    \
23810 _(get_node_graph, " ")                                                  \
23811 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23812 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23813 _(ioam_disable, "")                                                     \
23814 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23815                             " sw_if_index <sw_if_index> p <priority> "  \
23816                             "w <weight>] [del]")                        \
23817 _(one_add_del_locator, "locator-set <locator_name> "                    \
23818                         "iface <intf> | sw_if_index <sw_if_index> "     \
23819                         "p <priority> w <weight> [del]")                \
23820 _(one_add_del_local_eid,"vni <vni> eid "                                \
23821                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23822                          "locator-set <locator_name> [del]"             \
23823                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23824 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23825 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23826 _(one_enable_disable, "enable|disable")                                 \
23827 _(one_map_register_enable_disable, "enable|disable")                    \
23828 _(one_map_register_fallback_threshold, "<value>")                       \
23829 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23830 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23831                                "[seid <seid>] "                         \
23832                                "rloc <locator> p <prio> "               \
23833                                "w <weight> [rloc <loc> ... ] "          \
23834                                "action <action> [del-all]")             \
23835 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23836                           "<local-eid>")                                \
23837 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23838 _(one_use_petr, "ip-address> | disable")                                \
23839 _(one_map_request_mode, "src-dst|dst-only")                             \
23840 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23841 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23842 _(one_locator_set_dump, "[local | remote]")                             \
23843 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23844 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23845                        "[local] | [remote]")                            \
23846 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23847 _(one_ndp_bd_get, "")                                                   \
23848 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23849 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23850 _(one_l2_arp_bd_get, "")                                                \
23851 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23852 _(one_stats_enable_disable, "enable|disable")                           \
23853 _(show_one_stats_enable_disable, "")                                    \
23854 _(one_eid_table_vni_dump, "")                                           \
23855 _(one_eid_table_map_dump, "l2|l3")                                      \
23856 _(one_map_resolver_dump, "")                                            \
23857 _(one_map_server_dump, "")                                              \
23858 _(one_adjacencies_get, "vni <vni>")                                     \
23859 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23860 _(show_one_rloc_probe_state, "")                                        \
23861 _(show_one_map_register_state, "")                                      \
23862 _(show_one_status, "")                                                  \
23863 _(one_stats_dump, "")                                                   \
23864 _(one_stats_flush, "")                                                  \
23865 _(one_get_map_request_itr_rlocs, "")                                    \
23866 _(one_map_register_set_ttl, "<ttl>")                                    \
23867 _(one_set_transport_protocol, "udp|api")                                \
23868 _(one_get_transport_protocol, "")                                       \
23869 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23870 _(one_show_xtr_mode, "")                                                \
23871 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23872 _(one_show_pitr_mode, "")                                               \
23873 _(one_enable_disable_petr_mode, "enable|disable")                       \
23874 _(one_show_petr_mode, "")                                               \
23875 _(show_one_nsh_mapping, "")                                             \
23876 _(show_one_pitr, "")                                                    \
23877 _(show_one_use_petr, "")                                                \
23878 _(show_one_map_request_mode, "")                                        \
23879 _(show_one_map_register_ttl, "")                                        \
23880 _(show_one_map_register_fallback_threshold, "")                         \
23881 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23882                             " sw_if_index <sw_if_index> p <priority> "  \
23883                             "w <weight>] [del]")                        \
23884 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23885                         "iface <intf> | sw_if_index <sw_if_index> "     \
23886                         "p <priority> w <weight> [del]")                \
23887 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23888                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23889                          "locator-set <locator_name> [del]"             \
23890                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23891 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23892 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23893 _(lisp_enable_disable, "enable|disable")                                \
23894 _(lisp_map_register_enable_disable, "enable|disable")                   \
23895 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23896 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23897                                "[seid <seid>] "                         \
23898                                "rloc <locator> p <prio> "               \
23899                                "w <weight> [rloc <loc> ... ] "          \
23900                                "action <action> [del-all]")             \
23901 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23902                           "<local-eid>")                                \
23903 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23904 _(lisp_use_petr, "<ip-address> | disable")                              \
23905 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23906 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23907 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23908 _(lisp_locator_set_dump, "[local | remote]")                            \
23909 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23910 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23911                        "[local] | [remote]")                            \
23912 _(lisp_eid_table_vni_dump, "")                                          \
23913 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23914 _(lisp_map_resolver_dump, "")                                           \
23915 _(lisp_map_server_dump, "")                                             \
23916 _(lisp_adjacencies_get, "vni <vni>")                                    \
23917 _(gpe_fwd_entry_vnis_get, "")                                           \
23918 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23919 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23920                                 "[table <table-id>]")                   \
23921 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23922 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23923 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23924 _(gpe_get_encap_mode, "")                                               \
23925 _(lisp_gpe_add_del_iface, "up|down")                                    \
23926 _(lisp_gpe_enable_disable, "enable|disable")                            \
23927 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23928   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23929 _(show_lisp_rloc_probe_state, "")                                       \
23930 _(show_lisp_map_register_state, "")                                     \
23931 _(show_lisp_status, "")                                                 \
23932 _(lisp_get_map_request_itr_rlocs, "")                                   \
23933 _(show_lisp_pitr, "")                                                   \
23934 _(show_lisp_use_petr, "")                                               \
23935 _(show_lisp_map_request_mode, "")                                       \
23936 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23937 _(af_packet_delete, "name <host interface name>")                       \
23938 _(af_packet_dump, "")                                                   \
23939 _(policer_add_del, "name <policer name> <params> [del]")                \
23940 _(policer_dump, "[name <policer name>]")                                \
23941 _(policer_classify_set_interface,                                       \
23942   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23943   "  [l2-table <nn>] [del]")                                            \
23944 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23945 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23946     "[master|slave]")                                                   \
23947 _(netmap_delete, "name <interface name>")                               \
23948 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23949 _(mpls_fib_dump, "")                                                    \
23950 _(classify_table_ids, "")                                               \
23951 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23952 _(classify_table_info, "table_id <nn>")                                 \
23953 _(classify_session_dump, "table_id <nn>")                               \
23954 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23955     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23956     "[template_interval <nn>] [udp_checksum]")                          \
23957 _(ipfix_exporter_dump, "")                                              \
23958 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23959 _(ipfix_classify_stream_dump, "")                                       \
23960 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23961 _(ipfix_classify_table_dump, "")                                        \
23962 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23963 _(sw_interface_span_dump, "[l2]")                                           \
23964 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23965 _(pg_create_interface, "if_id <nn>")                                    \
23966 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23967 _(pg_enable_disable, "[stream <id>] disable")                           \
23968 _(ip_source_and_port_range_check_add_del,                               \
23969   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23970 _(ip_source_and_port_range_check_interface_add_del,                     \
23971   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23972   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23973 _(ipsec_gre_add_del_tunnel,                                             \
23974   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23975 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23976 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23977 _(l2_interface_pbb_tag_rewrite,                                         \
23978   "<intfc> | sw_if_index <nn> \n"                                       \
23979   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23980   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23981 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23982 _(flow_classify_set_interface,                                          \
23983   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23984 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23985 _(ip_fib_dump, "")                                                      \
23986 _(ip_mfib_dump, "")                                                     \
23987 _(ip6_fib_dump, "")                                                     \
23988 _(ip6_mfib_dump, "")                                                    \
23989 _(feature_enable_disable, "arc_name <arc_name> "                        \
23990   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23991 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23992 "[disable]")                                                            \
23993 _(l2_xconnect_dump, "")                                                 \
23994 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23995 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23996 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23997 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23998 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23999 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24000 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24001   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24002 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24003 _(sock_init_shm, "size <nnn>")                                          \
24004 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24005 _(dns_enable_disable, "[enable][disable]")                              \
24006 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24007 _(dns_resolve_name, "<hostname>")                                       \
24008 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24009 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24010 _(dns_resolve_name, "<hostname>")                                       \
24011 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24012   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24013 _(session_rules_dump, "")                                               \
24014 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24015 _(output_acl_set_interface,                                             \
24016   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24017   "  [l2-table <nn>] [del]")                                            \
24018 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24019
24020 /* List of command functions, CLI names map directly to functions */
24021 #define foreach_cli_function                                    \
24022 _(comment, "usage: comment <ignore-rest-of-line>")              \
24023 _(dump_interface_table, "usage: dump_interface_table")          \
24024 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24025 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24026 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24027 _(dump_stats_table, "usage: dump_stats_table")                  \
24028 _(dump_macro_table, "usage: dump_macro_table ")                 \
24029 _(dump_node_table, "usage: dump_node_table")                    \
24030 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24031 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24032 _(echo, "usage: echo <message>")                                \
24033 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24034 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24035 _(help, "usage: help")                                          \
24036 _(q, "usage: quit")                                             \
24037 _(quit, "usage: quit")                                          \
24038 _(search_node_table, "usage: search_node_table <name>...")      \
24039 _(set, "usage: set <variable-name> <value>")                    \
24040 _(script, "usage: script <file-name>")                          \
24041 _(statseg, "usage: statseg");                                   \
24042 _(unset, "usage: unset <variable-name>")
24043
24044 #define _(N,n)                                  \
24045     static void vl_api_##n##_t_handler_uni      \
24046     (vl_api_##n##_t * mp)                       \
24047     {                                           \
24048         vat_main_t * vam = &vat_main;           \
24049         if (vam->json_output) {                 \
24050             vl_api_##n##_t_handler_json(mp);    \
24051         } else {                                \
24052             vl_api_##n##_t_handler(mp);         \
24053         }                                       \
24054     }
24055 foreach_vpe_api_reply_msg;
24056 #if VPP_API_TEST_BUILTIN == 0
24057 foreach_standalone_reply_msg;
24058 #endif
24059 #undef _
24060
24061 void
24062 vat_api_hookup (vat_main_t * vam)
24063 {
24064 #define _(N,n)                                                  \
24065     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24066                            vl_api_##n##_t_handler_uni,          \
24067                            vl_noop_handler,                     \
24068                            vl_api_##n##_t_endian,               \
24069                            vl_api_##n##_t_print,                \
24070                            sizeof(vl_api_##n##_t), 1);
24071   foreach_vpe_api_reply_msg;
24072 #if VPP_API_TEST_BUILTIN == 0
24073   foreach_standalone_reply_msg;
24074 #endif
24075 #undef _
24076
24077 #if (VPP_API_TEST_BUILTIN==0)
24078   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24079
24080   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24081
24082   vam->function_by_name = hash_create_string (0, sizeof (uword));
24083
24084   vam->help_by_name = hash_create_string (0, sizeof (uword));
24085 #endif
24086
24087   /* API messages we can send */
24088 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24089   foreach_vpe_api_msg;
24090 #undef _
24091
24092   /* Help strings */
24093 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24094   foreach_vpe_api_msg;
24095 #undef _
24096
24097   /* CLI functions */
24098 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24099   foreach_cli_function;
24100 #undef _
24101
24102   /* Help strings */
24103 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24104   foreach_cli_function;
24105 #undef _
24106 }
24107
24108 #if VPP_API_TEST_BUILTIN
24109 static clib_error_t *
24110 vat_api_hookup_shim (vlib_main_t * vm)
24111 {
24112   vat_api_hookup (&vat_main);
24113   return 0;
24114 }
24115
24116 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24117 #endif
24118
24119 /*
24120  * fd.io coding-style-patch-verification: ON
24121  *
24122  * Local Variables:
24123  * eval: (c-set-style "gnu")
24124  * End:
24125  */