virtio: fast TAP interfaces with vhost-net backend
[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 <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.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/input_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/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
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   return vl_socket_client_connect
92     (&vam->socket_client_main, (char *) vam->socket_name,
93      "vpp_api_test(s)", 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 void
103 vl_socket_client_read_reply (socket_client_main_t * scm)
104 {
105 };
106 #endif
107
108
109 f64
110 vat_time_now (vat_main_t * vam)
111 {
112 #if VPP_API_TEST_BUILTIN
113   return vlib_time_now (vam->vlib_main);
114 #else
115   return clib_time_now (&vam->clib_time);
116 #endif
117 }
118
119 void
120 errmsg (char *fmt, ...)
121 {
122   vat_main_t *vam = &vat_main;
123   va_list va;
124   u8 *s;
125
126   va_start (va, fmt);
127   s = va_format (0, fmt, &va);
128   va_end (va);
129
130   vec_add1 (s, 0);
131
132 #if VPP_API_TEST_BUILTIN
133   vlib_cli_output (vam->vlib_main, (char *) s);
134 #else
135   {
136     if (vam->ifp != stdin)
137       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
138                vam->input_line_number);
139     fformat (vam->ofp, (char *) s);
140     fflush (vam->ofp);
141   }
142 #endif
143
144   vec_free (s);
145 }
146
147 #if VPP_API_TEST_BUILTIN == 0
148 static uword
149 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
150 {
151   vat_main_t *vam = va_arg (*args, vat_main_t *);
152   u32 *result = va_arg (*args, u32 *);
153   u8 *if_name;
154   uword *p;
155
156   if (!unformat (input, "%s", &if_name))
157     return 0;
158
159   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
160   if (p == 0)
161     return 0;
162   *result = p[0];
163   return 1;
164 }
165
166 /* Parse an IP4 address %d.%d.%d.%d. */
167 uword
168 unformat_ip4_address (unformat_input_t * input, va_list * args)
169 {
170   u8 *result = va_arg (*args, u8 *);
171   unsigned a[4];
172
173   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
174     return 0;
175
176   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
177     return 0;
178
179   result[0] = a[0];
180   result[1] = a[1];
181   result[2] = a[2];
182   result[3] = a[3];
183
184   return 1;
185 }
186
187 uword
188 unformat_ethernet_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   u32 i, a[6];
192
193   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
194                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
195     return 0;
196
197   /* Check range. */
198   for (i = 0; i < 6; i++)
199     if (a[i] >= (1 << 8))
200       return 0;
201
202   for (i = 0; i < 6; i++)
203     result[i] = a[i];
204
205   return 1;
206 }
207
208 /* Returns ethernet type as an int in host byte order. */
209 uword
210 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
211                                         va_list * args)
212 {
213   u16 *result = va_arg (*args, u16 *);
214   int type;
215
216   /* Numeric type. */
217   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
218     {
219       if (type >= (1 << 16))
220         return 0;
221       *result = type;
222       return 1;
223     }
224   return 0;
225 }
226
227 /* Parse an IP6 address. */
228 uword
229 unformat_ip6_address (unformat_input_t * input, va_list * args)
230 {
231   ip6_address_t *result = va_arg (*args, ip6_address_t *);
232   u16 hex_quads[8];
233   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
234   uword c, n_colon, double_colon_index;
235
236   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
237   double_colon_index = ARRAY_LEN (hex_quads);
238   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
239     {
240       hex_digit = 16;
241       if (c >= '0' && c <= '9')
242         hex_digit = c - '0';
243       else if (c >= 'a' && c <= 'f')
244         hex_digit = c + 10 - 'a';
245       else if (c >= 'A' && c <= 'F')
246         hex_digit = c + 10 - 'A';
247       else if (c == ':' && n_colon < 2)
248         n_colon++;
249       else
250         {
251           unformat_put_input (input);
252           break;
253         }
254
255       /* Too many hex quads. */
256       if (n_hex_quads >= ARRAY_LEN (hex_quads))
257         return 0;
258
259       if (hex_digit < 16)
260         {
261           hex_quad = (hex_quad << 4) | hex_digit;
262
263           /* Hex quad must fit in 16 bits. */
264           if (n_hex_digits >= 4)
265             return 0;
266
267           n_colon = 0;
268           n_hex_digits++;
269         }
270
271       /* Save position of :: */
272       if (n_colon == 2)
273         {
274           /* More than one :: ? */
275           if (double_colon_index < ARRAY_LEN (hex_quads))
276             return 0;
277           double_colon_index = n_hex_quads;
278         }
279
280       if (n_colon > 0 && n_hex_digits > 0)
281         {
282           hex_quads[n_hex_quads++] = hex_quad;
283           hex_quad = 0;
284           n_hex_digits = 0;
285         }
286     }
287
288   if (n_hex_digits > 0)
289     hex_quads[n_hex_quads++] = hex_quad;
290
291   {
292     word i;
293
294     /* Expand :: to appropriate number of zero hex quads. */
295     if (double_colon_index < ARRAY_LEN (hex_quads))
296       {
297         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
298
299         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
300           hex_quads[n_zero + i] = hex_quads[i];
301
302         for (i = 0; i < n_zero; i++)
303           hex_quads[double_colon_index + i] = 0;
304
305         n_hex_quads = ARRAY_LEN (hex_quads);
306       }
307
308     /* Too few hex quads given. */
309     if (n_hex_quads < ARRAY_LEN (hex_quads))
310       return 0;
311
312     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
313       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
314
315     return 1;
316   }
317 }
318
319 uword
320 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
321 {
322   u32 *r = va_arg (*args, u32 *);
323
324   if (0);
325 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
326   foreach_ipsec_policy_action
327 #undef _
328     else
329     return 0;
330   return 1;
331 }
332
333 uword
334 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
340   foreach_ipsec_crypto_alg
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 u8 *
348 format_ipsec_crypto_alg (u8 * s, va_list * args)
349 {
350   u32 i = va_arg (*args, u32);
351   u8 *t = 0;
352
353   switch (i)
354     {
355 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
356       foreach_ipsec_crypto_alg
357 #undef _
358     default:
359       return format (s, "unknown");
360     }
361   return format (s, "%s", t);
362 }
363
364 uword
365 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
371   foreach_ipsec_integ_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_integ_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_integ_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
402   foreach_ikev2_auth_method
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
416   foreach_ikev2_id_type
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422 #else /* VPP_API_TEST_BUILTIN == 1 */
423 static uword
424 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
425 {
426   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
427   vnet_main_t *vnm = vnet_get_main ();
428   u32 *result = va_arg (*args, u32 *);
429   u32 sw_if_index;
430
431   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
432     return 0;
433
434   *result = sw_if_index;
435   return 1;
436 }
437 #endif /* VPP_API_TEST_BUILTIN */
438
439 static uword
440 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
441 {
442   u8 *r = va_arg (*args, u8 *);
443
444   if (unformat (input, "kbps"))
445     *r = SSE2_QOS_RATE_KBPS;
446   else if (unformat (input, "pps"))
447     *r = SSE2_QOS_RATE_PPS;
448   else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_round_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "closest"))
459     *r = SSE2_QOS_ROUND_TO_CLOSEST;
460   else if (unformat (input, "up"))
461     *r = SSE2_QOS_ROUND_TO_UP;
462   else if (unformat (input, "down"))
463     *r = SSE2_QOS_ROUND_TO_DOWN;
464   else
465     return 0;
466   return 1;
467 }
468
469 static uword
470 unformat_policer_type (unformat_input_t * input, va_list * args)
471 {
472   u8 *r = va_arg (*args, u8 *);
473
474   if (unformat (input, "1r2c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R2C;
476   else if (unformat (input, "1r3c"))
477     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
478   else if (unformat (input, "2r3c-2698"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
480   else if (unformat (input, "2r3c-4115"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
482   else if (unformat (input, "2r3c-mef5cf1"))
483     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_dscp (unformat_input_t * input, va_list * va)
491 {
492   u8 *r = va_arg (*va, u8 *);
493
494   if (0);
495 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
496   foreach_vnet_dscp
497 #undef _
498     else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_action_type (unformat_input_t * input, va_list * va)
505 {
506   sse2_qos_pol_action_params_st *a
507     = va_arg (*va, sse2_qos_pol_action_params_st *);
508
509   if (unformat (input, "drop"))
510     a->action_type = SSE2_QOS_ACTION_DROP;
511   else if (unformat (input, "transmit"))
512     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
513   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
514     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
515   else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
522 {
523   u32 *r = va_arg (*va, u32 *);
524   u32 tid;
525
526   if (unformat (input, "ip4"))
527     tid = POLICER_CLASSIFY_TABLE_IP4;
528   else if (unformat (input, "ip6"))
529     tid = POLICER_CLASSIFY_TABLE_IP6;
530   else if (unformat (input, "l2"))
531     tid = POLICER_CLASSIFY_TABLE_L2;
532   else
533     return 0;
534
535   *r = tid;
536   return 1;
537 }
538
539 static uword
540 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = FLOW_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = FLOW_CLASSIFY_TABLE_IP6;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
557 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
558 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
559 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
560
561 #if (VPP_API_TEST_BUILTIN==0)
562 uword
563 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
564 {
565   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
566   mfib_itf_attribute_t attr;
567
568   old = *iflags;
569   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
570   {
571     if (unformat (input, mfib_itf_flag_long_names[attr]))
572       *iflags |= (1 << attr);
573   }
574   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
575   {
576     if (unformat (input, mfib_itf_flag_names[attr]))
577       *iflags |= (1 << attr);
578   }
579
580   return (old == *iflags ? 0 : 1);
581 }
582
583 uword
584 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
587   mfib_entry_attribute_t attr;
588
589   old = *eflags;
590   FOR_EACH_MFIB_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_flag_long_names[attr]))
593       *eflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_flag_names[attr]))
598       *eflags |= (1 << attr);
599   }
600
601   return (old == *eflags ? 0 : 1);
602 }
603
604 u8 *
605 format_ip4_address (u8 * s, va_list * args)
606 {
607   u8 *a = va_arg (*args, u8 *);
608   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
609 }
610
611 u8 *
612 format_ip6_address (u8 * s, va_list * args)
613 {
614   ip6_address_t *a = va_arg (*args, ip6_address_t *);
615   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
616
617   i_max_n_zero = ARRAY_LEN (a->as_u16);
618   max_n_zeros = 0;
619   i_first_zero = i_max_n_zero;
620   n_zeros = 0;
621   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
622     {
623       u32 is_zero = a->as_u16[i] == 0;
624       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
625         {
626           i_first_zero = i;
627           n_zeros = 0;
628         }
629       n_zeros += is_zero;
630       if ((!is_zero && n_zeros > max_n_zeros)
631           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
632         {
633           i_max_n_zero = i_first_zero;
634           max_n_zeros = n_zeros;
635           i_first_zero = ARRAY_LEN (a->as_u16);
636           n_zeros = 0;
637         }
638     }
639
640   last_double_colon = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       if (i == i_max_n_zero && max_n_zeros > 1)
644         {
645           s = format (s, "::");
646           i += max_n_zeros - 1;
647           last_double_colon = 1;
648         }
649       else
650         {
651           s = format (s, "%s%x",
652                       (last_double_colon || i == 0) ? "" : ":",
653                       clib_net_to_host_u16 (a->as_u16[i]));
654           last_double_colon = 0;
655         }
656     }
657
658   return s;
659 }
660
661 /* Format an IP46 address. */
662 u8 *
663 format_ip46_address (u8 * s, va_list * args)
664 {
665   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
666   ip46_type_t type = va_arg (*args, ip46_type_t);
667   int is_ip4 = 1;
668
669   switch (type)
670     {
671     case IP46_TYPE_ANY:
672       is_ip4 = ip46_address_is_ip4 (ip46);
673       break;
674     case IP46_TYPE_IP4:
675       is_ip4 = 1;
676       break;
677     case IP46_TYPE_IP6:
678       is_ip4 = 0;
679       break;
680     }
681
682   return is_ip4 ?
683     format (s, "%U", format_ip4_address, &ip46->ip4) :
684     format (s, "%U", format_ip6_address, &ip46->ip6);
685 }
686
687 u8 *
688 format_ethernet_address (u8 * s, va_list * args)
689 {
690   u8 *a = va_arg (*args, u8 *);
691
692   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
693                  a[0], a[1], a[2], a[3], a[4], a[5]);
694 }
695 #endif
696
697 static void
698 increment_v4_address (ip4_address_t * a)
699 {
700   u32 v;
701
702   v = ntohl (a->as_u32) + 1;
703   a->as_u32 = ntohl (v);
704 }
705
706 static void
707 increment_v6_address (ip6_address_t * a)
708 {
709   u64 v0, v1;
710
711   v0 = clib_net_to_host_u64 (a->as_u64[0]);
712   v1 = clib_net_to_host_u64 (a->as_u64[1]);
713
714   v1 += 1;
715   if (v1 == 0)
716     v0 += 1;
717   a->as_u64[0] = clib_net_to_host_u64 (v0);
718   a->as_u64[1] = clib_net_to_host_u64 (v1);
719 }
720
721 static void
722 increment_mac_address (u8 * mac)
723 {
724   u64 tmp = *((u64 *) mac);
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728
729   clib_memcpy (mac, &tmp, 6);
730 }
731
732 static void vl_api_create_loopback_reply_t_handler
733   (vl_api_create_loopback_reply_t * mp)
734 {
735   vat_main_t *vam = &vat_main;
736   i32 retval = ntohl (mp->retval);
737
738   vam->retval = retval;
739   vam->regenerate_interface_table = 1;
740   vam->sw_if_index = ntohl (mp->sw_if_index);
741   vam->result_ready = 1;
742 }
743
744 static void vl_api_create_loopback_reply_t_handler_json
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   vat_json_node_t node;
749
750   vat_json_init_object (&node);
751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
753
754   vat_json_print (vam->ofp, &node);
755   vat_json_free (&node);
756   vam->retval = ntohl (mp->retval);
757   vam->result_ready = 1;
758 }
759
760 static void vl_api_create_loopback_instance_reply_t_handler
761   (vl_api_create_loopback_instance_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler_json
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_af_packet_create_reply_t_handler
789   (vl_api_af_packet_create_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler_json
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_create_vlan_subif_reply_t_handler
818   (vl_api_create_vlan_subif_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler_json
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_subif_reply_t_handler
847   (vl_api_create_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler_json
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_interface_name_renumber_reply_t_handler
876   (vl_api_interface_name_renumber_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_interface_name_renumber_reply_t_handler_json
887   (vl_api_interface_name_renumber_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894
895   vat_json_print (vam->ofp, &node);
896   vat_json_free (&node);
897
898   vam->retval = ntohl (mp->retval);
899   vam->result_ready = 1;
900 }
901
902 /*
903  * Special-case: build the interface table, maintain
904  * the next loopback sw_if_index vbl.
905  */
906 static void vl_api_sw_interface_details_t_handler
907   (vl_api_sw_interface_details_t * mp)
908 {
909   vat_main_t *vam = &vat_main;
910   u8 *s = format (0, "%s%c", mp->interface_name, 0);
911
912   hash_set_mem (vam->sw_if_index_by_interface_name, s,
913                 ntohl (mp->sw_if_index));
914
915   /* In sub interface case, fill the sub interface table entry */
916   if (mp->sw_if_index != mp->sup_sw_if_index)
917     {
918       sw_interface_subif_t *sub = NULL;
919
920       vec_add2 (vam->sw_if_subif_table, sub, 1);
921
922       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
923       strncpy ((char *) sub->interface_name, (char *) s,
924                vec_len (sub->interface_name));
925       sub->sw_if_index = ntohl (mp->sw_if_index);
926       sub->sub_id = ntohl (mp->sub_id);
927
928       sub->sub_dot1ad = mp->sub_dot1ad;
929       sub->sub_number_of_tags = mp->sub_number_of_tags;
930       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
931       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
932       sub->sub_exact_match = mp->sub_exact_match;
933       sub->sub_default = mp->sub_default;
934       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
935       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
936
937       /* vlan tag rewrite */
938       sub->vtr_op = ntohl (mp->vtr_op);
939       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
940       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
941       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
942     }
943 }
944
945 static void vl_api_sw_interface_details_t_handler_json
946   (vl_api_sw_interface_details_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t *node = NULL;
950
951   if (VAT_JSON_ARRAY != vam->json_tree.type)
952     {
953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
954       vat_json_init_array (&vam->json_tree);
955     }
956   node = vat_json_array_add (&vam->json_tree);
957
958   vat_json_init_object (node);
959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
960   vat_json_object_add_uint (node, "sup_sw_if_index",
961                             ntohl (mp->sup_sw_if_index));
962   vat_json_object_add_uint (node, "l2_address_length",
963                             ntohl (mp->l2_address_length));
964   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
965                              sizeof (mp->l2_address));
966   vat_json_object_add_string_copy (node, "interface_name",
967                                    mp->interface_name);
968   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
969   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
970   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
971   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
972   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
973   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
974   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
975   vat_json_object_add_uint (node, "sub_number_of_tags",
976                             mp->sub_number_of_tags);
977   vat_json_object_add_uint (node, "sub_outer_vlan_id",
978                             ntohs (mp->sub_outer_vlan_id));
979   vat_json_object_add_uint (node, "sub_inner_vlan_id",
980                             ntohs (mp->sub_inner_vlan_id));
981   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
982   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
983   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
984                             mp->sub_outer_vlan_id_any);
985   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
986                             mp->sub_inner_vlan_id_any);
987   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
988   vat_json_object_add_uint (node, "vtr_push_dot1q",
989                             ntohl (mp->vtr_push_dot1q));
990   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
991   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
992   if (mp->sub_dot1ah)
993     {
994       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
995                                        format (0, "%U",
996                                                format_ethernet_address,
997                                                &mp->b_dmac));
998       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
999                                        format (0, "%U",
1000                                                format_ethernet_address,
1001                                                &mp->b_smac));
1002       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1003       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1004     }
1005 }
1006
1007 #if VPP_API_TEST_BUILTIN == 0
1008 static void vl_api_sw_interface_event_t_handler
1009   (vl_api_sw_interface_event_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   if (vam->interface_event_display)
1013     errmsg ("interface flags: sw_if_index %d %s %s",
1014             ntohl (mp->sw_if_index),
1015             mp->admin_up_down ? "admin-up" : "admin-down",
1016             mp->link_up_down ? "link-up" : "link-down");
1017 }
1018 #endif
1019
1020 static void vl_api_sw_interface_event_t_handler_json
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   /* JSON output not supported */
1024 }
1025
1026 static void
1027 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031
1032   vam->retval = retval;
1033   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void
1038 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   vat_json_node_t node;
1042   api_main_t *am = &api_main;
1043   void *oldheap;
1044   u8 *reply;
1045
1046   vat_json_init_object (&node);
1047   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1048   vat_json_object_add_uint (&node, "reply_in_shmem",
1049                             ntohl (mp->reply_in_shmem));
1050   /* Toss the shared-memory original... */
1051   pthread_mutex_lock (&am->vlib_rp->mutex);
1052   oldheap = svm_push_data_heap (am->vlib_rp);
1053
1054   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1055   vec_free (reply);
1056
1057   svm_pop_heap (oldheap);
1058   pthread_mutex_unlock (&am->vlib_rp->mutex);
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void
1068 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   u32 length = ntohl (mp->length);
1073
1074   vec_reset_length (vam->cmd_reply);
1075
1076   vam->retval = retval;
1077   if (retval == 0)
1078     {
1079       vec_validate (vam->cmd_reply, length);
1080       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void vl_api_classify_add_del_table_reply_t_handler
1106   (vl_api_classify_add_del_table_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   i32 retval = ntohl (mp->retval);
1110   if (vam->async_mode)
1111     {
1112       vam->async_errors += (retval < 0);
1113     }
1114   else
1115     {
1116       vam->retval = retval;
1117       if (retval == 0 &&
1118           ((mp->new_table_index != 0xFFFFFFFF) ||
1119            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1120            (mp->match_n_vectors != 0xFFFFFFFF)))
1121         /*
1122          * Note: this is just barely thread-safe, depends on
1123          * the main thread spinning waiting for an answer...
1124          */
1125         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1126                 ntohl (mp->new_table_index),
1127                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1128       vam->result_ready = 1;
1129     }
1130 }
1131
1132 static void vl_api_classify_add_del_table_reply_t_handler_json
1133   (vl_api_classify_add_del_table_reply_t * mp)
1134 {
1135   vat_main_t *vam = &vat_main;
1136   vat_json_node_t node;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "new_table_index",
1141                             ntohl (mp->new_table_index));
1142   vat_json_object_add_uint (&node, "skip_n_vectors",
1143                             ntohl (mp->skip_n_vectors));
1144   vat_json_object_add_uint (&node, "match_n_vectors",
1145                             ntohl (mp->match_n_vectors));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_get_node_index_reply_t_handler
1155   (vl_api_get_node_index_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("node index %d", ntohl (mp->node_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_get_node_index_reply_t_handler_json
1173   (vl_api_get_node_index_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_next_index_reply_t_handler
1190   (vl_api_get_next_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("next node index %d", ntohl (mp->next_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_next_index_reply_t_handler_json
1208   (vl_api_get_next_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_add_node_next_reply_t_handler
1225   (vl_api_add_node_next_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_add_node_next_reply_t_handler_json
1243   (vl_api_add_node_next_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_show_version_reply_t_handler
1260   (vl_api_show_version_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264
1265   if (retval >= 0)
1266     {
1267       errmsg ("        program: %s", mp->program);
1268       errmsg ("        version: %s", mp->version);
1269       errmsg ("     build date: %s", mp->build_date);
1270       errmsg ("build directory: %s", mp->build_directory);
1271     }
1272   vam->retval = retval;
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_show_version_reply_t_handler_json
1277   (vl_api_show_version_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_string_copy (&node, "program", mp->program);
1285   vat_json_object_add_string_copy (&node, "version", mp->version);
1286   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1287   vat_json_object_add_string_copy (&node, "build_directory",
1288                                    mp->build_directory);
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void
1298 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1299 {
1300   u32 sw_if_index = ntohl (mp->sw_if_index);
1301   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1302           mp->mac_ip ? "mac/ip binding" : "address resolution",
1303           ntohl (mp->pid), format_ip4_address, &mp->address,
1304           format_ethernet_address, mp->new_mac, sw_if_index);
1305 }
1306
1307 static void
1308 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1309 {
1310   /* JSON output not supported */
1311 }
1312
1313 static void
1314 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1315 {
1316   u32 sw_if_index = ntohl (mp->sw_if_index);
1317   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1318           mp->mac_ip ? "mac/ip binding" : "address resolution",
1319           ntohl (mp->pid), format_ip6_address, mp->address,
1320           format_ethernet_address, mp->new_mac, sw_if_index);
1321 }
1322
1323 static void
1324 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1325 {
1326   /* JSON output not supported */
1327 }
1328
1329 static void
1330 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1331 {
1332   u32 n_macs = ntohl (mp->n_macs);
1333   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1334           ntohl (mp->pid), mp->client_index, n_macs);
1335   int i;
1336   for (i = 0; i < n_macs; i++)
1337     {
1338       vl_api_mac_entry_t *mac = &mp->mac[i];
1339       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1340               i + 1, ntohl (mac->sw_if_index),
1341               format_ethernet_address, mac->mac_addr, mac->is_del);
1342       if (i == 1000)
1343         break;
1344     }
1345 }
1346
1347 static void
1348 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1349 {
1350   /* JSON output not supported */
1351 }
1352
1353 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1354 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1355
1356 /*
1357  * Special-case: build the bridge domain table, maintain
1358  * the next bd id vbl.
1359  */
1360 static void vl_api_bridge_domain_details_t_handler
1361   (vl_api_bridge_domain_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1365   int i;
1366
1367   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1368          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1369
1370   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1371          ntohl (mp->bd_id), mp->learn, mp->forward,
1372          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1373
1374   if (n_sw_ifs)
1375     {
1376       vl_api_bridge_domain_sw_if_t *sw_ifs;
1377       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1378              "Interface Name");
1379
1380       sw_ifs = mp->sw_if_details;
1381       for (i = 0; i < n_sw_ifs; i++)
1382         {
1383           u8 *sw_if_name = 0;
1384           u32 sw_if_index;
1385           hash_pair_t *p;
1386
1387           sw_if_index = ntohl (sw_ifs->sw_if_index);
1388
1389           /* *INDENT-OFF* */
1390           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1391                              ({
1392                                if ((u32) p->value[0] == sw_if_index)
1393                                  {
1394                                    sw_if_name = (u8 *)(p->key);
1395                                    break;
1396                                  }
1397                              }));
1398           /* *INDENT-ON* */
1399           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1400                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1401                  "sw_if_index not found!");
1402
1403           sw_ifs++;
1404         }
1405     }
1406 }
1407
1408 static void vl_api_bridge_domain_details_t_handler_json
1409   (vl_api_bridge_domain_details_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t *node, *array = NULL;
1413   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1414
1415   if (VAT_JSON_ARRAY != vam->json_tree.type)
1416     {
1417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1418       vat_json_init_array (&vam->json_tree);
1419     }
1420   node = vat_json_array_add (&vam->json_tree);
1421
1422   vat_json_init_object (node);
1423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1424   vat_json_object_add_uint (node, "flood", mp->flood);
1425   vat_json_object_add_uint (node, "forward", mp->forward);
1426   vat_json_object_add_uint (node, "learn", mp->learn);
1427   vat_json_object_add_uint (node, "bvi_sw_if_index",
1428                             ntohl (mp->bvi_sw_if_index));
1429   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1430   array = vat_json_object_add (node, "sw_if");
1431   vat_json_init_array (array);
1432
1433
1434
1435   if (n_sw_ifs)
1436     {
1437       vl_api_bridge_domain_sw_if_t *sw_ifs;
1438       int i;
1439
1440       sw_ifs = mp->sw_if_details;
1441       for (i = 0; i < n_sw_ifs; i++)
1442         {
1443           node = vat_json_array_add (array);
1444           vat_json_init_object (node);
1445           vat_json_object_add_uint (node, "sw_if_index",
1446                                     ntohl (sw_ifs->sw_if_index));
1447           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1448           sw_ifs++;
1449         }
1450     }
1451 }
1452
1453 static void vl_api_control_ping_reply_t_handler
1454   (vl_api_control_ping_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467   vam->socket_client_main.control_pings_outstanding--;
1468 }
1469
1470 static void vl_api_control_ping_reply_t_handler_json
1471   (vl_api_control_ping_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   i32 retval = ntohl (mp->retval);
1475
1476   if (VAT_JSON_NONE != vam->json_tree.type)
1477     {
1478       vat_json_print (vam->ofp, &vam->json_tree);
1479       vat_json_free (&vam->json_tree);
1480       vam->json_tree.type = VAT_JSON_NONE;
1481     }
1482   else
1483     {
1484       /* just print [] */
1485       vat_json_init_array (&vam->json_tree);
1486       vat_json_print (vam->ofp, &vam->json_tree);
1487       vam->json_tree.type = VAT_JSON_NONE;
1488     }
1489
1490   vam->retval = retval;
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495   vl_api_bridge_domain_set_mac_age_reply_t_handler
1496   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1512   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void
1528 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->result_ready = 1;
1540     }
1541 }
1542
1543 static void vl_api_l2_flags_reply_t_handler_json
1544   (vl_api_l2_flags_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t node;
1548
1549   vat_json_init_object (&node);
1550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1551   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1552                             ntohl (mp->resulting_feature_bitmap));
1553
1554   vat_json_print (vam->ofp, &node);
1555   vat_json_free (&node);
1556
1557   vam->retval = ntohl (mp->retval);
1558   vam->result_ready = 1;
1559 }
1560
1561 static void vl_api_bridge_flags_reply_t_handler
1562   (vl_api_bridge_flags_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   i32 retval = ntohl (mp->retval);
1566   if (vam->async_mode)
1567     {
1568       vam->async_errors += (retval < 0);
1569     }
1570   else
1571     {
1572       vam->retval = retval;
1573       vam->result_ready = 1;
1574     }
1575 }
1576
1577 static void vl_api_bridge_flags_reply_t_handler_json
1578   (vl_api_bridge_flags_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   vat_json_node_t node;
1582
1583   vat_json_init_object (&node);
1584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1585   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1586                             ntohl (mp->resulting_feature_bitmap));
1587
1588   vat_json_print (vam->ofp, &node);
1589   vat_json_free (&node);
1590
1591   vam->retval = ntohl (mp->retval);
1592   vam->result_ready = 1;
1593 }
1594
1595 static void vl_api_tap_connect_reply_t_handler
1596   (vl_api_tap_connect_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->sw_if_index = ntohl (mp->sw_if_index);
1608       vam->result_ready = 1;
1609     }
1610
1611 }
1612
1613 static void vl_api_tap_connect_reply_t_handler_json
1614   (vl_api_tap_connect_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628
1629 }
1630
1631 static void
1632 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->sw_if_index = ntohl (mp->sw_if_index);
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_modify_reply_t_handler_json
1649   (vl_api_tap_modify_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_tap_delete_reply_t_handler_json
1682   (vl_api_tap_delete_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void
1698 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->sw_if_index = ntohl (mp->sw_if_index);
1710       vam->result_ready = 1;
1711     }
1712
1713 }
1714
1715 static void vl_api_tap_create_v2_reply_t_handler_json
1716   (vl_api_tap_create_v2_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730
1731 }
1732
1733 static void
1734 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_delete_v2_reply_t_handler_json
1750   (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1766   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1782   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1790                             ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1800   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1817   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1834   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1850   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "fwd_entry_index",
1858                             clib_net_to_host_u32 (mp->fwd_entry_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 u8 *
1868 format_lisp_transport_protocol (u8 * s, va_list * args)
1869 {
1870   u32 proto = va_arg (*args, u32);
1871
1872   switch (proto)
1873     {
1874     case 1:
1875       return format (s, "udp");
1876     case 2:
1877       return format (s, "api");
1878     default:
1879       return 0;
1880     }
1881   return 0;
1882 }
1883
1884 static void vl_api_one_get_transport_protocol_reply_t_handler
1885   (vl_api_one_get_transport_protocol_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   i32 retval = ntohl (mp->retval);
1889   if (vam->async_mode)
1890     {
1891       vam->async_errors += (retval < 0);
1892     }
1893   else
1894     {
1895       u32 proto = mp->protocol;
1896       print (vam->ofp, "Transport protocol: %U",
1897              format_lisp_transport_protocol, proto);
1898       vam->retval = retval;
1899       vam->result_ready = 1;
1900     }
1901 }
1902
1903 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1904   (vl_api_one_get_transport_protocol_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   vat_json_node_t node;
1908   u8 *s;
1909
1910   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1911   vec_add1 (s, 0);
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1916
1917   vec_free (s);
1918   vat_json_print (vam->ofp, &node);
1919   vat_json_free (&node);
1920
1921   vam->retval = ntohl (mp->retval);
1922   vam->result_ready = 1;
1923 }
1924
1925 static void vl_api_one_add_del_locator_set_reply_t_handler
1926   (vl_api_one_add_del_locator_set_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   i32 retval = ntohl (mp->retval);
1930   if (vam->async_mode)
1931     {
1932       vam->async_errors += (retval < 0);
1933     }
1934   else
1935     {
1936       vam->retval = retval;
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1942   (vl_api_one_add_del_locator_set_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   vat_json_node_t node;
1946
1947   vat_json_init_object (&node);
1948   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1949   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1950
1951   vat_json_print (vam->ofp, &node);
1952   vat_json_free (&node);
1953
1954   vam->retval = ntohl (mp->retval);
1955   vam->result_ready = 1;
1956 }
1957
1958 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   i32 retval = ntohl (mp->retval);
1963   if (vam->async_mode)
1964     {
1965       vam->async_errors += (retval < 0);
1966     }
1967   else
1968     {
1969       vam->retval = retval;
1970       vam->sw_if_index = ntohl (mp->sw_if_index);
1971       vam->result_ready = 1;
1972     }
1973 }
1974
1975 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   vat_json_node_t node;
1980
1981   vat_json_init_object (&node);
1982   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1983   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1984
1985   vat_json_print (vam->ofp, &node);
1986   vat_json_free (&node);
1987
1988   vam->retval = ntohl (mp->retval);
1989   vam->result_ready = 1;
1990 }
1991
1992 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1993   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   i32 retval = ntohl (mp->retval);
1997   if (vam->async_mode)
1998     {
1999       vam->async_errors += (retval < 0);
2000     }
2001   else
2002     {
2003       vam->retval = retval;
2004       vam->sw_if_index = ntohl (mp->sw_if_index);
2005       vam->result_ready = 1;
2006     }
2007 }
2008
2009 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2010   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t node;
2014
2015   vat_json_init_object (&node);
2016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2017   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2018
2019   vat_json_print (vam->ofp, &node);
2020   vat_json_free (&node);
2021
2022   vam->retval = ntohl (mp->retval);
2023   vam->result_ready = 1;
2024 }
2025
2026 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2027   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   i32 retval = ntohl (mp->retval);
2031   if (vam->async_mode)
2032     {
2033       vam->async_errors += (retval < 0);
2034     }
2035   else
2036     {
2037       vam->retval = retval;
2038       vam->sw_if_index = ntohl (mp->sw_if_index);
2039       vam->result_ready = 1;
2040     }
2041 }
2042
2043 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2044   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vat_json_node_t node;
2048
2049   vat_json_init_object (&node);
2050   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2051   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2052
2053   vat_json_print (vam->ofp, &node);
2054   vat_json_free (&node);
2055
2056   vam->retval = ntohl (mp->retval);
2057   vam->result_ready = 1;
2058 }
2059
2060 static void vl_api_gre_add_del_tunnel_reply_t_handler
2061   (vl_api_gre_add_del_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2078   (vl_api_gre_add_del_tunnel_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "sw_if_index", 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_create_vhost_user_if_reply_t_handler
2095   (vl_api_create_vhost_user_if_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_create_vhost_user_if_reply_t_handler_json
2112   (vl_api_create_vhost_user_if_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 clib_error_t *
2129 receive_fd_msg (int socket_fd, int *my_fd)
2130 {
2131   char msgbuf[16];
2132   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2133   struct msghdr mh = { 0 };
2134   struct iovec iov[1];
2135   ssize_t size;
2136   struct ucred *cr = 0;
2137   struct cmsghdr *cmsg;
2138   pid_t pid __attribute__ ((unused));
2139   uid_t uid __attribute__ ((unused));
2140   gid_t gid __attribute__ ((unused));
2141
2142   iov[0].iov_base = msgbuf;
2143   iov[0].iov_len = 5;
2144   mh.msg_iov = iov;
2145   mh.msg_iovlen = 1;
2146   mh.msg_control = ctl;
2147   mh.msg_controllen = sizeof (ctl);
2148
2149   memset (ctl, 0, sizeof (ctl));
2150
2151   /* receive the incoming message */
2152   size = recvmsg (socket_fd, &mh, 0);
2153   if (size != 5)
2154     {
2155       return (size == 0) ? clib_error_return (0, "disconnected") :
2156         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2157                                 socket_fd);
2158     }
2159
2160   cmsg = CMSG_FIRSTHDR (&mh);
2161   while (cmsg)
2162     {
2163       if (cmsg->cmsg_level == SOL_SOCKET)
2164         {
2165           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2166             {
2167               cr = (struct ucred *) CMSG_DATA (cmsg);
2168               uid = cr->uid;
2169               gid = cr->gid;
2170               pid = cr->pid;
2171             }
2172           else if (cmsg->cmsg_type == SCM_RIGHTS)
2173             {
2174               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2175             }
2176         }
2177       cmsg = CMSG_NXTHDR (&mh, cmsg);
2178     }
2179   return 0;
2180 }
2181
2182 static void vl_api_memfd_segment_create_reply_t_handler
2183   (vl_api_memfd_segment_create_reply_t * mp)
2184 {
2185   /* Dont bother in the builtin version */
2186 #if VPP_API_TEST_BUILTIN == 0
2187   vat_main_t *vam = &vat_main;
2188   api_main_t *am = &api_main;
2189   socket_client_main_t *scm = &vam->socket_client_main;
2190   int my_fd = -1;
2191   clib_error_t *error;
2192   memfd_private_t memfd;
2193   i32 retval = ntohl (mp->retval);
2194
2195   if (retval == 0)
2196     {
2197       error = receive_fd_msg (scm->socket_fd, &my_fd);
2198       if (error)
2199         {
2200           retval = -99;
2201           goto out;
2202         }
2203
2204       memset (&memfd, 0, sizeof (memfd));
2205       memfd.fd = my_fd;
2206
2207       vam->client_index_invalid = 1;
2208
2209       /* Note: this closes memfd.fd */
2210       retval = memfd_slave_init (&memfd);
2211       if (retval)
2212         clib_warning ("WARNING: segment map returned %d", retval);
2213
2214       /* Pivot to the memory client segment that vpp just created */
2215
2216       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2217
2218       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2219
2220       vl_client_install_client_message_handlers ();
2221
2222       vl_client_connect_to_vlib_no_map ("pvt",
2223                                         "vpp_api_test(p)",
2224                                         32 /* input_queue_length */ );
2225       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2226
2227       vl_socket_client_enable_disable (&vam->socket_client_main,
2228                                        0 /* disable socket */ );
2229     }
2230
2231 out:
2232   if (vam->async_mode)
2233     {
2234       vam->async_errors += (retval < 0);
2235     }
2236   else
2237     {
2238       vam->retval = retval;
2239       vam->result_ready = 1;
2240     }
2241 #endif
2242 }
2243
2244 static void vl_api_memfd_segment_create_reply_t_handler_json
2245   (vl_api_memfd_segment_create_reply_t * mp)
2246 {
2247   clib_warning ("no");
2248 }
2249
2250 static void vl_api_dns_resolve_name_reply_t_handler
2251   (vl_api_dns_resolve_name_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263
2264       if (retval == 0)
2265         {
2266           if (mp->ip4_set)
2267             clib_warning ("ip4 address %U", format_ip4_address,
2268                           (ip4_address_t *) mp->ip4_address);
2269           if (mp->ip6_set)
2270             clib_warning ("ip6 address %U", format_ip6_address,
2271                           (ip6_address_t *) mp->ip6_address);
2272         }
2273       else
2274         clib_warning ("retval %d", retval);
2275     }
2276 }
2277
2278 static void vl_api_dns_resolve_name_reply_t_handler_json
2279   (vl_api_dns_resolve_name_reply_t * mp)
2280 {
2281   clib_warning ("not implemented");
2282 }
2283
2284 static void vl_api_dns_resolve_ip_reply_t_handler
2285   (vl_api_dns_resolve_ip_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   i32 retval = ntohl (mp->retval);
2289   if (vam->async_mode)
2290     {
2291       vam->async_errors += (retval < 0);
2292     }
2293   else
2294     {
2295       vam->retval = retval;
2296       vam->result_ready = 1;
2297
2298       if (retval == 0)
2299         {
2300           clib_warning ("canonical name %s", mp->name);
2301         }
2302       else
2303         clib_warning ("retval %d", retval);
2304     }
2305 }
2306
2307 static void vl_api_dns_resolve_ip_reply_t_handler_json
2308   (vl_api_dns_resolve_ip_reply_t * mp)
2309 {
2310   clib_warning ("not implemented");
2311 }
2312
2313
2314 static void vl_api_ip_address_details_t_handler
2315   (vl_api_ip_address_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   static ip_address_details_t empty_ip_address_details = { {0} };
2319   ip_address_details_t *address = NULL;
2320   ip_details_t *current_ip_details = NULL;
2321   ip_details_t *details = NULL;
2322
2323   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2324
2325   if (!details || vam->current_sw_if_index >= vec_len (details)
2326       || !details[vam->current_sw_if_index].present)
2327     {
2328       errmsg ("ip address details arrived but not stored");
2329       errmsg ("ip_dump should be called first");
2330       return;
2331     }
2332
2333   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2334
2335 #define addresses (current_ip_details->addr)
2336
2337   vec_validate_init_empty (addresses, vec_len (addresses),
2338                            empty_ip_address_details);
2339
2340   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2341
2342   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2343   address->prefix_length = mp->prefix_length;
2344 #undef addresses
2345 }
2346
2347 static void vl_api_ip_address_details_t_handler_json
2348   (vl_api_ip_address_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   vat_json_node_t *node = NULL;
2352   struct in6_addr ip6;
2353   struct in_addr ip4;
2354
2355   if (VAT_JSON_ARRAY != vam->json_tree.type)
2356     {
2357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2358       vat_json_init_array (&vam->json_tree);
2359     }
2360   node = vat_json_array_add (&vam->json_tree);
2361
2362   vat_json_init_object (node);
2363   if (vam->is_ipv6)
2364     {
2365       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2366       vat_json_object_add_ip6 (node, "ip", ip6);
2367     }
2368   else
2369     {
2370       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2371       vat_json_object_add_ip4 (node, "ip", ip4);
2372     }
2373   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2374 }
2375
2376 static void
2377 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   static ip_details_t empty_ip_details = { 0 };
2381   ip_details_t *ip = NULL;
2382   u32 sw_if_index = ~0;
2383
2384   sw_if_index = ntohl (mp->sw_if_index);
2385
2386   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2387                            sw_if_index, empty_ip_details);
2388
2389   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2390                          sw_if_index);
2391
2392   ip->present = 1;
2393 }
2394
2395 static void
2396 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   if (VAT_JSON_ARRAY != vam->json_tree.type)
2401     {
2402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2403       vat_json_init_array (&vam->json_tree);
2404     }
2405   vat_json_array_add_uint (&vam->json_tree,
2406                            clib_net_to_host_u32 (mp->sw_if_index));
2407 }
2408
2409 static void vl_api_map_domain_details_t_handler_json
2410   (vl_api_map_domain_details_t * mp)
2411 {
2412   vat_json_node_t *node = NULL;
2413   vat_main_t *vam = &vat_main;
2414   struct in6_addr ip6;
2415   struct in_addr ip4;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422
2423   node = vat_json_array_add (&vam->json_tree);
2424   vat_json_init_object (node);
2425
2426   vat_json_object_add_uint (node, "domain_index",
2427                             clib_net_to_host_u32 (mp->domain_index));
2428   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2429   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2430   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2431   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2432   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2433   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2434   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2435   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2436   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2437   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2438   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2439   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2440   vat_json_object_add_uint (node, "flags", mp->flags);
2441   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2442   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2443 }
2444
2445 static void vl_api_map_domain_details_t_handler
2446   (vl_api_map_domain_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   if (mp->is_translation)
2451     {
2452       print (vam->ofp,
2453              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2454              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2455              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2456              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2457              clib_net_to_host_u32 (mp->domain_index));
2458     }
2459   else
2460     {
2461       print (vam->ofp,
2462              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2463              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2464              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2465              format_ip6_address, mp->ip6_src,
2466              clib_net_to_host_u32 (mp->domain_index));
2467     }
2468   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2469          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2470          mp->is_translation ? "map-t" : "");
2471 }
2472
2473 static void vl_api_map_rule_details_t_handler_json
2474   (vl_api_map_rule_details_t * mp)
2475 {
2476   struct in6_addr ip6;
2477   vat_json_node_t *node = NULL;
2478   vat_main_t *vam = &vat_main;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485
2486   node = vat_json_array_add (&vam->json_tree);
2487   vat_json_init_object (node);
2488
2489   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2490   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2491   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2492 }
2493
2494 static void
2495 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2499          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2500 }
2501
2502 static void
2503 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2504 {
2505   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2506           "router_addr %U host_mac %U",
2507           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2508           format_ip4_address, &mp->host_address,
2509           format_ip4_address, &mp->router_address,
2510           format_ethernet_address, mp->host_mac);
2511 }
2512
2513 static void vl_api_dhcp_compl_event_t_handler_json
2514   (vl_api_dhcp_compl_event_t * mp)
2515 {
2516   /* JSON output not supported */
2517 }
2518
2519 static void
2520 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2521                               u32 counter)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   static u64 default_counter = 0;
2525
2526   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2527                            NULL);
2528   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2529                            sw_if_index, default_counter);
2530   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2531 }
2532
2533 static void
2534 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2535                                 interface_counter_t counter)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   static interface_counter_t default_counter = { 0, };
2539
2540   vec_validate_init_empty (vam->combined_interface_counters,
2541                            vnet_counter_type, NULL);
2542   vec_validate_init_empty (vam->combined_interface_counters
2543                            [vnet_counter_type], sw_if_index, default_counter);
2544   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2545 }
2546
2547 static void vl_api_vnet_interface_simple_counters_t_handler
2548   (vl_api_vnet_interface_simple_counters_t * mp)
2549 {
2550   /* not supported */
2551 }
2552
2553 static void vl_api_vnet_interface_combined_counters_t_handler
2554   (vl_api_vnet_interface_combined_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler_json
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   u64 *v_packets;
2563   u64 packets;
2564   u32 count;
2565   u32 first_sw_if_index;
2566   int i;
2567
2568   count = ntohl (mp->count);
2569   first_sw_if_index = ntohl (mp->first_sw_if_index);
2570
2571   v_packets = (u64 *) & mp->data;
2572   for (i = 0; i < count; i++)
2573     {
2574       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2575       set_simple_interface_counter (mp->vnet_counter_type,
2576                                     first_sw_if_index + i, packets);
2577       v_packets++;
2578     }
2579 }
2580
2581 static void vl_api_vnet_interface_combined_counters_t_handler_json
2582   (vl_api_vnet_interface_combined_counters_t * mp)
2583 {
2584   interface_counter_t counter;
2585   vlib_counter_t *v;
2586   u32 first_sw_if_index;
2587   int i;
2588   u32 count;
2589
2590   count = ntohl (mp->count);
2591   first_sw_if_index = ntohl (mp->first_sw_if_index);
2592
2593   v = (vlib_counter_t *) & mp->data;
2594   for (i = 0; i < count; i++)
2595     {
2596       counter.packets =
2597         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2598       counter.bytes =
2599         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2600       set_combined_interface_counter (mp->vnet_counter_type,
2601                                       first_sw_if_index + i, counter);
2602       v++;
2603     }
2604 }
2605
2606 static u32
2607 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i;
2611
2612   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2613     {
2614       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2615         {
2616           return i;
2617         }
2618     }
2619   return ~0;
2620 }
2621
2622 static u32
2623 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static void vl_api_vnet_ip4_fib_counters_t_handler
2639   (vl_api_vnet_ip4_fib_counters_t * mp)
2640 {
2641   /* not supported */
2642 }
2643
2644 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2645   (vl_api_vnet_ip4_fib_counters_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vl_api_ip4_fib_counter_t *v;
2649   ip4_fib_counter_t *counter;
2650   struct in_addr ip4;
2651   u32 vrf_id;
2652   u32 vrf_index;
2653   u32 count;
2654   int i;
2655
2656   vrf_id = ntohl (mp->vrf_id);
2657   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2658   if (~0 == vrf_index)
2659     {
2660       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2661       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2662       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2663       vec_validate (vam->ip4_fib_counters, vrf_index);
2664       vam->ip4_fib_counters[vrf_index] = NULL;
2665     }
2666
2667   vec_free (vam->ip4_fib_counters[vrf_index]);
2668   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2669   count = ntohl (mp->count);
2670   for (i = 0; i < count; i++)
2671     {
2672       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2673       counter = &vam->ip4_fib_counters[vrf_index][i];
2674       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2675       counter->address = ip4;
2676       counter->address_length = v->address_length;
2677       counter->packets = clib_net_to_host_u64 (v->packets);
2678       counter->bytes = clib_net_to_host_u64 (v->bytes);
2679       v++;
2680     }
2681 }
2682
2683 static void vl_api_vnet_ip4_nbr_counters_t_handler
2684   (vl_api_vnet_ip4_nbr_counters_t * mp)
2685 {
2686   /* not supported */
2687 }
2688
2689 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2690   (vl_api_vnet_ip4_nbr_counters_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vl_api_ip4_nbr_counter_t *v;
2694   ip4_nbr_counter_t *counter;
2695   u32 sw_if_index;
2696   u32 count;
2697   int i;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700   count = ntohl (mp->count);
2701   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2702
2703   if (mp->begin)
2704     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2705
2706   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2707   for (i = 0; i < count; i++)
2708     {
2709       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2710       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2711       counter->address.s_addr = v->address;
2712       counter->packets = clib_net_to_host_u64 (v->packets);
2713       counter->bytes = clib_net_to_host_u64 (v->bytes);
2714       counter->linkt = v->link_type;
2715       v++;
2716     }
2717 }
2718
2719 static void vl_api_vnet_ip6_fib_counters_t_handler
2720   (vl_api_vnet_ip6_fib_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2726   (vl_api_vnet_ip6_fib_counters_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   vl_api_ip6_fib_counter_t *v;
2730   ip6_fib_counter_t *counter;
2731   struct in6_addr ip6;
2732   u32 vrf_id;
2733   u32 vrf_index;
2734   u32 count;
2735   int i;
2736
2737   vrf_id = ntohl (mp->vrf_id);
2738   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2739   if (~0 == vrf_index)
2740     {
2741       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2742       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2743       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2744       vec_validate (vam->ip6_fib_counters, vrf_index);
2745       vam->ip6_fib_counters[vrf_index] = NULL;
2746     }
2747
2748   vec_free (vam->ip6_fib_counters[vrf_index]);
2749   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2750   count = ntohl (mp->count);
2751   for (i = 0; i < count; i++)
2752     {
2753       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2754       counter = &vam->ip6_fib_counters[vrf_index][i];
2755       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2756       counter->address = ip6;
2757       counter->address_length = v->address_length;
2758       counter->packets = clib_net_to_host_u64 (v->packets);
2759       counter->bytes = clib_net_to_host_u64 (v->bytes);
2760       v++;
2761     }
2762 }
2763
2764 static void vl_api_vnet_ip6_nbr_counters_t_handler
2765   (vl_api_vnet_ip6_nbr_counters_t * mp)
2766 {
2767   /* not supported */
2768 }
2769
2770 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2771   (vl_api_vnet_ip6_nbr_counters_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vl_api_ip6_nbr_counter_t *v;
2775   ip6_nbr_counter_t *counter;
2776   struct in6_addr ip6;
2777   u32 sw_if_index;
2778   u32 count;
2779   int i;
2780
2781   sw_if_index = ntohl (mp->sw_if_index);
2782   count = ntohl (mp->count);
2783   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2784
2785   if (mp->begin)
2786     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2787
2788   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2789   for (i = 0; i < count; i++)
2790     {
2791       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2792       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2793       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2794       counter->address = ip6;
2795       counter->packets = clib_net_to_host_u64 (v->packets);
2796       counter->bytes = clib_net_to_host_u64 (v->bytes);
2797       v++;
2798     }
2799 }
2800
2801 static void vl_api_get_first_msg_id_reply_t_handler
2802   (vl_api_get_first_msg_id_reply_t * mp)
2803 {
2804   vat_main_t *vam = &vat_main;
2805   i32 retval = ntohl (mp->retval);
2806
2807   if (vam->async_mode)
2808     {
2809       vam->async_errors += (retval < 0);
2810     }
2811   else
2812     {
2813       vam->retval = retval;
2814       vam->result_ready = 1;
2815     }
2816   if (retval >= 0)
2817     {
2818       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2819     }
2820 }
2821
2822 static void vl_api_get_first_msg_id_reply_t_handler_json
2823   (vl_api_get_first_msg_id_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t node;
2827
2828   vat_json_init_object (&node);
2829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2830   vat_json_object_add_uint (&node, "first_msg_id",
2831                             (uint) ntohs (mp->first_msg_id));
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void vl_api_get_node_graph_reply_t_handler
2841   (vl_api_get_node_graph_reply_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   api_main_t *am = &api_main;
2845   i32 retval = ntohl (mp->retval);
2846   u8 *pvt_copy, *reply;
2847   void *oldheap;
2848   vlib_node_t *node;
2849   int i;
2850
2851   if (vam->async_mode)
2852     {
2853       vam->async_errors += (retval < 0);
2854     }
2855   else
2856     {
2857       vam->retval = retval;
2858       vam->result_ready = 1;
2859     }
2860
2861   /* "Should never happen..." */
2862   if (retval != 0)
2863     return;
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866   pvt_copy = vec_dup (reply);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   if (vam->graph_nodes)
2878     {
2879       hash_free (vam->graph_node_index_by_name);
2880
2881       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2882         {
2883           node = vam->graph_nodes[i];
2884           vec_free (node->name);
2885           vec_free (node->next_nodes);
2886           vec_free (node);
2887         }
2888       vec_free (vam->graph_nodes);
2889     }
2890
2891   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2892   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2893   vec_free (pvt_copy);
2894
2895   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2896     {
2897       node = vam->graph_nodes[i];
2898       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2899     }
2900 }
2901
2902 static void vl_api_get_node_graph_reply_t_handler_json
2903   (vl_api_get_node_graph_reply_t * mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   api_main_t *am = &api_main;
2907   void *oldheap;
2908   vat_json_node_t node;
2909   u8 *reply;
2910
2911   /* $$$$ make this real? */
2912   vat_json_init_object (&node);
2913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2914   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2915
2916   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2917
2918   /* Toss the shared-memory original... */
2919   pthread_mutex_lock (&am->vlib_rp->mutex);
2920   oldheap = svm_push_data_heap (am->vlib_rp);
2921
2922   vec_free (reply);
2923
2924   svm_pop_heap (oldheap);
2925   pthread_mutex_unlock (&am->vlib_rp->mutex);
2926
2927   vat_json_print (vam->ofp, &node);
2928   vat_json_free (&node);
2929
2930   vam->retval = ntohl (mp->retval);
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   u8 *s = 0;
2939
2940   if (mp->local)
2941     {
2942       s = format (s, "%=16d%=16d%=16d",
2943                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2944     }
2945   else
2946     {
2947       s = format (s, "%=16U%=16d%=16d",
2948                   mp->is_ipv6 ? format_ip6_address :
2949                   format_ip4_address,
2950                   mp->ip_address, mp->priority, mp->weight);
2951     }
2952
2953   print (vam->ofp, "%v", s);
2954   vec_free (s);
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = NULL;
2962   struct in6_addr ip6;
2963   struct in_addr ip4;
2964
2965   if (VAT_JSON_ARRAY != vam->json_tree.type)
2966     {
2967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2968       vat_json_init_array (&vam->json_tree);
2969     }
2970   node = vat_json_array_add (&vam->json_tree);
2971   vat_json_init_object (node);
2972
2973   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2974   vat_json_object_add_uint (node, "priority", mp->priority);
2975   vat_json_object_add_uint (node, "weight", mp->weight);
2976
2977   if (mp->local)
2978     vat_json_object_add_uint (node, "sw_if_index",
2979                               clib_net_to_host_u32 (mp->sw_if_index));
2980   else
2981     {
2982       if (mp->is_ipv6)
2983         {
2984           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2985           vat_json_object_add_ip6 (node, "address", ip6);
2986         }
2987       else
2988         {
2989           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2990           vat_json_object_add_ip4 (node, "address", ip4);
2991         }
2992     }
2993 }
2994
2995 static void
2996 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2997                                           mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   u8 *ls_name = 0;
3001
3002   ls_name = format (0, "%s", mp->ls_name);
3003
3004   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3005          ls_name);
3006   vec_free (ls_name);
3007 }
3008
3009 static void
3010   vl_api_one_locator_set_details_t_handler_json
3011   (vl_api_one_locator_set_details_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t *node = 0;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018   vec_add1 (ls_name, 0);
3019
3020   if (VAT_JSON_ARRAY != vam->json_tree.type)
3021     {
3022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3023       vat_json_init_array (&vam->json_tree);
3024     }
3025   node = vat_json_array_add (&vam->json_tree);
3026
3027   vat_json_init_object (node);
3028   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3029   vat_json_object_add_uint (node, "ls_index",
3030                             clib_net_to_host_u32 (mp->ls_index));
3031   vec_free (ls_name);
3032 }
3033
3034 typedef struct
3035 {
3036   u32 spi;
3037   u8 si;
3038 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3039
3040 uword
3041 unformat_nsh_address (unformat_input_t * input, va_list * args)
3042 {
3043   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3044   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3045 }
3046
3047 u8 *
3048 format_nsh_address_vat (u8 * s, va_list * args)
3049 {
3050   nsh_t *a = va_arg (*args, nsh_t *);
3051   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3052 }
3053
3054 static u8 *
3055 format_lisp_flat_eid (u8 * s, va_list * args)
3056 {
3057   u32 type = va_arg (*args, u32);
3058   u8 *eid = va_arg (*args, u8 *);
3059   u32 eid_len = va_arg (*args, u32);
3060
3061   switch (type)
3062     {
3063     case 0:
3064       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3065     case 1:
3066       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3067     case 2:
3068       return format (s, "%U", format_ethernet_address, eid);
3069     case 3:
3070       return format (s, "%U", format_nsh_address_vat, eid);
3071     }
3072   return 0;
3073 }
3074
3075 static u8 *
3076 format_lisp_eid_vat (u8 * s, va_list * args)
3077 {
3078   u32 type = va_arg (*args, u32);
3079   u8 *eid = va_arg (*args, u8 *);
3080   u32 eid_len = va_arg (*args, u32);
3081   u8 *seid = va_arg (*args, u8 *);
3082   u32 seid_len = va_arg (*args, u32);
3083   u32 is_src_dst = va_arg (*args, u32);
3084
3085   if (is_src_dst)
3086     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3087
3088   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3089
3090   return s;
3091 }
3092
3093 static void
3094 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   u8 *s = 0, *eid = 0;
3098
3099   if (~0 == mp->locator_set_index)
3100     s = format (0, "action: %d", mp->action);
3101   else
3102     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3103
3104   eid = format (0, "%U", format_lisp_eid_vat,
3105                 mp->eid_type,
3106                 mp->eid,
3107                 mp->eid_prefix_len,
3108                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109   vec_add1 (eid, 0);
3110
3111   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3112          clib_net_to_host_u32 (mp->vni),
3113          eid,
3114          mp->is_local ? "local" : "remote",
3115          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3116          clib_net_to_host_u16 (mp->key_id), mp->key);
3117
3118   vec_free (s);
3119   vec_free (eid);
3120 }
3121
3122 static void
3123 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3124                                              * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = 0;
3128   u8 *eid = 0;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136
3137   vat_json_init_object (node);
3138   if (~0 == mp->locator_set_index)
3139     vat_json_object_add_uint (node, "action", mp->action);
3140   else
3141     vat_json_object_add_uint (node, "locator_set_index",
3142                               clib_net_to_host_u32 (mp->locator_set_index));
3143
3144   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3145   if (mp->eid_type == 3)
3146     {
3147       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3148       vat_json_init_object (nsh_json);
3149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3150       vat_json_object_add_uint (nsh_json, "spi",
3151                                 clib_net_to_host_u32 (nsh->spi));
3152       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3153     }
3154   else
3155     {
3156       eid = format (0, "%U", format_lisp_eid_vat,
3157                     mp->eid_type,
3158                     mp->eid,
3159                     mp->eid_prefix_len,
3160                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3161       vec_add1 (eid, 0);
3162       vat_json_object_add_string_copy (node, "eid", eid);
3163       vec_free (eid);
3164     }
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3167   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3168
3169   if (mp->key_id)
3170     {
3171       vat_json_object_add_uint (node, "key_id",
3172                                 clib_net_to_host_u16 (mp->key_id));
3173       vat_json_object_add_string_copy (node, "key", mp->key);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   u8 *seid = 0, *deid = 0;
3182   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3183
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   if (mp->is_ip4)
3194     format_ip_address_fcn = format_ip4_address;
3195   else
3196     format_ip_address_fcn = format_ip6_address;
3197
3198
3199   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3200          clib_net_to_host_u32 (mp->vni),
3201          seid, deid,
3202          format_ip_address_fcn, mp->lloc,
3203          format_ip_address_fcn, mp->rloc,
3204          clib_net_to_host_u32 (mp->pkt_count),
3205          clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3213 {
3214   struct in6_addr ip6;
3215   struct in_addr ip4;
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = 0;
3218   u8 *deid = 0, *seid = 0;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   deid = format (0, "%U", format_lisp_eid_vat,
3229                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3230
3231   seid = format (0, "%U", format_lisp_eid_vat,
3232                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3233
3234   vec_add1 (deid, 0);
3235   vec_add1 (seid, 0);
3236
3237   vat_json_object_add_string_copy (node, "seid", seid);
3238   vat_json_object_add_string_copy (node, "deid", deid);
3239   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3240
3241   if (mp->is_ip4)
3242     {
3243       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3244       vat_json_object_add_ip4 (node, "lloc", ip4);
3245       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "rloc", ip4);
3247     }
3248   else
3249     {
3250       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3251       vat_json_object_add_ip6 (node, "lloc", ip6);
3252       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3253       vat_json_object_add_ip6 (node, "rloc", ip6);
3254     }
3255   vat_json_object_add_uint (node, "pkt_count",
3256                             clib_net_to_host_u32 (mp->pkt_count));
3257   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3258
3259   vec_free (deid);
3260   vec_free (seid);
3261 }
3262
3263 static void
3264   vl_api_one_eid_table_map_details_t_handler
3265   (vl_api_one_eid_table_map_details_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268
3269   u8 *line = format (0, "%=10d%=10d",
3270                      clib_net_to_host_u32 (mp->vni),
3271                      clib_net_to_host_u32 (mp->dp_table));
3272   print (vam->ofp, "%v", line);
3273   vec_free (line);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler_json
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node = NULL;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "dp_table",
3291                             clib_net_to_host_u32 (mp->dp_table));
3292   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3293 }
3294
3295 static void
3296   vl_api_one_eid_table_vni_details_t_handler
3297   (vl_api_one_eid_table_vni_details_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3302   print (vam->ofp, "%v", line);
3303   vec_free (line);
3304 }
3305
3306 static void
3307   vl_api_one_eid_table_vni_details_t_handler_json
3308   (vl_api_one_eid_table_vni_details_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t *node = NULL;
3312
3313   if (VAT_JSON_ARRAY != vam->json_tree.type)
3314     {
3315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3316       vat_json_init_array (&vam->json_tree);
3317     }
3318   node = vat_json_array_add (&vam->json_tree);
3319   vat_json_init_object (node);
3320   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3325   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3331   print (vam->ofp, "fallback threshold value: %d", mp->value);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3339   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   vat_json_init_object (node);
3347   vat_json_object_add_uint (node, "value", mp->value);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_map_register_state_reply_t_handler
3358   (vl_api_show_one_map_register_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler_json
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t _node, *node = &_node;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3378
3379   vat_json_init_object (node);
3380   vat_json_object_add_string_copy (node, "state", s);
3381
3382   vat_json_print (vam->ofp, node);
3383   vat_json_free (node);
3384
3385   vam->retval = retval;
3386   vam->result_ready = 1;
3387   vec_free (s);
3388 }
3389
3390 static void
3391   vl_api_show_one_rloc_probe_state_reply_t_handler
3392   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   int retval = clib_net_to_host_u32 (mp->retval);
3396
3397   if (retval)
3398     goto end;
3399
3400   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t _node, *node = &_node;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3415   vat_json_init_object (node);
3416   vat_json_object_add_string_copy (node, "state", s);
3417
3418   vat_json_print (vam->ofp, node);
3419   vat_json_free (node);
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423   vec_free (s);
3424 }
3425
3426 static void
3427   vl_api_show_one_stats_enable_disable_reply_t_handler
3428   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432
3433   if (retval)
3434     goto end;
3435
3436   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3437 end:
3438   vam->retval = retval;
3439   vam->result_ready = 1;
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t _node, *node = &_node;
3448   int retval = clib_net_to_host_u32 (mp->retval);
3449
3450   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3451   vat_json_init_object (node);
3452   vat_json_object_add_string_copy (node, "state", s);
3453
3454   vat_json_print (vam->ofp, node);
3455   vat_json_free (node);
3456
3457   vam->retval = retval;
3458   vam->result_ready = 1;
3459   vec_free (s);
3460 }
3461
3462 static void
3463 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3464 {
3465   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3466   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3467   e->vni = clib_net_to_host_u32 (e->vni);
3468 }
3469
3470 static void
3471   gpe_fwd_entries_get_reply_t_net_to_host
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u32 i;
3475
3476   mp->count = clib_net_to_host_u32 (mp->count);
3477   for (i = 0; i < mp->count; i++)
3478     {
3479       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3480     }
3481 }
3482
3483 static u8 *
3484 format_gpe_encap_mode (u8 * s, va_list * args)
3485 {
3486   u32 mode = va_arg (*args, u32);
3487
3488   switch (mode)
3489     {
3490     case 0:
3491       return format (s, "lisp");
3492     case 1:
3493       return format (s, "vxlan");
3494     }
3495   return 0;
3496 }
3497
3498 static void
3499   vl_api_gpe_get_encap_mode_reply_t_handler
3500   (vl_api_gpe_get_encap_mode_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503
3504   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3505   vam->retval = ntohl (mp->retval);
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510   vl_api_gpe_get_encap_mode_reply_t_handler_json
3511   (vl_api_gpe_get_encap_mode_reply_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t node;
3515
3516   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3517   vec_add1 (encap_mode, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3521
3522   vec_free (encap_mode);
3523   vat_json_print (vam->ofp, &node);
3524   vat_json_free (&node);
3525
3526   vam->retval = ntohl (mp->retval);
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_fwd_entry_path_details_t_handler
3532   (vl_api_gpe_fwd_entry_path_details_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3536
3537   if (mp->lcl_loc.is_ip4)
3538     format_ip_address_fcn = format_ip4_address;
3539   else
3540     format_ip_address_fcn = format_ip6_address;
3541
3542   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3543          format_ip_address_fcn, &mp->lcl_loc,
3544          format_ip_address_fcn, &mp->rmt_loc);
3545 }
3546
3547 static void
3548 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3549 {
3550   struct in6_addr ip6;
3551   struct in_addr ip4;
3552
3553   if (loc->is_ip4)
3554     {
3555       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3556       vat_json_object_add_ip4 (n, "address", ip4);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3561       vat_json_object_add_ip6 (n, "address", ip6);
3562     }
3563   vat_json_object_add_uint (n, "weight", loc->weight);
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entry_path_details_t_handler_json
3568   (vl_api_gpe_fwd_entry_path_details_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   vat_json_node_t *node = NULL;
3572   vat_json_node_t *loc_node;
3573
3574   if (VAT_JSON_ARRAY != vam->json_tree.type)
3575     {
3576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3577       vat_json_init_array (&vam->json_tree);
3578     }
3579   node = vat_json_array_add (&vam->json_tree);
3580   vat_json_init_object (node);
3581
3582   loc_node = vat_json_object_add (node, "local_locator");
3583   vat_json_init_object (loc_node);
3584   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3585
3586   loc_node = vat_json_object_add (node, "remote_locator");
3587   vat_json_init_object (loc_node);
3588   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3589 }
3590
3591 static void
3592   vl_api_gpe_fwd_entries_get_reply_t_handler
3593   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_fwd_entry_t *e;
3599
3600   if (retval)
3601     goto end;
3602
3603   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3604
3605   for (i = 0; i < mp->count; i++)
3606     {
3607       e = &mp->entries[i];
3608       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3609              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3610              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3611     }
3612
3613 end:
3614   vam->retval = retval;
3615   vam->result_ready = 1;
3616 }
3617
3618 static void
3619   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3620   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3621 {
3622   u8 *s = 0;
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t *e = 0, root;
3625   u32 i;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_fwd_entry_t *fwd;
3628
3629   if (retval)
3630     goto end;
3631
3632   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < mp->count; i++)
3636     {
3637       e = vat_json_array_add (&root);
3638       fwd = &mp->entries[i];
3639
3640       vat_json_init_object (e);
3641       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3642       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3643       vat_json_object_add_int (e, "vni", fwd->vni);
3644       vat_json_object_add_int (e, "action", fwd->action);
3645
3646       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3647                   fwd->leid_prefix_len);
3648       vec_add1 (s, 0);
3649       vat_json_object_add_string_copy (e, "leid", s);
3650       vec_free (s);
3651
3652       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3653                   fwd->reid_prefix_len);
3654       vec_add1 (s, 0);
3655       vat_json_object_add_string_copy (e, "reid", s);
3656       vec_free (s);
3657     }
3658
3659   vat_json_print (vam->ofp, &root);
3660   vat_json_free (&root);
3661
3662 end:
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3669   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_gpe_native_fwd_rpath_t *r;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     {
3683       r = &mp->entries[i];
3684       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3685              clib_net_to_host_u32 (r->fib_index),
3686              clib_net_to_host_u32 (r->nh_sw_if_index),
3687              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3688     }
3689
3690 end:
3691   vam->retval = retval;
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3697   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   vat_json_node_t root, *e;
3701   u32 i, n;
3702   int retval = clib_net_to_host_u32 (mp->retval);
3703   vl_api_gpe_native_fwd_rpath_t *r;
3704   u8 *s;
3705
3706   if (retval)
3707     goto end;
3708
3709   n = clib_net_to_host_u32 (mp->count);
3710   vat_json_init_array (&root);
3711
3712   for (i = 0; i < n; i++)
3713     {
3714       e = vat_json_array_add (&root);
3715       vat_json_init_object (e);
3716       r = &mp->entries[i];
3717       s =
3718         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3719                 r->nh_addr);
3720       vec_add1 (s, 0);
3721       vat_json_object_add_string_copy (e, "ip4", s);
3722       vec_free (s);
3723
3724       vat_json_object_add_uint (e, "fib_index",
3725                                 clib_net_to_host_u32 (r->fib_index));
3726       vat_json_object_add_uint (e, "nh_sw_if_index",
3727                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3728     }
3729
3730   vat_json_print (vam->ofp, &root);
3731   vat_json_free (&root);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3740   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743   u32 i, n;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745
3746   if (retval)
3747     goto end;
3748
3749   n = clib_net_to_host_u32 (mp->count);
3750
3751   for (i = 0; i < n; i++)
3752     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3761   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_ndp_entries_get_reply_t_handler
3787   (vl_api_one_ndp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
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     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_entries_get_reply_t_handler_json
3809   (vl_api_one_ndp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_ndp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip6", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_entries_get_reply_t_handler
3852   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   u32 i, n;
3856   int retval = clib_net_to_host_u32 (mp->retval);
3857
3858   if (retval)
3859     goto end;
3860
3861   n = clib_net_to_host_u32 (mp->count);
3862
3863   for (i = 0; i < n; i++)
3864     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3865            format_ethernet_address, mp->entries[i].mac);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3874   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3875 {
3876   u8 *s = 0;
3877   vat_main_t *vam = &vat_main;
3878   vat_json_node_t *e = 0, root;
3879   u32 i, n;
3880   int retval = clib_net_to_host_u32 (mp->retval);
3881   vl_api_one_l2_arp_entry_t *arp_entry;
3882
3883   if (retval)
3884     goto end;
3885
3886   n = clib_net_to_host_u32 (mp->count);
3887   vat_json_init_array (&root);
3888
3889   for (i = 0; i < n; i++)
3890     {
3891       e = vat_json_array_add (&root);
3892       arp_entry = &mp->entries[i];
3893
3894       vat_json_init_object (e);
3895       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3896       vec_add1 (s, 0);
3897
3898       vat_json_object_add_string_copy (e, "mac", s);
3899       vec_free (s);
3900
3901       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3902       vec_add1 (s, 0);
3903       vat_json_object_add_string_copy (e, "ip4", s);
3904       vec_free (s);
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_ndp_bd_get_reply_t_handler_json
3939   (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_l2_arp_bd_get_reply_t_handler
3968   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973
3974   if (retval)
3975     goto end;
3976
3977   n = clib_net_to_host_u32 (mp->count);
3978
3979   for (i = 0; i < n; i++)
3980     {
3981       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3982     }
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002   vat_json_init_array (&root);
4003
4004   for (i = 0; i < n; i++)
4005     {
4006       vat_json_array_add_uint (&root,
4007                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4008     }
4009
4010   vat_json_print (vam->ofp, &root);
4011   vat_json_free (&root);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_adjacencies_get_reply_t_handler
4020   (vl_api_one_adjacencies_get_reply_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   u32 i, n;
4024   int retval = clib_net_to_host_u32 (mp->retval);
4025   vl_api_one_adjacency_t *a;
4026
4027   if (retval)
4028     goto end;
4029
4030   n = clib_net_to_host_u32 (mp->count);
4031
4032   for (i = 0; i < n; i++)
4033     {
4034       a = &mp->adjacencies[i];
4035       print (vam->ofp, "%U %40U",
4036              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4037              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4038     }
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_adjacencies_get_reply_t_handler_json
4047   (vl_api_one_adjacencies_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_adjacency_t *a;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       a = &mp->adjacencies[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4069                   a->leid_prefix_len);
4070       vec_add1 (s, 0);
4071       vat_json_object_add_string_copy (e, "leid", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4075                   a->reid_prefix_len);
4076       vec_add1 (s, 0);
4077       vat_json_object_add_string_copy (e, "reid", s);
4078       vec_free (s);
4079     }
4080
4081   vat_json_print (vam->ofp, &root);
4082   vat_json_free (&root);
4083
4084 end:
4085   vam->retval = retval;
4086   vam->result_ready = 1;
4087 }
4088
4089 static void
4090 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093
4094   print (vam->ofp, "%=20U",
4095          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4096          mp->ip_address);
4097 }
4098
4099 static void
4100   vl_api_one_map_server_details_t_handler_json
4101   (vl_api_one_map_server_details_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105   struct in6_addr ip6;
4106   struct in_addr ip4;
4107
4108   if (VAT_JSON_ARRAY != vam->json_tree.type)
4109     {
4110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4111       vat_json_init_array (&vam->json_tree);
4112     }
4113   node = vat_json_array_add (&vam->json_tree);
4114
4115   vat_json_init_object (node);
4116   if (mp->is_ipv6)
4117     {
4118       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4119       vat_json_object_add_ip6 (node, "map-server", ip6);
4120     }
4121   else
4122     {
4123       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4124       vat_json_object_add_ip4 (node, "map-server", ip4);
4125     }
4126 }
4127
4128 static void
4129 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4130                                            * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133
4134   print (vam->ofp, "%=20U",
4135          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4136          mp->ip_address);
4137 }
4138
4139 static void
4140   vl_api_one_map_resolver_details_t_handler_json
4141   (vl_api_one_map_resolver_details_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t *node = NULL;
4145   struct in6_addr ip6;
4146   struct in_addr ip4;
4147
4148   if (VAT_JSON_ARRAY != vam->json_tree.type)
4149     {
4150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4151       vat_json_init_array (&vam->json_tree);
4152     }
4153   node = vat_json_array_add (&vam->json_tree);
4154
4155   vat_json_init_object (node);
4156   if (mp->is_ipv6)
4157     {
4158       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4159       vat_json_object_add_ip6 (node, "map resolver", ip6);
4160     }
4161   else
4162     {
4163       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4164       vat_json_object_add_ip4 (node, "map resolver", ip4);
4165     }
4166 }
4167
4168 static void
4169 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4170 {
4171   vat_main_t *vam = &vat_main;
4172   i32 retval = ntohl (mp->retval);
4173
4174   if (0 <= retval)
4175     {
4176       print (vam->ofp, "feature: %s\ngpe: %s",
4177              mp->feature_status ? "enabled" : "disabled",
4178              mp->gpe_status ? "enabled" : "disabled");
4179     }
4180
4181   vam->retval = retval;
4182   vam->result_ready = 1;
4183 }
4184
4185 static void
4186   vl_api_show_one_status_reply_t_handler_json
4187   (vl_api_show_one_status_reply_t * mp)
4188 {
4189   vat_main_t *vam = &vat_main;
4190   vat_json_node_t node;
4191   u8 *gpe_status = NULL;
4192   u8 *feature_status = NULL;
4193
4194   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4195   feature_status = format (0, "%s",
4196                            mp->feature_status ? "enabled" : "disabled");
4197   vec_add1 (gpe_status, 0);
4198   vec_add1 (feature_status, 0);
4199
4200   vat_json_init_object (&node);
4201   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4202   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4203
4204   vec_free (gpe_status);
4205   vec_free (feature_status);
4206
4207   vat_json_print (vam->ofp, &node);
4208   vat_json_free (&node);
4209
4210   vam->retval = ntohl (mp->retval);
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4216   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   i32 retval = ntohl (mp->retval);
4220
4221   if (retval >= 0)
4222     {
4223       print (vam->ofp, "%=20s", mp->locator_set_name);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t *node = NULL;
4236
4237   if (VAT_JSON_ARRAY != vam->json_tree.type)
4238     {
4239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4240       vat_json_init_array (&vam->json_tree);
4241     }
4242   node = vat_json_array_add (&vam->json_tree);
4243
4244   vat_json_init_object (node);
4245   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4246
4247   vat_json_print (vam->ofp, node);
4248   vat_json_free (node);
4249
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static u8 *
4255 format_lisp_map_request_mode (u8 * s, va_list * args)
4256 {
4257   u32 mode = va_arg (*args, u32);
4258
4259   switch (mode)
4260     {
4261     case 0:
4262       return format (0, "dst-only");
4263     case 1:
4264       return format (0, "src-dst");
4265     }
4266   return 0;
4267 }
4268
4269 static void
4270   vl_api_show_one_map_request_mode_reply_t_handler
4271   (vl_api_show_one_map_request_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   i32 retval = ntohl (mp->retval);
4275
4276   if (0 <= retval)
4277     {
4278       u32 mode = mp->mode;
4279       print (vam->ofp, "map_request_mode: %U",
4280              format_lisp_map_request_mode, mode);
4281     }
4282
4283   vam->retval = retval;
4284   vam->result_ready = 1;
4285 }
4286
4287 static void
4288   vl_api_show_one_map_request_mode_reply_t_handler_json
4289   (vl_api_show_one_map_request_mode_reply_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t node;
4293   u8 *s = 0;
4294   u32 mode;
4295
4296   mode = mp->mode;
4297   s = format (0, "%U", format_lisp_map_request_mode, mode);
4298   vec_add1 (s, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vec_free (s);
4306   vam->retval = ntohl (mp->retval);
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_one_show_xtr_mode_reply_t_handler
4312   (vl_api_one_show_xtr_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316
4317   if (0 <= retval)
4318     {
4319       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4320     }
4321
4322   vam->retval = retval;
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler_json
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   vat_json_node_t node;
4332   u8 *status = 0;
4333
4334   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4335   vec_add1 (status, 0);
4336
4337   vat_json_init_object (&node);
4338   vat_json_object_add_string_copy (&node, "status", status);
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_pitr_mode_reply_t_handler
4351   (vl_api_one_show_pitr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler_json
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371   u8 *status = 0;
4372
4373   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4374   vec_add1 (status, 0);
4375
4376   vat_json_init_object (&node);
4377   vat_json_object_add_string_copy (&node, "status", status);
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_petr_mode_reply_t_handler
4390   (vl_api_one_show_petr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   if (0 <= retval)
4396     {
4397       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler_json
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *status = 0;
4411
4412   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4413   vec_add1 (status, 0);
4414
4415   vat_json_init_object (&node);
4416   vat_json_object_add_string_copy (&node, "status", status);
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_use_petr_reply_t_handler
4429   (vl_api_show_one_use_petr_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->status ? "enabled" : "disabled");
4437       if (mp->status)
4438         {
4439           print (vam->ofp, "Proxy-ETR address; %U",
4440                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4441                  mp->address);
4442         }
4443     }
4444
4445   vam->retval = retval;
4446   vam->result_ready = 1;
4447 }
4448
4449 static void
4450   vl_api_show_one_use_petr_reply_t_handler_json
4451   (vl_api_show_one_use_petr_reply_t * mp)
4452 {
4453   vat_main_t *vam = &vat_main;
4454   vat_json_node_t node;
4455   u8 *status = 0;
4456   struct in_addr ip4;
4457   struct in6_addr ip6;
4458
4459   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4460   vec_add1 (status, 0);
4461
4462   vat_json_init_object (&node);
4463   vat_json_object_add_string_copy (&node, "status", status);
4464   if (mp->status)
4465     {
4466       if (mp->is_ip4)
4467         {
4468           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4469           vat_json_object_add_ip6 (&node, "address", ip6);
4470         }
4471       else
4472         {
4473           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4474           vat_json_object_add_ip4 (&node, "address", ip4);
4475         }
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_nsh_mapping_reply_t_handler
4489   (vl_api_show_one_nsh_mapping_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "%-20s%-16s",
4497              mp->is_set ? "set" : "not-set",
4498              mp->is_set ? (char *) mp->locator_set_name : "");
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_nsh_mapping_reply_t_handler_json
4507   (vl_api_show_one_nsh_mapping_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511   u8 *status = 0;
4512
4513   status = format (0, "%s", mp->is_set ? "yes" : "no");
4514   vec_add1 (status, 0);
4515
4516   vat_json_init_object (&node);
4517   vat_json_object_add_string_copy (&node, "is_set", status);
4518   if (mp->is_set)
4519     {
4520       vat_json_object_add_string_copy (&node, "locator_set",
4521                                        mp->locator_set_name);
4522     }
4523
4524   vec_free (status);
4525
4526   vat_json_print (vam->ofp, &node);
4527   vat_json_free (&node);
4528
4529   vam->retval = ntohl (mp->retval);
4530   vam->result_ready = 1;
4531 }
4532
4533 static void
4534   vl_api_show_one_map_register_ttl_reply_t_handler
4535   (vl_api_show_one_map_register_ttl_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   i32 retval = ntohl (mp->retval);
4539
4540   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4541
4542   if (0 <= retval)
4543     {
4544       print (vam->ofp, "ttl: %u", mp->ttl);
4545     }
4546
4547   vam->retval = retval;
4548   vam->result_ready = 1;
4549 }
4550
4551 static void
4552   vl_api_show_one_map_register_ttl_reply_t_handler_json
4553   (vl_api_show_one_map_register_ttl_reply_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   vat_json_node_t node;
4557
4558   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4559   vat_json_init_object (&node);
4560   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   i32 retval = ntohl (mp->retval);
4574
4575   if (0 <= retval)
4576     {
4577       print (vam->ofp, "%-20s%-16s",
4578              mp->status ? "enabled" : "disabled",
4579              mp->status ? (char *) mp->locator_set_name : "");
4580     }
4581
4582   vam->retval = retval;
4583   vam->result_ready = 1;
4584 }
4585
4586 static void
4587 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4588 {
4589   vat_main_t *vam = &vat_main;
4590   vat_json_node_t node;
4591   u8 *status = 0;
4592
4593   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4594   vec_add1 (status, 0);
4595
4596   vat_json_init_object (&node);
4597   vat_json_object_add_string_copy (&node, "status", status);
4598   if (mp->status)
4599     {
4600       vat_json_object_add_string_copy (&node, "locator_set",
4601                                        mp->locator_set_name);
4602     }
4603
4604   vec_free (status);
4605
4606   vat_json_print (vam->ofp, &node);
4607   vat_json_free (&node);
4608
4609   vam->retval = ntohl (mp->retval);
4610   vam->result_ready = 1;
4611 }
4612
4613 static u8 *
4614 format_policer_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4619     s = format (s, "1r2c");
4620   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4621     s = format (s, "1r3c");
4622   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4623     s = format (s, "2r3c-2698");
4624   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4625     s = format (s, "2r3c-4115");
4626   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4627     s = format (s, "2r3c-mef5cf1");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_policer_rate_type (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637
4638   if (i == SSE2_QOS_RATE_KBPS)
4639     s = format (s, "kbps");
4640   else if (i == SSE2_QOS_RATE_PPS)
4641     s = format (s, "pps");
4642   else
4643     s = format (s, "ILLEGAL");
4644   return s;
4645 }
4646
4647 static u8 *
4648 format_policer_round_type (u8 * s, va_list * va)
4649 {
4650   u32 i = va_arg (*va, u32);
4651
4652   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4653     s = format (s, "closest");
4654   else if (i == SSE2_QOS_ROUND_TO_UP)
4655     s = format (s, "up");
4656   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4657     s = format (s, "down");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_action_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ACTION_DROP)
4669     s = format (s, "drop");
4670   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4671     s = format (s, "transmit");
4672   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4673     s = format (s, "mark-and-transmit");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_dscp (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683   char *t = 0;
4684
4685   switch (i)
4686     {
4687 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4688       foreach_vnet_dscp
4689 #undef _
4690     default:
4691       return format (s, "ILLEGAL");
4692     }
4693   s = format (s, "%s", t);
4694   return s;
4695 }
4696
4697 static void
4698 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4702
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705   else
4706     conform_dscp_str = format (0, "");
4707
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710   else
4711     exceed_dscp_str = format (0, "");
4712
4713   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4714     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4715   else
4716     violate_dscp_str = format (0, "");
4717
4718   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4719          "rate type %U, round type %U, %s rate, %s color-aware, "
4720          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4721          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4722          "conform action %U%s, exceed action %U%s, violate action %U%s",
4723          mp->name,
4724          format_policer_type, mp->type,
4725          ntohl (mp->cir),
4726          ntohl (mp->eir),
4727          clib_net_to_host_u64 (mp->cb),
4728          clib_net_to_host_u64 (mp->eb),
4729          format_policer_rate_type, mp->rate_type,
4730          format_policer_round_type, mp->round_type,
4731          mp->single_rate ? "single" : "dual",
4732          mp->color_aware ? "is" : "not",
4733          ntohl (mp->cir_tokens_per_period),
4734          ntohl (mp->pir_tokens_per_period),
4735          ntohl (mp->scale),
4736          ntohl (mp->current_limit),
4737          ntohl (mp->current_bucket),
4738          ntohl (mp->extended_limit),
4739          ntohl (mp->extended_bucket),
4740          clib_net_to_host_u64 (mp->last_update_time),
4741          format_policer_action_type, mp->conform_action_type,
4742          conform_dscp_str,
4743          format_policer_action_type, mp->exceed_action_type,
4744          exceed_dscp_str,
4745          format_policer_action_type, mp->violate_action_type,
4746          violate_dscp_str);
4747
4748   vec_free (conform_dscp_str);
4749   vec_free (exceed_dscp_str);
4750   vec_free (violate_dscp_str);
4751 }
4752
4753 static void vl_api_policer_details_t_handler_json
4754   (vl_api_policer_details_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t *node;
4758   u8 *rate_type_str, *round_type_str, *type_str;
4759   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4760
4761   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4762   round_type_str =
4763     format (0, "%U", format_policer_round_type, mp->round_type);
4764   type_str = format (0, "%U", format_policer_type, mp->type);
4765   conform_action_str = format (0, "%U", format_policer_action_type,
4766                                mp->conform_action_type);
4767   exceed_action_str = format (0, "%U", format_policer_action_type,
4768                               mp->exceed_action_type);
4769   violate_action_str = format (0, "%U", format_policer_action_type,
4770                                mp->violate_action_type);
4771
4772   if (VAT_JSON_ARRAY != vam->json_tree.type)
4773     {
4774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4775       vat_json_init_array (&vam->json_tree);
4776     }
4777   node = vat_json_array_add (&vam->json_tree);
4778
4779   vat_json_init_object (node);
4780   vat_json_object_add_string_copy (node, "name", mp->name);
4781   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4782   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4783   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4784   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4785   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4786   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4787   vat_json_object_add_string_copy (node, "type", type_str);
4788   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4789   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4790   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4791   vat_json_object_add_uint (node, "cir_tokens_per_period",
4792                             ntohl (mp->cir_tokens_per_period));
4793   vat_json_object_add_uint (node, "eir_tokens_per_period",
4794                             ntohl (mp->pir_tokens_per_period));
4795   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4796   vat_json_object_add_uint (node, "current_bucket",
4797                             ntohl (mp->current_bucket));
4798   vat_json_object_add_uint (node, "extended_limit",
4799                             ntohl (mp->extended_limit));
4800   vat_json_object_add_uint (node, "extended_bucket",
4801                             ntohl (mp->extended_bucket));
4802   vat_json_object_add_uint (node, "last_update_time",
4803                             ntohl (mp->last_update_time));
4804   vat_json_object_add_string_copy (node, "conform_action",
4805                                    conform_action_str);
4806   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4807     {
4808       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4809       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4810       vec_free (dscp_str);
4811     }
4812   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4813   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4814     {
4815       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4816       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4817       vec_free (dscp_str);
4818     }
4819   vat_json_object_add_string_copy (node, "violate_action",
4820                                    violate_action_str);
4821   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4824       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827
4828   vec_free (rate_type_str);
4829   vec_free (round_type_str);
4830   vec_free (type_str);
4831   vec_free (conform_action_str);
4832   vec_free (exceed_action_str);
4833   vec_free (violate_action_str);
4834 }
4835
4836 static void
4837 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4838                                            mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   int i, count = ntohl (mp->count);
4842
4843   if (count > 0)
4844     print (vam->ofp, "classify table ids (%d) : ", count);
4845   for (i = 0; i < count; i++)
4846     {
4847       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4848       print (vam->ofp, (i < count - 1) ? "," : "");
4849     }
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855   vl_api_classify_table_ids_reply_t_handler_json
4856   (vl_api_classify_table_ids_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   int i, count = ntohl (mp->count);
4860
4861   if (count > 0)
4862     {
4863       vat_json_node_t node;
4864
4865       vat_json_init_object (&node);
4866       for (i = 0; i < count; i++)
4867         {
4868           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4869         }
4870       vat_json_print (vam->ofp, &node);
4871       vat_json_free (&node);
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_by_interface_reply_t_handler
4879   (vl_api_classify_table_by_interface_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   u32 table_id;
4883
4884   table_id = ntohl (mp->l2_table_id);
4885   if (table_id != ~0)
4886     print (vam->ofp, "l2 table id : %d", table_id);
4887   else
4888     print (vam->ofp, "l2 table id : No input ACL tables configured");
4889   table_id = ntohl (mp->ip4_table_id);
4890   if (table_id != ~0)
4891     print (vam->ofp, "ip4 table id : %d", table_id);
4892   else
4893     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4894   table_id = ntohl (mp->ip6_table_id);
4895   if (table_id != ~0)
4896     print (vam->ofp, "ip6 table id : %d", table_id);
4897   else
4898     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4899   vam->retval = ntohl (mp->retval);
4900   vam->result_ready = 1;
4901 }
4902
4903 static void
4904   vl_api_classify_table_by_interface_reply_t_handler_json
4905   (vl_api_classify_table_by_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   vat_json_init_object (&node);
4911
4912   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4913   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4914   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_policer_add_del_reply_t_handler
4924   (vl_api_policer_add_del_reply_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (vam->async_mode)
4929     {
4930       vam->async_errors += (retval < 0);
4931     }
4932   else
4933     {
4934       vam->retval = retval;
4935       vam->result_ready = 1;
4936       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4937         /*
4938          * Note: this is just barely thread-safe, depends on
4939          * the main thread spinning waiting for an answer...
4940          */
4941         errmsg ("policer index %d", ntohl (mp->policer_index));
4942     }
4943 }
4944
4945 static void vl_api_policer_add_del_reply_t_handler_json
4946   (vl_api_policer_add_del_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   vat_json_init_object (&node);
4952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4953   vat_json_object_add_uint (&node, "policer_index",
4954                             ntohl (mp->policer_index));
4955
4956   vat_json_print (vam->ofp, &node);
4957   vat_json_free (&node);
4958
4959   vam->retval = ntohl (mp->retval);
4960   vam->result_ready = 1;
4961 }
4962
4963 /* Format hex dump. */
4964 u8 *
4965 format_hex_bytes (u8 * s, va_list * va)
4966 {
4967   u8 *bytes = va_arg (*va, u8 *);
4968   int n_bytes = va_arg (*va, int);
4969   uword i;
4970
4971   /* Print short or long form depending on byte count. */
4972   uword short_form = n_bytes <= 32;
4973   u32 indent = format_get_indent (s);
4974
4975   if (n_bytes == 0)
4976     return s;
4977
4978   for (i = 0; i < n_bytes; i++)
4979     {
4980       if (!short_form && (i % 32) == 0)
4981         s = format (s, "%08x: ", i);
4982       s = format (s, "%02x", bytes[i]);
4983       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4984         s = format (s, "\n%U", format_white_space, indent);
4985     }
4986
4987   return s;
4988 }
4989
4990 static void
4991 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4992                                             * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   i32 retval = ntohl (mp->retval);
4996   if (retval == 0)
4997     {
4998       print (vam->ofp, "classify table info :");
4999       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5000              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5001              ntohl (mp->miss_next_index));
5002       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5003              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5004              ntohl (mp->match_n_vectors));
5005       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5006              ntohl (mp->mask_length));
5007     }
5008   vam->retval = retval;
5009   vam->result_ready = 1;
5010 }
5011
5012 static void
5013   vl_api_classify_table_info_reply_t_handler_json
5014   (vl_api_classify_table_info_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t node;
5018
5019   i32 retval = ntohl (mp->retval);
5020   if (retval == 0)
5021     {
5022       vat_json_init_object (&node);
5023
5024       vat_json_object_add_int (&node, "sessions",
5025                                ntohl (mp->active_sessions));
5026       vat_json_object_add_int (&node, "nexttbl",
5027                                ntohl (mp->next_table_index));
5028       vat_json_object_add_int (&node, "nextnode",
5029                                ntohl (mp->miss_next_index));
5030       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5031       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5032       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5033       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5034                       ntohl (mp->mask_length), 0);
5035       vat_json_object_add_string_copy (&node, "mask", s);
5036
5037       vat_json_print (vam->ofp, &node);
5038       vat_json_free (&node);
5039     }
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void
5045 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5046                                            mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049
5050   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5051          ntohl (mp->hit_next_index), ntohl (mp->advance),
5052          ntohl (mp->opaque_index));
5053   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5054          ntohl (mp->match_length));
5055 }
5056
5057 static void
5058   vl_api_classify_session_details_t_handler_json
5059   (vl_api_classify_session_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   vat_json_node_t *node = NULL;
5063
5064   if (VAT_JSON_ARRAY != vam->json_tree.type)
5065     {
5066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5067       vat_json_init_array (&vam->json_tree);
5068     }
5069   node = vat_json_array_add (&vam->json_tree);
5070
5071   vat_json_init_object (node);
5072   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5073   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5074   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5075   u8 *s =
5076     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5077             0);
5078   vat_json_object_add_string_copy (node, "match", s);
5079 }
5080
5081 static void vl_api_pg_create_interface_reply_t_handler
5082   (vl_api_pg_create_interface_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085
5086   vam->retval = ntohl (mp->retval);
5087   vam->result_ready = 1;
5088 }
5089
5090 static void vl_api_pg_create_interface_reply_t_handler_json
5091   (vl_api_pg_create_interface_reply_t * mp)
5092 {
5093   vat_main_t *vam = &vat_main;
5094   vat_json_node_t node;
5095
5096   i32 retval = ntohl (mp->retval);
5097   if (retval == 0)
5098     {
5099       vat_json_init_object (&node);
5100
5101       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5102
5103       vat_json_print (vam->ofp, &node);
5104       vat_json_free (&node);
5105     }
5106   vam->retval = ntohl (mp->retval);
5107   vam->result_ready = 1;
5108 }
5109
5110 static void vl_api_policer_classify_details_t_handler
5111   (vl_api_policer_classify_details_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114
5115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5116          ntohl (mp->table_index));
5117 }
5118
5119 static void vl_api_policer_classify_details_t_handler_json
5120   (vl_api_policer_classify_details_t * mp)
5121 {
5122   vat_main_t *vam = &vat_main;
5123   vat_json_node_t *node;
5124
5125   if (VAT_JSON_ARRAY != vam->json_tree.type)
5126     {
5127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5128       vat_json_init_array (&vam->json_tree);
5129     }
5130   node = vat_json_array_add (&vam->json_tree);
5131
5132   vat_json_init_object (node);
5133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5138   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   i32 retval = ntohl (mp->retval);
5142   if (vam->async_mode)
5143     {
5144       vam->async_errors += (retval < 0);
5145     }
5146   else
5147     {
5148       vam->retval = retval;
5149       vam->sw_if_index = ntohl (mp->sw_if_index);
5150       vam->result_ready = 1;
5151     }
5152 }
5153
5154 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5155   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5156 {
5157   vat_main_t *vam = &vat_main;
5158   vat_json_node_t node;
5159
5160   vat_json_init_object (&node);
5161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5162   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5163
5164   vat_json_print (vam->ofp, &node);
5165   vat_json_free (&node);
5166
5167   vam->retval = ntohl (mp->retval);
5168   vam->result_ready = 1;
5169 }
5170
5171 static void vl_api_flow_classify_details_t_handler
5172   (vl_api_flow_classify_details_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175
5176   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5177          ntohl (mp->table_index));
5178 }
5179
5180 static void vl_api_flow_classify_details_t_handler_json
5181   (vl_api_flow_classify_details_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t *node;
5185
5186   if (VAT_JSON_ARRAY != vam->json_tree.type)
5187     {
5188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5189       vat_json_init_array (&vam->json_tree);
5190     }
5191   node = vat_json_array_add (&vam->json_tree);
5192
5193   vat_json_init_object (node);
5194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5195   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5196 }
5197
5198 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5199 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5200 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5201 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5202 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5203 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5204 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5205 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5206 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5207 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5208 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5209 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5210 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5211 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5212 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5213 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5214 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5215 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5216 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5217 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5218 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5219 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5220
5221 /*
5222  * Generate boilerplate reply handlers, which
5223  * dig the return value out of the xxx_reply_t API message,
5224  * stick it into vam->retval, and set vam->result_ready
5225  *
5226  * Could also do this by pointing N message decode slots at
5227  * a single function, but that could break in subtle ways.
5228  */
5229
5230 #define foreach_standard_reply_retval_handler           \
5231 _(sw_interface_set_flags_reply)                         \
5232 _(sw_interface_add_del_address_reply)                   \
5233 _(sw_interface_set_rx_mode_reply)                       \
5234 _(sw_interface_set_table_reply)                         \
5235 _(sw_interface_set_mpls_enable_reply)                   \
5236 _(sw_interface_set_vpath_reply)                         \
5237 _(sw_interface_set_vxlan_bypass_reply)                  \
5238 _(sw_interface_set_geneve_bypass_reply)                 \
5239 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5240 _(sw_interface_set_l2_bridge_reply)                     \
5241 _(bridge_domain_add_del_reply)                          \
5242 _(sw_interface_set_l2_xconnect_reply)                   \
5243 _(l2fib_add_del_reply)                                  \
5244 _(l2fib_flush_int_reply)                                \
5245 _(l2fib_flush_bd_reply)                                 \
5246 _(ip_add_del_route_reply)                               \
5247 _(ip_table_add_del_reply)                               \
5248 _(ip_mroute_add_del_reply)                              \
5249 _(mpls_route_add_del_reply)                             \
5250 _(mpls_table_add_del_reply)                             \
5251 _(mpls_ip_bind_unbind_reply)                            \
5252 _(bier_route_add_del_reply)                             \
5253 _(bier_table_add_del_reply)                             \
5254 _(proxy_arp_add_del_reply)                              \
5255 _(proxy_arp_intfc_enable_disable_reply)                 \
5256 _(sw_interface_set_unnumbered_reply)                    \
5257 _(ip_neighbor_add_del_reply)                            \
5258 _(oam_add_del_reply)                                    \
5259 _(reset_fib_reply)                                      \
5260 _(dhcp_proxy_config_reply)                              \
5261 _(dhcp_proxy_set_vss_reply)                             \
5262 _(dhcp_client_config_reply)                             \
5263 _(set_ip_flow_hash_reply)                               \
5264 _(sw_interface_ip6_enable_disable_reply)                \
5265 _(sw_interface_ip6_set_link_local_address_reply)        \
5266 _(ip6nd_proxy_add_del_reply)                            \
5267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5268 _(sw_interface_ip6nd_ra_config_reply)                   \
5269 _(set_arp_neighbor_limit_reply)                         \
5270 _(l2_patch_add_del_reply)                               \
5271 _(sr_policy_add_reply)                                  \
5272 _(sr_policy_mod_reply)                                  \
5273 _(sr_policy_del_reply)                                  \
5274 _(sr_localsid_add_del_reply)                            \
5275 _(sr_steering_add_del_reply)                            \
5276 _(classify_add_del_session_reply)                       \
5277 _(classify_set_interface_ip_table_reply)                \
5278 _(classify_set_interface_l2_tables_reply)               \
5279 _(l2tpv3_set_tunnel_cookies_reply)                      \
5280 _(l2tpv3_interface_enable_disable_reply)                \
5281 _(l2tpv3_set_lookup_key_reply)                          \
5282 _(l2_fib_clear_table_reply)                             \
5283 _(l2_interface_efp_filter_reply)                        \
5284 _(l2_interface_vlan_tag_rewrite_reply)                  \
5285 _(modify_vhost_user_if_reply)                           \
5286 _(delete_vhost_user_if_reply)                           \
5287 _(want_ip4_arp_events_reply)                            \
5288 _(want_ip6_nd_events_reply)                             \
5289 _(want_l2_macs_events_reply)                            \
5290 _(input_acl_set_interface_reply)                        \
5291 _(ipsec_spd_add_del_reply)                              \
5292 _(ipsec_interface_add_del_spd_reply)                    \
5293 _(ipsec_spd_add_del_entry_reply)                        \
5294 _(ipsec_sad_add_del_entry_reply)                        \
5295 _(ipsec_sa_set_key_reply)                               \
5296 _(ipsec_tunnel_if_add_del_reply)                        \
5297 _(ipsec_tunnel_if_set_key_reply)                        \
5298 _(ipsec_tunnel_if_set_sa_reply)                         \
5299 _(ikev2_profile_add_del_reply)                          \
5300 _(ikev2_profile_set_auth_reply)                         \
5301 _(ikev2_profile_set_id_reply)                           \
5302 _(ikev2_profile_set_ts_reply)                           \
5303 _(ikev2_set_local_key_reply)                            \
5304 _(ikev2_set_responder_reply)                            \
5305 _(ikev2_set_ike_transforms_reply)                       \
5306 _(ikev2_set_esp_transforms_reply)                       \
5307 _(ikev2_set_sa_lifetime_reply)                          \
5308 _(ikev2_initiate_sa_init_reply)                         \
5309 _(ikev2_initiate_del_ike_sa_reply)                      \
5310 _(ikev2_initiate_del_child_sa_reply)                    \
5311 _(ikev2_initiate_rekey_child_sa_reply)                  \
5312 _(delete_loopback_reply)                                \
5313 _(bd_ip_mac_add_del_reply)                              \
5314 _(map_del_domain_reply)                                 \
5315 _(map_add_del_rule_reply)                               \
5316 _(want_interface_events_reply)                          \
5317 _(want_stats_reply)                                     \
5318 _(cop_interface_enable_disable_reply)                   \
5319 _(cop_whitelist_enable_disable_reply)                   \
5320 _(sw_interface_clear_stats_reply)                       \
5321 _(ioam_enable_reply)                                    \
5322 _(ioam_disable_reply)                                   \
5323 _(one_add_del_locator_reply)                            \
5324 _(one_add_del_local_eid_reply)                          \
5325 _(one_add_del_remote_mapping_reply)                     \
5326 _(one_add_del_adjacency_reply)                          \
5327 _(one_add_del_map_resolver_reply)                       \
5328 _(one_add_del_map_server_reply)                         \
5329 _(one_enable_disable_reply)                             \
5330 _(one_rloc_probe_enable_disable_reply)                  \
5331 _(one_map_register_enable_disable_reply)                \
5332 _(one_map_register_set_ttl_reply)                       \
5333 _(one_set_transport_protocol_reply)                     \
5334 _(one_map_register_fallback_threshold_reply)            \
5335 _(one_pitr_set_locator_set_reply)                       \
5336 _(one_map_request_mode_reply)                           \
5337 _(one_add_del_map_request_itr_rlocs_reply)              \
5338 _(one_eid_table_add_del_map_reply)                      \
5339 _(one_use_petr_reply)                                   \
5340 _(one_stats_enable_disable_reply)                       \
5341 _(one_add_del_l2_arp_entry_reply)                       \
5342 _(one_add_del_ndp_entry_reply)                          \
5343 _(one_stats_flush_reply)                                \
5344 _(one_enable_disable_xtr_mode_reply)                    \
5345 _(one_enable_disable_pitr_mode_reply)                   \
5346 _(one_enable_disable_petr_mode_reply)                   \
5347 _(gpe_enable_disable_reply)                             \
5348 _(gpe_set_encap_mode_reply)                             \
5349 _(gpe_add_del_iface_reply)                              \
5350 _(gpe_add_del_native_fwd_rpath_reply)                   \
5351 _(af_packet_delete_reply)                               \
5352 _(policer_classify_set_interface_reply)                 \
5353 _(netmap_create_reply)                                  \
5354 _(netmap_delete_reply)                                  \
5355 _(set_ipfix_exporter_reply)                             \
5356 _(set_ipfix_classify_stream_reply)                      \
5357 _(ipfix_classify_table_add_del_reply)                   \
5358 _(flow_classify_set_interface_reply)                    \
5359 _(sw_interface_span_enable_disable_reply)               \
5360 _(pg_capture_reply)                                     \
5361 _(pg_enable_disable_reply)                              \
5362 _(ip_source_and_port_range_check_add_del_reply)         \
5363 _(ip_source_and_port_range_check_interface_add_del_reply)\
5364 _(delete_subif_reply)                                   \
5365 _(l2_interface_pbb_tag_rewrite_reply)                   \
5366 _(punt_reply)                                           \
5367 _(feature_enable_disable_reply)                         \
5368 _(sw_interface_tag_add_del_reply)                       \
5369 _(sw_interface_set_mtu_reply)                           \
5370 _(p2p_ethernet_add_reply)                               \
5371 _(p2p_ethernet_del_reply)                               \
5372 _(lldp_config_reply)                                    \
5373 _(sw_interface_set_lldp_reply)                          \
5374 _(tcp_configure_src_addresses_reply)                    \
5375 _(dns_enable_disable_reply)                             \
5376 _(dns_name_server_add_del_reply)                        \
5377 _(session_rule_add_del_reply)                           \
5378 _(ip_container_proxy_add_del_reply)
5379
5380 #define _(n)                                    \
5381     static void vl_api_##n##_t_handler          \
5382     (vl_api_##n##_t * mp)                       \
5383     {                                           \
5384         vat_main_t * vam = &vat_main;           \
5385         i32 retval = ntohl(mp->retval);         \
5386         if (vam->async_mode) {                  \
5387             vam->async_errors += (retval < 0);  \
5388         } else {                                \
5389             vam->retval = retval;               \
5390             vam->result_ready = 1;              \
5391         }                                       \
5392     }
5393 foreach_standard_reply_retval_handler;
5394 #undef _
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler_json     \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         vat_json_node_t node;                   \
5402         vat_json_init_object(&node);            \
5403         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5404         vat_json_print(vam->ofp, &node);        \
5405         vam->retval = ntohl(mp->retval);        \
5406         vam->result_ready = 1;                  \
5407     }
5408 foreach_standard_reply_retval_handler;
5409 #undef _
5410
5411 /*
5412  * Table of message reply handlers, must include boilerplate handlers
5413  * we just generated
5414  */
5415
5416 #define foreach_vpe_api_reply_msg                                       \
5417 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5418 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5419 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5420 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5421 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5422 _(CLI_REPLY, cli_reply)                                                 \
5423 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5424 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5425   sw_interface_add_del_address_reply)                                   \
5426 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5427 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5428 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5429 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5430 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5431 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5432 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5433 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5434   sw_interface_set_l2_xconnect_reply)                                   \
5435 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5436   sw_interface_set_l2_bridge_reply)                                     \
5437 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5438 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5439 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5440 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5441 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5442 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5443 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5444 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5445 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5446 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5447 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5448 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5449 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5450 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5451 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5453 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5454 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5455 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5456 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5457 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5458 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5459 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5460 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5461 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5462   proxy_arp_intfc_enable_disable_reply)                                 \
5463 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5465   sw_interface_set_unnumbered_reply)                                    \
5466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5472 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5473 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5477   sw_interface_ip6_enable_disable_reply)                                \
5478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5479   sw_interface_ip6_set_link_local_address_reply)                        \
5480 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5481 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5483   sw_interface_ip6nd_ra_prefix_reply)                                   \
5484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5485   sw_interface_ip6nd_ra_config_reply)                                   \
5486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5488 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5489 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5490 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5491 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5492 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5493 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5494 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5495 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5496 classify_set_interface_ip_table_reply)                                  \
5497 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5498   classify_set_interface_l2_tables_reply)                               \
5499 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5500 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5501 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5502 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5503 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5504   l2tpv3_interface_enable_disable_reply)                                \
5505 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5506 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5507 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5508 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5509 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5510 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5511 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5512 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5513 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5514 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5515 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5516 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5517 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5518 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5519 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5520 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5521 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5522 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5523 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5524 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5525 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5526 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5527 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5528 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5529 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5530 _(L2_MACS_EVENT, l2_macs_event)                                         \
5531 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5532 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5533 _(IP_DETAILS, ip_details)                                               \
5534 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5535 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5536 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5537 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5538 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5539 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5540 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5541 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5542 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5543 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5544 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5545 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5546 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5547 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5548 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5549 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5550 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5551 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5552 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5553 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5554 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5555 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5556 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5557 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5558 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5571 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5572 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5573 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5574 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5575 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5576 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5577 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5578 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5579 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5580 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5581 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5582   one_map_register_enable_disable_reply)                                \
5583 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5584 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5585 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5586 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5587   one_map_register_fallback_threshold_reply)                            \
5588 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5589   one_rloc_probe_enable_disable_reply)                                  \
5590 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5591 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5592 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5593 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5594 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5595 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5596 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5597 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5598 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5599 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5600 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5601 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5602 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5603 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5604 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5605 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5606   show_one_stats_enable_disable_reply)                                  \
5607 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5608 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5609 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5610 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5611 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5612 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5613 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5614 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5615   one_enable_disable_pitr_mode_reply)                                   \
5616 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5617   one_enable_disable_petr_mode_reply)                                   \
5618 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5619 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5620 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5621 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5622 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5623 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5624 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5625 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5626 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5627 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5628 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5629 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5630   gpe_add_del_native_fwd_rpath_reply)                                   \
5631 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5632   gpe_fwd_entry_path_details)                                           \
5633 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5634 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5635   one_add_del_map_request_itr_rlocs_reply)                              \
5636 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5637   one_get_map_request_itr_rlocs_reply)                                  \
5638 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5639 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5640 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5641 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5642 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5643 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5644   show_one_map_register_state_reply)                                    \
5645 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5646 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5647   show_one_map_register_fallback_threshold_reply)                       \
5648 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5649 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5650 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5651 _(POLICER_DETAILS, policer_details)                                     \
5652 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5653 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5654 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5655 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5656 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5657 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5658 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5659 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5660 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5661 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5662 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5663 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5664 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5665 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5666 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5667 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5668 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5669 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5670 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5671 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5672 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5673 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5674 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5675 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5676 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5677  ip_source_and_port_range_check_add_del_reply)                          \
5678 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5679  ip_source_and_port_range_check_interface_add_del_reply)                \
5680 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5681 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5682 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5683 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5684 _(PUNT_REPLY, punt_reply)                                               \
5685 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5686 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5687 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5688 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5689 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5690 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5691 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5692 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5693 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5694 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5695 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5696 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5697 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5698 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5699 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5700 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5701 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5702 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5703 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5704 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5705 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5706
5707 #define foreach_standalone_reply_msg                                    \
5708 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5709 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5710 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5713 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5714 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5715 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5716
5717 typedef struct
5718 {
5719   u8 *name;
5720   u32 value;
5721 } name_sort_t;
5722
5723
5724 #define STR_VTR_OP_CASE(op)     \
5725     case L2_VTR_ ## op:         \
5726         return "" # op;
5727
5728 static const char *
5729 str_vtr_op (u32 vtr_op)
5730 {
5731   switch (vtr_op)
5732     {
5733       STR_VTR_OP_CASE (DISABLED);
5734       STR_VTR_OP_CASE (PUSH_1);
5735       STR_VTR_OP_CASE (PUSH_2);
5736       STR_VTR_OP_CASE (POP_1);
5737       STR_VTR_OP_CASE (POP_2);
5738       STR_VTR_OP_CASE (TRANSLATE_1_1);
5739       STR_VTR_OP_CASE (TRANSLATE_1_2);
5740       STR_VTR_OP_CASE (TRANSLATE_2_1);
5741       STR_VTR_OP_CASE (TRANSLATE_2_2);
5742     }
5743
5744   return "UNKNOWN";
5745 }
5746
5747 static int
5748 dump_sub_interface_table (vat_main_t * vam)
5749 {
5750   const sw_interface_subif_t *sub = NULL;
5751
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   print (vam->ofp,
5760          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5761          "Interface", "sw_if_index",
5762          "sub id", "dot1ad", "tags", "outer id",
5763          "inner id", "exact", "default", "outer any", "inner any");
5764
5765   vec_foreach (sub, vam->sw_if_subif_table)
5766   {
5767     print (vam->ofp,
5768            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5769            sub->interface_name,
5770            sub->sw_if_index,
5771            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5772            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5773            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5774            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5775     if (sub->vtr_op != L2_VTR_DISABLED)
5776       {
5777         print (vam->ofp,
5778                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5779                "tag1: %d tag2: %d ]",
5780                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5781                sub->vtr_tag1, sub->vtr_tag2);
5782       }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 name_sort_cmp (void *a1, void *a2)
5790 {
5791   name_sort_t *n1 = a1;
5792   name_sort_t *n2 = a2;
5793
5794   return strcmp ((char *) n1->name, (char *) n2->name);
5795 }
5796
5797 static int
5798 dump_interface_table (vat_main_t * vam)
5799 {
5800   hash_pair_t *p;
5801   name_sort_t *nses = 0, *ns;
5802
5803   if (vam->json_output)
5804     {
5805       clib_warning
5806         ("JSON output supported only for VPE API calls and dump_stats_table");
5807       return -99;
5808     }
5809
5810   /* *INDENT-OFF* */
5811   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5812   ({
5813     vec_add2 (nses, ns, 1);
5814     ns->name = (u8 *)(p->key);
5815     ns->value = (u32) p->value[0];
5816   }));
5817   /* *INDENT-ON* */
5818
5819   vec_sort_with_function (nses, name_sort_cmp);
5820
5821   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5822   vec_foreach (ns, nses)
5823   {
5824     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5825   }
5826   vec_free (nses);
5827   return 0;
5828 }
5829
5830 static int
5831 dump_ip_table (vat_main_t * vam, int is_ipv6)
5832 {
5833   const ip_details_t *det = NULL;
5834   const ip_address_details_t *address = NULL;
5835   u32 i = ~0;
5836
5837   print (vam->ofp, "%-12s", "sw_if_index");
5838
5839   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5840   {
5841     i++;
5842     if (!det->present)
5843       {
5844         continue;
5845       }
5846     print (vam->ofp, "%-12d", i);
5847     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5848     if (!det->addr)
5849       {
5850         continue;
5851       }
5852     vec_foreach (address, det->addr)
5853     {
5854       print (vam->ofp,
5855              "            %-30U%-13d",
5856              is_ipv6 ? format_ip6_address : format_ip4_address,
5857              address->ip, address->prefix_length);
5858     }
5859   }
5860
5861   return 0;
5862 }
5863
5864 static int
5865 dump_ipv4_table (vat_main_t * vam)
5866 {
5867   if (vam->json_output)
5868     {
5869       clib_warning
5870         ("JSON output supported only for VPE API calls and dump_stats_table");
5871       return -99;
5872     }
5873
5874   return dump_ip_table (vam, 0);
5875 }
5876
5877 static int
5878 dump_ipv6_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 1);
5888 }
5889
5890 static char *
5891 counter_type_to_str (u8 counter_type, u8 is_combined)
5892 {
5893   if (!is_combined)
5894     {
5895       switch (counter_type)
5896         {
5897         case VNET_INTERFACE_COUNTER_DROP:
5898           return "drop";
5899         case VNET_INTERFACE_COUNTER_PUNT:
5900           return "punt";
5901         case VNET_INTERFACE_COUNTER_IP4:
5902           return "ip4";
5903         case VNET_INTERFACE_COUNTER_IP6:
5904           return "ip6";
5905         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5906           return "rx-no-buf";
5907         case VNET_INTERFACE_COUNTER_RX_MISS:
5908           return "rx-miss";
5909         case VNET_INTERFACE_COUNTER_RX_ERROR:
5910           return "rx-error";
5911         case VNET_INTERFACE_COUNTER_TX_ERROR:
5912           return "tx-error";
5913         default:
5914           return "INVALID-COUNTER-TYPE";
5915         }
5916     }
5917   else
5918     {
5919       switch (counter_type)
5920         {
5921         case VNET_INTERFACE_COUNTER_RX:
5922           return "rx";
5923         case VNET_INTERFACE_COUNTER_TX:
5924           return "tx";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929 }
5930
5931 static int
5932 dump_stats_table (vat_main_t * vam)
5933 {
5934   vat_json_node_t node;
5935   vat_json_node_t *msg_array;
5936   vat_json_node_t *msg;
5937   vat_json_node_t *counter_array;
5938   vat_json_node_t *counter;
5939   interface_counter_t c;
5940   u64 packets;
5941   ip4_fib_counter_t *c4;
5942   ip6_fib_counter_t *c6;
5943   ip4_nbr_counter_t *n4;
5944   ip6_nbr_counter_t *n6;
5945   int i, j;
5946
5947   if (!vam->json_output)
5948     {
5949       clib_warning ("dump_stats_table supported only in JSON format");
5950       return -99;
5951     }
5952
5953   vat_json_init_object (&node);
5954
5955   /* interface counters */
5956   msg_array = vat_json_object_add (&node, "interface_counters");
5957   vat_json_init_array (msg_array);
5958   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5959     {
5960       msg = vat_json_array_add (msg_array);
5961       vat_json_init_object (msg);
5962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5963                                        (u8 *) counter_type_to_str (i, 0));
5964       vat_json_object_add_int (msg, "is_combined", 0);
5965       counter_array = vat_json_object_add (msg, "data");
5966       vat_json_init_array (counter_array);
5967       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5968         {
5969           packets = vam->simple_interface_counters[i][j];
5970           vat_json_array_add_uint (counter_array, packets);
5971         }
5972     }
5973   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5978                                        (u8 *) counter_type_to_str (i, 1));
5979       vat_json_object_add_int (msg, "is_combined", 1);
5980       counter_array = vat_json_object_add (msg, "data");
5981       vat_json_init_array (counter_array);
5982       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5983         {
5984           c = vam->combined_interface_counters[i][j];
5985           counter = vat_json_array_add (counter_array);
5986           vat_json_init_object (counter);
5987           vat_json_object_add_uint (counter, "packets", c.packets);
5988           vat_json_object_add_uint (counter, "bytes", c.bytes);
5989         }
5990     }
5991
5992   /* ip4 fib counters */
5993   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "vrf_id",
6000                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           c4 = &vam->ip4_fib_counters[i][j];
6008           vat_json_object_add_ip4 (counter, "address", c4->address);
6009           vat_json_object_add_uint (counter, "address_length",
6010                                     c4->address_length);
6011           vat_json_object_add_uint (counter, "packets", c4->packets);
6012           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6013         }
6014     }
6015
6016   /* ip6 fib counters */
6017   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6018   vat_json_init_array (msg_array);
6019   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6020     {
6021       msg = vat_json_array_add (msg_array);
6022       vat_json_init_object (msg);
6023       vat_json_object_add_uint (msg, "vrf_id",
6024                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6025       counter_array = vat_json_object_add (msg, "c");
6026       vat_json_init_array (counter_array);
6027       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6028         {
6029           counter = vat_json_array_add (counter_array);
6030           vat_json_init_object (counter);
6031           c6 = &vam->ip6_fib_counters[i][j];
6032           vat_json_object_add_ip6 (counter, "address", c6->address);
6033           vat_json_object_add_uint (counter, "address_length",
6034                                     c6->address_length);
6035           vat_json_object_add_uint (counter, "packets", c6->packets);
6036           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6037         }
6038     }
6039
6040   /* ip4 nbr counters */
6041   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6042   vat_json_init_array (msg_array);
6043   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6044     {
6045       msg = vat_json_array_add (msg_array);
6046       vat_json_init_object (msg);
6047       vat_json_object_add_uint (msg, "sw_if_index", i);
6048       counter_array = vat_json_object_add (msg, "c");
6049       vat_json_init_array (counter_array);
6050       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6051         {
6052           counter = vat_json_array_add (counter_array);
6053           vat_json_init_object (counter);
6054           n4 = &vam->ip4_nbr_counters[i][j];
6055           vat_json_object_add_ip4 (counter, "address", n4->address);
6056           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6057           vat_json_object_add_uint (counter, "packets", n4->packets);
6058           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6059         }
6060     }
6061
6062   /* ip6 nbr counters */
6063   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6064   vat_json_init_array (msg_array);
6065   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6066     {
6067       msg = vat_json_array_add (msg_array);
6068       vat_json_init_object (msg);
6069       vat_json_object_add_uint (msg, "sw_if_index", i);
6070       counter_array = vat_json_object_add (msg, "c");
6071       vat_json_init_array (counter_array);
6072       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6073         {
6074           counter = vat_json_array_add (counter_array);
6075           vat_json_init_object (counter);
6076           n6 = &vam->ip6_nbr_counters[i][j];
6077           vat_json_object_add_ip6 (counter, "address", n6->address);
6078           vat_json_object_add_uint (counter, "packets", n6->packets);
6079           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6080         }
6081     }
6082
6083   vat_json_print (vam->ofp, &node);
6084   vat_json_free (&node);
6085
6086   return 0;
6087 }
6088
6089 /*
6090  * Pass CLI buffers directly in the CLI_INBAND API message,
6091  * instead of an additional shared memory area.
6092  */
6093 static int
6094 exec_inband (vat_main_t * vam)
6095 {
6096   vl_api_cli_inband_t *mp;
6097   unformat_input_t *i = vam->input;
6098   int ret;
6099
6100   if (vec_len (i->buffer) == 0)
6101     return -1;
6102
6103   if (vam->exec_mode == 0 && unformat (i, "mode"))
6104     {
6105       vam->exec_mode = 1;
6106       return 0;
6107     }
6108   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6109     {
6110       vam->exec_mode = 0;
6111       return 0;
6112     }
6113
6114   /*
6115    * In order for the CLI command to work, it
6116    * must be a vector ending in \n, not a C-string ending
6117    * in \n\0.
6118    */
6119   u32 len = vec_len (vam->input->buffer);
6120   M2 (CLI_INBAND, mp, len);
6121   clib_memcpy (mp->cmd, vam->input->buffer, len);
6122   mp->length = htonl (len);
6123
6124   S (mp);
6125   W (ret);
6126   /* json responses may or may not include a useful reply... */
6127   if (vec_len (vam->cmd_reply))
6128     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6129   return ret;
6130 }
6131
6132 int
6133 exec (vat_main_t * vam)
6134 {
6135   return exec_inband (vam);
6136 }
6137
6138 static int
6139 api_create_loopback (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_create_loopback_t *mp;
6143   vl_api_create_loopback_instance_t *mp_lbi;
6144   u8 mac_address[6];
6145   u8 mac_set = 0;
6146   u8 is_specified = 0;
6147   u32 user_instance = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6155         mac_set = 1;
6156       if (unformat (i, "instance %d", &user_instance))
6157         is_specified = 1;
6158       else
6159         break;
6160     }
6161
6162   if (is_specified)
6163     {
6164       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6165       mp_lbi->is_specified = is_specified;
6166       if (is_specified)
6167         mp_lbi->user_instance = htonl (user_instance);
6168       if (mac_set)
6169         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6170       S (mp_lbi);
6171     }
6172   else
6173     {
6174       /* Construct the API message */
6175       M (CREATE_LOOPBACK, mp);
6176       if (mac_set)
6177         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6178       S (mp);
6179     }
6180
6181   W (ret);
6182   return ret;
6183 }
6184
6185 static int
6186 api_delete_loopback (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_delete_loopback_t *mp;
6190   u32 sw_if_index = ~0;
6191   int ret;
6192
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         ;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index == ~0)
6202     {
6203       errmsg ("missing sw_if_index");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (DELETE_LOOPBACK, mp);
6209   mp->sw_if_index = ntohl (sw_if_index);
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_want_stats (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_want_stats_t *mp;
6221   int enable = -1;
6222   int ret;
6223
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (enable == -1)
6235     {
6236       errmsg ("missing enable|disable");
6237       return -99;
6238     }
6239
6240   M (WANT_STATS, mp);
6241   mp->enable_disable = enable;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_want_interface_events (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_want_interface_events_t *mp;
6253   int enable = -1;
6254   int ret;
6255
6256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6257     {
6258       if (unformat (i, "enable"))
6259         enable = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (enable == -1)
6267     {
6268       errmsg ("missing enable|disable");
6269       return -99;
6270     }
6271
6272   M (WANT_INTERFACE_EVENTS, mp);
6273   mp->enable_disable = enable;
6274
6275   vam->interface_event_display = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282
6283 /* Note: non-static, called once to set up the initial intfc table */
6284 int
6285 api_sw_interface_dump (vat_main_t * vam)
6286 {
6287   vl_api_sw_interface_dump_t *mp;
6288   vl_api_control_ping_t *mp_ping;
6289   hash_pair_t *p;
6290   name_sort_t *nses = 0, *ns;
6291   sw_interface_subif_t *sub = NULL;
6292   int ret;
6293
6294   /* Toss the old name table */
6295   /* *INDENT-OFF* */
6296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6297   ({
6298     vec_add2 (nses, ns, 1);
6299     ns->name = (u8 *)(p->key);
6300     ns->value = (u32) p->value[0];
6301   }));
6302   /* *INDENT-ON* */
6303
6304   hash_free (vam->sw_if_index_by_interface_name);
6305
6306   vec_foreach (ns, nses) vec_free (ns->name);
6307
6308   vec_free (nses);
6309
6310   vec_foreach (sub, vam->sw_if_subif_table)
6311   {
6312     vec_free (sub->interface_name);
6313   }
6314   vec_free (vam->sw_if_subif_table);
6315
6316   /* recreate the interface name hash table */
6317   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6318
6319   /* Get list of ethernets */
6320   M (SW_INTERFACE_DUMP, mp);
6321   mp->name_filter_valid = 1;
6322   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6323   S (mp);
6324
6325   /* and local / loopback interfaces */
6326   M (SW_INTERFACE_DUMP, mp);
6327   mp->name_filter_valid = 1;
6328   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6329   S (mp);
6330
6331   /* and packet-generator interfaces */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and vxlan-gpe tunnel interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6341            sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and vxlan tunnel interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and geneve tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and host (af_packet) interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and l2tpv3 tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6366            sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and GRE tunnel interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and LISP-GPE interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "lisp_gpe",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and IPSEC tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* Use a control ping for synchronization */
6389   MPING (CONTROL_PING, mp_ping);
6390   S (mp_ping);
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_flags (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_flags_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   u8 admin_up = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "admin-up"))
6410         admin_up = 1;
6411       else if (unformat (i, "admin-down"))
6412         admin_up = 0;
6413       else
6414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         sw_if_index_set = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_FLAGS, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->admin_up_down = admin_up;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply, return the good/bad news... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_rx_mode (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_rx_mode_t *mp;
6446   u32 sw_if_index;
6447   u8 sw_if_index_set = 0;
6448   int ret;
6449   u8 queue_id_valid = 0;
6450   u32 queue_id;
6451   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "queue %d", &queue_id))
6457         queue_id_valid = 1;
6458       else if (unformat (i, "polling"))
6459         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6460       else if (unformat (i, "interrupt"))
6461         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6462       else if (unformat (i, "adaptive"))
6463         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6464       else
6465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6479     {
6480       errmsg ("missing rx-mode");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (SW_INTERFACE_SET_RX_MODE, mp);
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->mode = mode;
6488   mp->queue_id_valid = queue_id_valid;
6489   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6490
6491   /* send it... */
6492   S (mp);
6493
6494   /* Wait for a reply, return the good/bad news... */
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_clear_stats (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_clear_stats_t *mp;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else
6516         break;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_CLEAR_STATS, mp);
6521
6522   if (sw_if_index_set == 1)
6523     mp->sw_if_index = ntohl (sw_if_index);
6524   else
6525     mp->sw_if_index = ~0;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply, return the good/bad news... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_add_del_address (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_add_del_address_t *mp;
6540   u32 sw_if_index;
6541   u8 sw_if_index_set = 0;
6542   u8 is_add = 1, del_all = 0;
6543   u32 address_length = 0;
6544   u8 v4_address_set = 0;
6545   u8 v6_address_set = 0;
6546   ip4_address_t v4address;
6547   ip6_address_t v6address;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "del-all"))
6554         del_all = 1;
6555       else if (unformat (i, "del"))
6556         is_add = 0;
6557       else
6558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "%U/%d",
6563                          unformat_ip4_address, &v4address, &address_length))
6564         v4_address_set = 1;
6565       else if (unformat (i, "%U/%d",
6566                          unformat_ip6_address, &v6address, &address_length))
6567         v6_address_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577   if (v4_address_set && v6_address_set)
6578     {
6579       errmsg ("both v4 and v6 addresses set");
6580       return -99;
6581     }
6582   if (!v4_address_set && !v6_address_set && !del_all)
6583     {
6584       errmsg ("no addresses set");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6590
6591   mp->sw_if_index = ntohl (sw_if_index);
6592   mp->is_add = is_add;
6593   mp->del_all = del_all;
6594   if (v6_address_set)
6595     {
6596       mp->is_ipv6 = 1;
6597       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6598     }
6599   else
6600     {
6601       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6602     }
6603   mp->address_length = address_length;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return good/bad news  */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_mpls_enable_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "disable"))
6631         enable = 0;
6632       else if (unformat (i, "dis"))
6633         enable = 0;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->enable = enable;
6649
6650   /* send it... */
6651   S (mp);
6652
6653   /* Wait for a reply... */
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_sw_interface_set_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_set_table_t *mp;
6663   u32 sw_if_index, vrf_id = 0;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "vrf %d", &vrf_id))
6676         ;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   /* Construct the API message */
6690   M (SW_INTERFACE_SET_TABLE, mp);
6691
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694   mp->vrf_id = ntohl (vrf_id);
6695
6696   /* send it... */
6697   S (mp);
6698
6699   /* Wait for a reply... */
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static void vl_api_sw_interface_get_table_reply_t_handler
6705   (vl_api_sw_interface_get_table_reply_t * mp)
6706 {
6707   vat_main_t *vam = &vat_main;
6708
6709   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6710
6711   vam->retval = ntohl (mp->retval);
6712   vam->result_ready = 1;
6713
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler_json
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t node;
6721
6722   vat_json_init_object (&node);
6723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6724   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6725
6726   vat_json_print (vam->ofp, &node);
6727   vat_json_free (&node);
6728
6729   vam->retval = ntohl (mp->retval);
6730   vam->result_ready = 1;
6731 }
6732
6733 static int
6734 api_sw_interface_get_table (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_get_table_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 is_ipv6 = 0;
6741   int ret;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "ipv6"))
6750         is_ipv6 = 1;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   M (SW_INTERFACE_GET_TABLE, mp);
6762   mp->sw_if_index = htonl (sw_if_index);
6763   mp->is_ipv6 = is_ipv6;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vpath (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vpath_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "enable"))
6788         is_enable = 1;
6789       else if (unformat (i, "disable"))
6790         is_enable = 0;
6791       else
6792         break;
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (SW_INTERFACE_SET_VPATH, mp);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->enable = is_enable;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply... */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6820   u32 sw_if_index = 0;
6821   u8 sw_if_index_set = 0;
6822   u8 is_enable = 1;
6823   u8 is_ipv6 = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "enable"))
6834         is_enable = 1;
6835       else if (unformat (i, "disable"))
6836         is_enable = 0;
6837       else if (unformat (i, "ip4"))
6838         is_ipv6 = 0;
6839       else if (unformat (i, "ip6"))
6840         is_ipv6 = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855   mp->enable = is_enable;
6856   mp->is_ipv6 = is_ipv6;
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863   return ret;
6864 }
6865
6866 static int
6867 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_geneve_bypass_t *mp;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_enable = 1;
6874   u8 is_ipv6 = 0;
6875   int ret;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "enable"))
6885         is_enable = 1;
6886       else if (unformat (i, "disable"))
6887         is_enable = 0;
6888       else if (unformat (i, "ip4"))
6889         is_ipv6 = 0;
6890       else if (unformat (i, "ip6"))
6891         is_ipv6 = 1;
6892       else
6893         break;
6894     }
6895
6896   if (sw_if_index_set == 0)
6897     {
6898       errmsg ("missing interface name or sw_if_index");
6899       return -99;
6900     }
6901
6902   /* Construct the API message */
6903   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6904
6905   mp->sw_if_index = ntohl (sw_if_index);
6906   mp->enable = is_enable;
6907   mp->is_ipv6 = is_ipv6;
6908
6909   /* send it... */
6910   S (mp);
6911
6912   /* Wait for a reply... */
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_xconnect_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 tx_sw_if_index;
6925   u8 tx_sw_if_index_set = 0;
6926   u8 enable = 1;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6933         rx_sw_if_index_set = 1;
6934       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6935         tx_sw_if_index_set = 1;
6936       else if (unformat (i, "rx"))
6937         {
6938           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939             {
6940               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6941                             &rx_sw_if_index))
6942                 rx_sw_if_index_set = 1;
6943             }
6944           else
6945             break;
6946         }
6947       else if (unformat (i, "tx"))
6948         {
6949           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950             {
6951               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6952                             &tx_sw_if_index))
6953                 tx_sw_if_index_set = 1;
6954             }
6955           else
6956             break;
6957         }
6958       else if (unformat (i, "enable"))
6959         enable = 1;
6960       else if (unformat (i, "disable"))
6961         enable = 0;
6962       else
6963         break;
6964     }
6965
6966   if (rx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing rx interface name or rx_sw_if_index");
6969       return -99;
6970     }
6971
6972   if (enable && (tx_sw_if_index_set == 0))
6973     {
6974       errmsg ("missing tx interface name or tx_sw_if_index");
6975       return -99;
6976     }
6977
6978   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6979
6980   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6981   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6982   mp->enable = enable;
6983
6984   S (mp);
6985   W (ret);
6986   return ret;
6987 }
6988
6989 static int
6990 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_sw_interface_set_l2_bridge_t *mp;
6994   u32 rx_sw_if_index;
6995   u8 rx_sw_if_index_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u8 bvi = 0;
6999   u32 shg = 0;
7000   u8 enable = 1;
7001   int ret;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7007         rx_sw_if_index_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else
7011         if (unformat
7012             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7013         rx_sw_if_index_set = 1;
7014       else if (unformat (i, "shg %d", &shg))
7015         ;
7016       else if (unformat (i, "bvi"))
7017         bvi = 1;
7018       else if (unformat (i, "enable"))
7019         enable = 1;
7020       else if (unformat (i, "disable"))
7021         enable = 0;
7022       else
7023         break;
7024     }
7025
7026   if (rx_sw_if_index_set == 0)
7027     {
7028       errmsg ("missing rx interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   if (enable && (bd_id_set == 0))
7033     {
7034       errmsg ("missing bridge domain");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7039
7040   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7041   mp->bd_id = ntohl (bd_id);
7042   mp->shg = (u8) shg;
7043   mp->bvi = bvi;
7044   mp->enable = enable;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_bridge_domain_dump (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_bridge_domain_dump_t *mp;
7056   vl_api_control_ping_t *mp_ping;
7057   u32 bd_id = ~0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "bd_id %d", &bd_id))
7064         ;
7065       else
7066         break;
7067     }
7068
7069   M (BRIDGE_DOMAIN_DUMP, mp);
7070   mp->bd_id = ntohl (bd_id);
7071   S (mp);
7072
7073   /* Use a control ping for synchronization */
7074   MPING (CONTROL_PING, mp_ping);
7075   S (mp_ping);
7076
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_bridge_domain_add_del (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_bridge_domain_add_del_t *mp;
7086   u32 bd_id = ~0;
7087   u8 is_add = 1;
7088   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7089   u8 *bd_tag = NULL;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id))
7097         ;
7098       else if (unformat (i, "flood %d", &flood))
7099         ;
7100       else if (unformat (i, "uu-flood %d", &uu_flood))
7101         ;
7102       else if (unformat (i, "forward %d", &forward))
7103         ;
7104       else if (unformat (i, "learn %d", &learn))
7105         ;
7106       else if (unformat (i, "arp-term %d", &arp_term))
7107         ;
7108       else if (unformat (i, "mac-age %d", &mac_age))
7109         ;
7110       else if (unformat (i, "bd-tag %s", &bd_tag))
7111         ;
7112       else if (unformat (i, "del"))
7113         {
7114           is_add = 0;
7115           flood = uu_flood = forward = learn = 0;
7116         }
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       ret = -99;
7125       goto done;
7126     }
7127
7128   if (mac_age > 255)
7129     {
7130       errmsg ("mac age must be less than 256 ");
7131       ret = -99;
7132       goto done;
7133     }
7134
7135   if ((bd_tag) && (vec_len (bd_tag) > 63))
7136     {
7137       errmsg ("bd-tag cannot be longer than 63");
7138       ret = -99;
7139       goto done;
7140     }
7141
7142   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7143
7144   mp->bd_id = ntohl (bd_id);
7145   mp->flood = flood;
7146   mp->uu_flood = uu_flood;
7147   mp->forward = forward;
7148   mp->learn = learn;
7149   mp->arp_term = arp_term;
7150   mp->is_add = is_add;
7151   mp->mac_age = (u8) mac_age;
7152   if (bd_tag)
7153     {
7154       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7155       mp->bd_tag[vec_len (bd_tag)] = 0;
7156     }
7157   S (mp);
7158   W (ret);
7159
7160 done:
7161   vec_free (bd_tag);
7162   return ret;
7163 }
7164
7165 static int
7166 api_l2fib_flush_bd (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_l2fib_flush_bd_t *mp;
7170   u32 bd_id = ~0;
7171   int ret;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id));
7177       else
7178         break;
7179     }
7180
7181   if (bd_id == ~0)
7182     {
7183       errmsg ("missing bridge domain");
7184       return -99;
7185     }
7186
7187   M (L2FIB_FLUSH_BD, mp);
7188
7189   mp->bd_id = htonl (bd_id);
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_l2fib_flush_int (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_l2fib_flush_int_t *mp;
7201   u32 sw_if_index = ~0;
7202   int ret;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "sw_if_index %d", &sw_if_index));
7208       else
7209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7210       else
7211         break;
7212     }
7213
7214   if (sw_if_index == ~0)
7215     {
7216       errmsg ("missing interface name or sw_if_index");
7217       return -99;
7218     }
7219
7220   M (L2FIB_FLUSH_INT, mp);
7221
7222   mp->sw_if_index = ntohl (sw_if_index);
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_add_del (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_add_del_t *mp;
7234   f64 timeout;
7235   u8 mac[6] = { 0 };
7236   u8 mac_set = 0;
7237   u32 bd_id;
7238   u8 bd_id_set = 0;
7239   u32 sw_if_index = ~0;
7240   u8 sw_if_index_set = 0;
7241   u8 is_add = 1;
7242   u8 static_mac = 0;
7243   u8 filter_mac = 0;
7244   u8 bvi_mac = 0;
7245   int count = 1;
7246   f64 before = 0;
7247   int j;
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7253         mac_set = 1;
7254       else if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7257         sw_if_index_set = 1;
7258       else if (unformat (i, "sw_if"))
7259         {
7260           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261             {
7262               if (unformat
7263                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7264                 sw_if_index_set = 1;
7265             }
7266           else
7267             break;
7268         }
7269       else if (unformat (i, "static"))
7270         static_mac = 1;
7271       else if (unformat (i, "filter"))
7272         {
7273           filter_mac = 1;
7274           static_mac = 1;
7275         }
7276       else if (unformat (i, "bvi"))
7277         {
7278           bvi_mac = 1;
7279           static_mac = 1;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "count %d", &count))
7284         ;
7285       else
7286         break;
7287     }
7288
7289   if (mac_set == 0)
7290     {
7291       errmsg ("missing mac address");
7292       return -99;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7302     {
7303       errmsg ("missing interface name or sw_if_index");
7304       return -99;
7305     }
7306
7307   if (count > 1)
7308     {
7309       /* Turn on async mode */
7310       vam->async_mode = 1;
7311       vam->async_errors = 0;
7312       before = vat_time_now (vam);
7313     }
7314
7315   for (j = 0; j < count; j++)
7316     {
7317       M (L2FIB_ADD_DEL, mp);
7318
7319       clib_memcpy (mp->mac, mac, 6);
7320       mp->bd_id = ntohl (bd_id);
7321       mp->is_add = is_add;
7322
7323       if (is_add)
7324         {
7325           mp->sw_if_index = ntohl (sw_if_index);
7326           mp->static_mac = static_mac;
7327           mp->filter_mac = filter_mac;
7328           mp->bvi_mac = bvi_mac;
7329         }
7330       increment_mac_address (mac);
7331       /* send it... */
7332       S (mp);
7333     }
7334
7335   if (count > 1)
7336     {
7337       vl_api_control_ping_t *mp_ping;
7338       f64 after;
7339
7340       /* Shut off async mode */
7341       vam->async_mode = 0;
7342
7343       MPING (CONTROL_PING, mp_ping);
7344       S (mp_ping);
7345
7346       timeout = vat_time_now (vam) + 1.0;
7347       while (vat_time_now (vam) < timeout)
7348         if (vam->result_ready == 1)
7349           goto out;
7350       vam->retval = -99;
7351
7352     out:
7353       if (vam->retval == -99)
7354         errmsg ("timeout");
7355
7356       if (vam->async_errors > 0)
7357         {
7358           errmsg ("%d asynchronous errors", vam->async_errors);
7359           vam->retval = -98;
7360         }
7361       vam->async_errors = 0;
7362       after = vat_time_now (vam);
7363
7364       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7365              count, after - before, count / (after - before));
7366     }
7367   else
7368     {
7369       int ret;
7370
7371       /* Wait for a reply... */
7372       W (ret);
7373       return ret;
7374     }
7375   /* Return the good/bad news */
7376   return (vam->retval);
7377 }
7378
7379 static int
7380 api_bridge_domain_set_mac_age (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bridge_domain_set_mac_age_t *mp;
7384   u32 bd_id = ~0;
7385   u32 mac_age = 0;
7386   int ret;
7387
7388   /* Parse args required to build the message */
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id));
7392       else if (unformat (i, "mac-age %d", &mac_age));
7393       else
7394         break;
7395     }
7396
7397   if (bd_id == ~0)
7398     {
7399       errmsg ("missing bridge domain");
7400       return -99;
7401     }
7402
7403   if (mac_age > 255)
7404     {
7405       errmsg ("mac age must be less than 256 ");
7406       return -99;
7407     }
7408
7409   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7410
7411   mp->bd_id = htonl (bd_id);
7412   mp->mac_age = (u8) mac_age;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_l2_flags (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_l2_flags_t *mp;
7424   u32 sw_if_index;
7425   u32 flags = 0;
7426   u8 sw_if_index_set = 0;
7427   u8 is_set = 0;
7428   int ret;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "sw_if_index %d", &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if"))
7436         {
7437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438             {
7439               if (unformat
7440                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7441                 sw_if_index_set = 1;
7442             }
7443           else
7444             break;
7445         }
7446       else if (unformat (i, "learn"))
7447         flags |= L2_LEARN;
7448       else if (unformat (i, "forward"))
7449         flags |= L2_FWD;
7450       else if (unformat (i, "flood"))
7451         flags |= L2_FLOOD;
7452       else if (unformat (i, "uu-flood"))
7453         flags |= L2_UU_FLOOD;
7454       else if (unformat (i, "arp-term"))
7455         flags |= L2_ARP_TERM;
7456       else if (unformat (i, "off"))
7457         is_set = 0;
7458       else if (unformat (i, "disable"))
7459         is_set = 0;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing interface name or sw_if_index");
7467       return -99;
7468     }
7469
7470   M (L2_FLAGS, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473   mp->feature_bitmap = ntohl (flags);
7474   mp->is_set = is_set;
7475
7476   S (mp);
7477   W (ret);
7478   return ret;
7479 }
7480
7481 static int
7482 api_bridge_flags (vat_main_t * vam)
7483 {
7484   unformat_input_t *i = vam->input;
7485   vl_api_bridge_flags_t *mp;
7486   u32 bd_id;
7487   u8 bd_id_set = 0;
7488   u8 is_set = 1;
7489   u32 flags = 0;
7490   int ret;
7491
7492   /* Parse args required to build the message */
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "bd_id %d", &bd_id))
7496         bd_id_set = 1;
7497       else if (unformat (i, "learn"))
7498         flags |= L2_LEARN;
7499       else if (unformat (i, "forward"))
7500         flags |= L2_FWD;
7501       else if (unformat (i, "flood"))
7502         flags |= L2_FLOOD;
7503       else if (unformat (i, "uu-flood"))
7504         flags |= L2_UU_FLOOD;
7505       else if (unformat (i, "arp-term"))
7506         flags |= L2_ARP_TERM;
7507       else if (unformat (i, "off"))
7508         is_set = 0;
7509       else if (unformat (i, "disable"))
7510         is_set = 0;
7511       else
7512         break;
7513     }
7514
7515   if (bd_id_set == 0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   M (BRIDGE_FLAGS, mp);
7522
7523   mp->bd_id = ntohl (bd_id);
7524   mp->feature_bitmap = ntohl (flags);
7525   mp->is_set = is_set;
7526
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_bd_ip_mac_add_del (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_bd_ip_mac_add_del_t *mp;
7537   u32 bd_id;
7538   u8 is_ipv6 = 0;
7539   u8 is_add = 1;
7540   u8 bd_id_set = 0;
7541   u8 ip_set = 0;
7542   u8 mac_set = 0;
7543   ip4_address_t v4addr;
7544   ip6_address_t v6addr;
7545   u8 macaddr[6];
7546   int ret;
7547
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "bd_id %d", &bd_id))
7553         {
7554           bd_id_set++;
7555         }
7556       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7557         {
7558           ip_set++;
7559         }
7560       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7561         {
7562           ip_set++;
7563           is_ipv6++;
7564         }
7565       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7566         {
7567           mac_set++;
7568         }
7569       else if (unformat (i, "del"))
7570         is_add = 0;
7571       else
7572         break;
7573     }
7574
7575   if (bd_id_set == 0)
7576     {
7577       errmsg ("missing bridge domain");
7578       return -99;
7579     }
7580   else if (ip_set == 0)
7581     {
7582       errmsg ("missing IP address");
7583       return -99;
7584     }
7585   else if (mac_set == 0)
7586     {
7587       errmsg ("missing MAC address");
7588       return -99;
7589     }
7590
7591   M (BD_IP_MAC_ADD_DEL, mp);
7592
7593   mp->bd_id = ntohl (bd_id);
7594   mp->is_ipv6 = is_ipv6;
7595   mp->is_add = is_add;
7596   if (is_ipv6)
7597     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7598   else
7599     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7600   clib_memcpy (mp->mac_address, macaddr, 6);
7601   S (mp);
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_connect (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_connect_t *mp;
7611   u8 mac_address[6];
7612   u8 random_mac = 1;
7613   u8 name_set = 0;
7614   u8 *tap_name;
7615   u8 *tag = 0;
7616   ip4_address_t ip4_address;
7617   u32 ip4_mask_width;
7618   int ip4_address_set = 0;
7619   ip6_address_t ip6_address;
7620   u32 ip6_mask_width;
7621   int ip6_address_set = 0;
7622   int ret;
7623
7624   memset (mac_address, 0, sizeof (mac_address));
7625
7626   /* Parse args required to build the message */
7627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7630         {
7631           random_mac = 0;
7632         }
7633       else if (unformat (i, "random-mac"))
7634         random_mac = 1;
7635       else if (unformat (i, "tapname %s", &tap_name))
7636         name_set = 1;
7637       else if (unformat (i, "tag %s", &tag))
7638         ;
7639       else if (unformat (i, "address %U/%d",
7640                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7641         ip4_address_set = 1;
7642       else if (unformat (i, "address %U/%d",
7643                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7644         ip6_address_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (name_set == 0)
7650     {
7651       errmsg ("missing tap name");
7652       return -99;
7653     }
7654   if (vec_len (tap_name) > 63)
7655     {
7656       errmsg ("tap name too long");
7657       return -99;
7658     }
7659   vec_add1 (tap_name, 0);
7660
7661   if (vec_len (tag) > 63)
7662     {
7663       errmsg ("tag too long");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_CONNECT, mp);
7669
7670   mp->use_random_mac = random_mac;
7671   clib_memcpy (mp->mac_address, mac_address, 6);
7672   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7673   if (tag)
7674     clib_memcpy (mp->tag, tag, vec_len (tag));
7675
7676   if (ip4_address_set)
7677     {
7678       mp->ip4_address_set = 1;
7679       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7680       mp->ip4_mask_width = ip4_mask_width;
7681     }
7682   if (ip6_address_set)
7683     {
7684       mp->ip6_address_set = 1;
7685       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7686       mp->ip6_mask_width = ip6_mask_width;
7687     }
7688
7689   vec_free (tap_name);
7690   vec_free (tag);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_tap_modify (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_tap_modify_t *mp;
7705   u8 mac_address[6];
7706   u8 random_mac = 1;
7707   u8 name_set = 0;
7708   u8 *tap_name;
7709   u32 sw_if_index = ~0;
7710   u8 sw_if_index_set = 0;
7711   int ret;
7712
7713   memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7723         {
7724           random_mac = 0;
7725         }
7726       else if (unformat (i, "random-mac"))
7727         random_mac = 1;
7728       else if (unformat (i, "tapname %s", &tap_name))
7729         name_set = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing vpp interface name");
7737       return -99;
7738     }
7739   if (name_set == 0)
7740     {
7741       errmsg ("missing tap name");
7742       return -99;
7743     }
7744   if (vec_len (tap_name) > 63)
7745     {
7746       errmsg ("tap name too long");
7747     }
7748   vec_add1 (tap_name, 0);
7749
7750   /* Construct the API message */
7751   M (TAP_MODIFY, mp);
7752
7753   mp->use_random_mac = random_mac;
7754   mp->sw_if_index = ntohl (sw_if_index);
7755   clib_memcpy (mp->mac_address, mac_address, 6);
7756   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7757   vec_free (tap_name);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_tap_delete (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_tap_delete_t *mp;
7772   u32 sw_if_index = ~0;
7773   u8 sw_if_index_set = 0;
7774   int ret;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing vpp interface name");
7790       return -99;
7791     }
7792
7793   /* Construct the API message */
7794   M (TAP_DELETE, mp);
7795
7796   mp->sw_if_index = ntohl (sw_if_index);
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply... */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 static int
7807 api_tap_create_v2 (vat_main_t * vam)
7808 {
7809   unformat_input_t *i = vam->input;
7810   vl_api_tap_create_v2_t *mp;
7811   u8 mac_address[6];
7812   u8 random_mac = 1;
7813   u8 name_set = 0;
7814   u8 *tap_name;
7815   u8 *net_ns;
7816   u8 net_ns_set = 0;
7817   int ret;
7818   int rx_ring_sz = 0, tx_ring_sz = 0;
7819
7820   memset (mac_address, 0, sizeof (mac_address));
7821
7822   /* Parse args required to build the message */
7823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7824     {
7825       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7826         {
7827           random_mac = 0;
7828         }
7829       else if (unformat (i, "name %s", &tap_name))
7830         name_set = 1;
7831       else if (unformat (i, "host-ns %s", &net_ns))
7832         net_ns_set = 1;
7833       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7834         ;
7835       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7836         ;
7837       else
7838         break;
7839     }
7840
7841   if (name_set == 0)
7842     {
7843       errmsg ("missing tap name. ");
7844       return -99;
7845     }
7846   if (vec_len (tap_name) > 63)
7847     {
7848       errmsg ("tap name too long. ");
7849       return -99;
7850     }
7851   if (vec_len (net_ns) > 63)
7852     {
7853       errmsg ("host name space too long. ");
7854       return -99;
7855     }
7856   if (!is_pow2 (rx_ring_sz))
7857     {
7858       errmsg ("rx ring size must be power of 2. ");
7859       return -99;
7860     }
7861   if (rx_ring_sz > 32768)
7862     {
7863       errmsg ("rx ring size must be 32768 or lower. ");
7864       return -99;
7865     }
7866   if (!is_pow2 (tx_ring_sz))
7867     {
7868       errmsg ("tx ring size must be power of 2. ");
7869       return -99;
7870     }
7871   if (tx_ring_sz > 32768)
7872     {
7873       errmsg ("tx ring size must be 32768 or lower. ");
7874       return -99;
7875     }
7876
7877   vec_add1 (tap_name, 0);
7878   vec_add1 (net_ns, 0);
7879
7880   /* Construct the API message */
7881   M (TAP_CREATE_V2, mp);
7882
7883   mp->use_random_mac = random_mac;
7884   clib_memcpy (mp->mac_address, mac_address, 6);
7885   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7886   mp->net_ns_set = net_ns_set;
7887   mp->rx_ring_sz = rx_ring_sz;
7888   mp->tx_ring_sz = tx_ring_sz;
7889   if (net_ns)
7890     clib_memcpy (mp->net_ns, net_ns, vec_len (net_ns));
7891
7892   vec_free (tap_name);
7893   vec_free (net_ns);
7894
7895   /* send it... */
7896   S (mp);
7897
7898   /* Wait for a reply... */
7899   W (ret);
7900   return ret;
7901 }
7902
7903 static int
7904 api_tap_delete_v2 (vat_main_t * vam)
7905 {
7906   unformat_input_t *i = vam->input;
7907   vl_api_tap_delete_v2_t *mp;
7908   u32 sw_if_index = ~0;
7909   u8 sw_if_index_set = 0;
7910   int ret;
7911
7912   /* Parse args required to build the message */
7913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7916         sw_if_index_set = 1;
7917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7918         sw_if_index_set = 1;
7919       else
7920         break;
7921     }
7922
7923   if (sw_if_index_set == 0)
7924     {
7925       errmsg ("missing vpp interface name. ");
7926       return -99;
7927     }
7928
7929   /* Construct the API message */
7930   M (TAP_DELETE_V2, mp);
7931
7932   mp->sw_if_index = ntohl (sw_if_index);
7933
7934   /* send it... */
7935   S (mp);
7936
7937   /* Wait for a reply... */
7938   W (ret);
7939   return ret;
7940 }
7941
7942 static int
7943 api_ip_table_add_del (vat_main_t * vam)
7944 {
7945   unformat_input_t *i = vam->input;
7946   vl_api_ip_table_add_del_t *mp;
7947   u32 table_id = ~0;
7948   u8 is_ipv6 = 0;
7949   u8 is_add = 1;
7950   int ret = 0;
7951
7952   /* Parse args required to build the message */
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "ipv6"))
7956         is_ipv6 = 1;
7957       else if (unformat (i, "del"))
7958         is_add = 0;
7959       else if (unformat (i, "add"))
7960         is_add = 1;
7961       else if (unformat (i, "table %d", &table_id))
7962         ;
7963       else
7964         {
7965           clib_warning ("parse error '%U'", format_unformat_error, i);
7966           return -99;
7967         }
7968     }
7969
7970   if (~0 == table_id)
7971     {
7972       errmsg ("missing table-ID");
7973       return -99;
7974     }
7975
7976   /* Construct the API message */
7977   M (IP_TABLE_ADD_DEL, mp);
7978
7979   mp->table_id = ntohl (table_id);
7980   mp->is_ipv6 = is_ipv6;
7981   mp->is_add = is_add;
7982
7983   /* send it... */
7984   S (mp);
7985
7986   /* Wait for a reply... */
7987   W (ret);
7988
7989   return ret;
7990 }
7991
7992 static int
7993 api_ip_add_del_route (vat_main_t * vam)
7994 {
7995   unformat_input_t *i = vam->input;
7996   vl_api_ip_add_del_route_t *mp;
7997   u32 sw_if_index = ~0, vrf_id = 0;
7998   u8 is_ipv6 = 0;
7999   u8 is_local = 0, is_drop = 0;
8000   u8 is_unreach = 0, is_prohibit = 0;
8001   u8 create_vrf_if_needed = 0;
8002   u8 is_add = 1;
8003   u32 next_hop_weight = 1;
8004   u8 is_multipath = 0;
8005   u8 address_set = 0;
8006   u8 address_length_set = 0;
8007   u32 next_hop_table_id = 0;
8008   u32 resolve_attempts = 0;
8009   u32 dst_address_length = 0;
8010   u8 next_hop_set = 0;
8011   ip4_address_t v4_dst_address, v4_next_hop_address;
8012   ip6_address_t v6_dst_address, v6_next_hop_address;
8013   int count = 1;
8014   int j;
8015   f64 before = 0;
8016   u32 random_add_del = 0;
8017   u32 *random_vector = 0;
8018   uword *random_hash;
8019   u32 random_seed = 0xdeaddabe;
8020   u32 classify_table_index = ~0;
8021   u8 is_classify = 0;
8022   u8 resolve_host = 0, resolve_attached = 0;
8023   mpls_label_t *next_hop_out_label_stack = NULL;
8024   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8025   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8026
8027   /* Parse args required to build the message */
8028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8029     {
8030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8031         ;
8032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8033         ;
8034       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8035         {
8036           address_set = 1;
8037           is_ipv6 = 0;
8038         }
8039       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8040         {
8041           address_set = 1;
8042           is_ipv6 = 1;
8043         }
8044       else if (unformat (i, "/%d", &dst_address_length))
8045         {
8046           address_length_set = 1;
8047         }
8048
8049       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8050                                          &v4_next_hop_address))
8051         {
8052           next_hop_set = 1;
8053         }
8054       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8055                                          &v6_next_hop_address))
8056         {
8057           next_hop_set = 1;
8058         }
8059       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8060         ;
8061       else if (unformat (i, "weight %d", &next_hop_weight))
8062         ;
8063       else if (unformat (i, "drop"))
8064         {
8065           is_drop = 1;
8066         }
8067       else if (unformat (i, "null-send-unreach"))
8068         {
8069           is_unreach = 1;
8070         }
8071       else if (unformat (i, "null-send-prohibit"))
8072         {
8073           is_prohibit = 1;
8074         }
8075       else if (unformat (i, "local"))
8076         {
8077           is_local = 1;
8078         }
8079       else if (unformat (i, "classify %d", &classify_table_index))
8080         {
8081           is_classify = 1;
8082         }
8083       else if (unformat (i, "del"))
8084         is_add = 0;
8085       else if (unformat (i, "add"))
8086         is_add = 1;
8087       else if (unformat (i, "resolve-via-host"))
8088         resolve_host = 1;
8089       else if (unformat (i, "resolve-via-attached"))
8090         resolve_attached = 1;
8091       else if (unformat (i, "multipath"))
8092         is_multipath = 1;
8093       else if (unformat (i, "vrf %d", &vrf_id))
8094         ;
8095       else if (unformat (i, "create-vrf"))
8096         create_vrf_if_needed = 1;
8097       else if (unformat (i, "count %d", &count))
8098         ;
8099       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8100         ;
8101       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8102         ;
8103       else if (unformat (i, "out-label %d", &next_hop_out_label))
8104         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8105       else if (unformat (i, "via-label %d", &next_hop_via_label))
8106         ;
8107       else if (unformat (i, "random"))
8108         random_add_del = 1;
8109       else if (unformat (i, "seed %d", &random_seed))
8110         ;
8111       else
8112         {
8113           clib_warning ("parse error '%U'", format_unformat_error, i);
8114           return -99;
8115         }
8116     }
8117
8118   if (!next_hop_set && !is_drop && !is_local &&
8119       !is_classify && !is_unreach && !is_prohibit &&
8120       MPLS_LABEL_INVALID == next_hop_via_label)
8121     {
8122       errmsg
8123         ("next hop / local / drop / unreach / prohibit / classify not set");
8124       return -99;
8125     }
8126
8127   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8128     {
8129       errmsg ("next hop and next-hop via label set");
8130       return -99;
8131     }
8132   if (address_set == 0)
8133     {
8134       errmsg ("missing addresses");
8135       return -99;
8136     }
8137
8138   if (address_length_set == 0)
8139     {
8140       errmsg ("missing address length");
8141       return -99;
8142     }
8143
8144   /* Generate a pile of unique, random routes */
8145   if (random_add_del)
8146     {
8147       u32 this_random_address;
8148       random_hash = hash_create (count, sizeof (uword));
8149
8150       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8151       for (j = 0; j <= count; j++)
8152         {
8153           do
8154             {
8155               this_random_address = random_u32 (&random_seed);
8156               this_random_address =
8157                 clib_host_to_net_u32 (this_random_address);
8158             }
8159           while (hash_get (random_hash, this_random_address));
8160           vec_add1 (random_vector, this_random_address);
8161           hash_set (random_hash, this_random_address, 1);
8162         }
8163       hash_free (random_hash);
8164       v4_dst_address.as_u32 = random_vector[0];
8165     }
8166
8167   if (count > 1)
8168     {
8169       /* Turn on async mode */
8170       vam->async_mode = 1;
8171       vam->async_errors = 0;
8172       before = vat_time_now (vam);
8173     }
8174
8175   for (j = 0; j < count; j++)
8176     {
8177       /* Construct the API message */
8178       M2 (IP_ADD_DEL_ROUTE, mp,
8179           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8180
8181       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8182       mp->table_id = ntohl (vrf_id);
8183       mp->create_vrf_if_needed = create_vrf_if_needed;
8184
8185       mp->is_add = is_add;
8186       mp->is_drop = is_drop;
8187       mp->is_unreach = is_unreach;
8188       mp->is_prohibit = is_prohibit;
8189       mp->is_ipv6 = is_ipv6;
8190       mp->is_local = is_local;
8191       mp->is_classify = is_classify;
8192       mp->is_multipath = is_multipath;
8193       mp->is_resolve_host = resolve_host;
8194       mp->is_resolve_attached = resolve_attached;
8195       mp->next_hop_weight = next_hop_weight;
8196       mp->dst_address_length = dst_address_length;
8197       mp->next_hop_table_id = ntohl (next_hop_table_id);
8198       mp->classify_table_index = ntohl (classify_table_index);
8199       mp->next_hop_via_label = ntohl (next_hop_via_label);
8200       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8201       if (0 != mp->next_hop_n_out_labels)
8202         {
8203           memcpy (mp->next_hop_out_label_stack,
8204                   next_hop_out_label_stack,
8205                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8206           vec_free (next_hop_out_label_stack);
8207         }
8208
8209       if (is_ipv6)
8210         {
8211           clib_memcpy (mp->dst_address, &v6_dst_address,
8212                        sizeof (v6_dst_address));
8213           if (next_hop_set)
8214             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8215                          sizeof (v6_next_hop_address));
8216           increment_v6_address (&v6_dst_address);
8217         }
8218       else
8219         {
8220           clib_memcpy (mp->dst_address, &v4_dst_address,
8221                        sizeof (v4_dst_address));
8222           if (next_hop_set)
8223             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8224                          sizeof (v4_next_hop_address));
8225           if (random_add_del)
8226             v4_dst_address.as_u32 = random_vector[j + 1];
8227           else
8228             increment_v4_address (&v4_dst_address);
8229         }
8230       /* send it... */
8231       S (mp);
8232       /* If we receive SIGTERM, stop now... */
8233       if (vam->do_exit)
8234         break;
8235     }
8236
8237   /* When testing multiple add/del ops, use a control-ping to sync */
8238   if (count > 1)
8239     {
8240       vl_api_control_ping_t *mp_ping;
8241       f64 after;
8242       f64 timeout;
8243
8244       /* Shut off async mode */
8245       vam->async_mode = 0;
8246
8247       MPING (CONTROL_PING, mp_ping);
8248       S (mp_ping);
8249
8250       timeout = vat_time_now (vam) + 1.0;
8251       while (vat_time_now (vam) < timeout)
8252         if (vam->result_ready == 1)
8253           goto out;
8254       vam->retval = -99;
8255
8256     out:
8257       if (vam->retval == -99)
8258         errmsg ("timeout");
8259
8260       if (vam->async_errors > 0)
8261         {
8262           errmsg ("%d asynchronous errors", vam->async_errors);
8263           vam->retval = -98;
8264         }
8265       vam->async_errors = 0;
8266       after = vat_time_now (vam);
8267
8268       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8269       if (j > 0)
8270         count = j;
8271
8272       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8273              count, after - before, count / (after - before));
8274     }
8275   else
8276     {
8277       int ret;
8278
8279       /* Wait for a reply... */
8280       W (ret);
8281       return ret;
8282     }
8283
8284   /* Return the good/bad news */
8285   return (vam->retval);
8286 }
8287
8288 static int
8289 api_ip_mroute_add_del (vat_main_t * vam)
8290 {
8291   unformat_input_t *i = vam->input;
8292   vl_api_ip_mroute_add_del_t *mp;
8293   u32 sw_if_index = ~0, vrf_id = 0;
8294   u8 is_ipv6 = 0;
8295   u8 is_local = 0;
8296   u8 create_vrf_if_needed = 0;
8297   u8 is_add = 1;
8298   u8 address_set = 0;
8299   u32 grp_address_length = 0;
8300   ip4_address_t v4_grp_address, v4_src_address;
8301   ip6_address_t v6_grp_address, v6_src_address;
8302   mfib_itf_flags_t iflags = 0;
8303   mfib_entry_flags_t eflags = 0;
8304   int ret;
8305
8306   /* Parse args required to build the message */
8307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8308     {
8309       if (unformat (i, "sw_if_index %d", &sw_if_index))
8310         ;
8311       else if (unformat (i, "%U %U",
8312                          unformat_ip4_address, &v4_src_address,
8313                          unformat_ip4_address, &v4_grp_address))
8314         {
8315           grp_address_length = 64;
8316           address_set = 1;
8317           is_ipv6 = 0;
8318         }
8319       else if (unformat (i, "%U %U",
8320                          unformat_ip6_address, &v6_src_address,
8321                          unformat_ip6_address, &v6_grp_address))
8322         {
8323           grp_address_length = 256;
8324           address_set = 1;
8325           is_ipv6 = 1;
8326         }
8327       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8328         {
8329           memset (&v4_src_address, 0, sizeof (v4_src_address));
8330           grp_address_length = 32;
8331           address_set = 1;
8332           is_ipv6 = 0;
8333         }
8334       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8335         {
8336           memset (&v6_src_address, 0, sizeof (v6_src_address));
8337           grp_address_length = 128;
8338           address_set = 1;
8339           is_ipv6 = 1;
8340         }
8341       else if (unformat (i, "/%d", &grp_address_length))
8342         ;
8343       else if (unformat (i, "local"))
8344         {
8345           is_local = 1;
8346         }
8347       else if (unformat (i, "del"))
8348         is_add = 0;
8349       else if (unformat (i, "add"))
8350         is_add = 1;
8351       else if (unformat (i, "vrf %d", &vrf_id))
8352         ;
8353       else if (unformat (i, "create-vrf"))
8354         create_vrf_if_needed = 1;
8355       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8356         ;
8357       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8358         ;
8359       else
8360         {
8361           clib_warning ("parse error '%U'", format_unformat_error, i);
8362           return -99;
8363         }
8364     }
8365
8366   if (address_set == 0)
8367     {
8368       errmsg ("missing addresses\n");
8369       return -99;
8370     }
8371
8372   /* Construct the API message */
8373   M (IP_MROUTE_ADD_DEL, mp);
8374
8375   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8376   mp->table_id = ntohl (vrf_id);
8377   mp->create_vrf_if_needed = create_vrf_if_needed;
8378
8379   mp->is_add = is_add;
8380   mp->is_ipv6 = is_ipv6;
8381   mp->is_local = is_local;
8382   mp->itf_flags = ntohl (iflags);
8383   mp->entry_flags = ntohl (eflags);
8384   mp->grp_address_length = grp_address_length;
8385   mp->grp_address_length = ntohs (mp->grp_address_length);
8386
8387   if (is_ipv6)
8388     {
8389       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8390       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8391     }
8392   else
8393     {
8394       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8395       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8396
8397     }
8398
8399   /* send it... */
8400   S (mp);
8401   /* Wait for a reply... */
8402   W (ret);
8403   return ret;
8404 }
8405
8406 static int
8407 api_mpls_table_add_del (vat_main_t * vam)
8408 {
8409   unformat_input_t *i = vam->input;
8410   vl_api_mpls_table_add_del_t *mp;
8411   u32 table_id = ~0;
8412   u8 is_add = 1;
8413   int ret = 0;
8414
8415   /* Parse args required to build the message */
8416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8417     {
8418       if (unformat (i, "table %d", &table_id))
8419         ;
8420       else if (unformat (i, "del"))
8421         is_add = 0;
8422       else if (unformat (i, "add"))
8423         is_add = 1;
8424       else
8425         {
8426           clib_warning ("parse error '%U'", format_unformat_error, i);
8427           return -99;
8428         }
8429     }
8430
8431   if (~0 == table_id)
8432     {
8433       errmsg ("missing table-ID");
8434       return -99;
8435     }
8436
8437   /* Construct the API message */
8438   M (MPLS_TABLE_ADD_DEL, mp);
8439
8440   mp->mt_table_id = ntohl (table_id);
8441   mp->mt_is_add = is_add;
8442
8443   /* send it... */
8444   S (mp);
8445
8446   /* Wait for a reply... */
8447   W (ret);
8448
8449   return ret;
8450 }
8451
8452 static int
8453 api_mpls_route_add_del (vat_main_t * vam)
8454 {
8455   unformat_input_t *i = vam->input;
8456   vl_api_mpls_route_add_del_t *mp;
8457   u32 sw_if_index = ~0, table_id = 0;
8458   u8 create_table_if_needed = 0;
8459   u8 is_add = 1;
8460   u32 next_hop_weight = 1;
8461   u8 is_multipath = 0;
8462   u32 next_hop_table_id = 0;
8463   u8 next_hop_set = 0;
8464   ip4_address_t v4_next_hop_address = {
8465     .as_u32 = 0,
8466   };
8467   ip6_address_t v6_next_hop_address = { {0} };
8468   int count = 1;
8469   int j;
8470   f64 before = 0;
8471   u32 classify_table_index = ~0;
8472   u8 is_classify = 0;
8473   u8 resolve_host = 0, resolve_attached = 0;
8474   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8475   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8476   mpls_label_t *next_hop_out_label_stack = NULL;
8477   mpls_label_t local_label = MPLS_LABEL_INVALID;
8478   u8 is_eos = 0;
8479   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8480
8481   /* Parse args required to build the message */
8482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8483     {
8484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8485         ;
8486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8487         ;
8488       else if (unformat (i, "%d", &local_label))
8489         ;
8490       else if (unformat (i, "eos"))
8491         is_eos = 1;
8492       else if (unformat (i, "non-eos"))
8493         is_eos = 0;
8494       else if (unformat (i, "via %U", unformat_ip4_address,
8495                          &v4_next_hop_address))
8496         {
8497           next_hop_set = 1;
8498           next_hop_proto = DPO_PROTO_IP4;
8499         }
8500       else if (unformat (i, "via %U", unformat_ip6_address,
8501                          &v6_next_hop_address))
8502         {
8503           next_hop_set = 1;
8504           next_hop_proto = DPO_PROTO_IP6;
8505         }
8506       else if (unformat (i, "weight %d", &next_hop_weight))
8507         ;
8508       else if (unformat (i, "create-table"))
8509         create_table_if_needed = 1;
8510       else if (unformat (i, "classify %d", &classify_table_index))
8511         {
8512           is_classify = 1;
8513         }
8514       else if (unformat (i, "del"))
8515         is_add = 0;
8516       else if (unformat (i, "add"))
8517         is_add = 1;
8518       else if (unformat (i, "resolve-via-host"))
8519         resolve_host = 1;
8520       else if (unformat (i, "resolve-via-attached"))
8521         resolve_attached = 1;
8522       else if (unformat (i, "multipath"))
8523         is_multipath = 1;
8524       else if (unformat (i, "count %d", &count))
8525         ;
8526       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8527         {
8528           next_hop_set = 1;
8529           next_hop_proto = DPO_PROTO_IP4;
8530         }
8531       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8532         {
8533           next_hop_set = 1;
8534           next_hop_proto = DPO_PROTO_IP6;
8535         }
8536       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8537         ;
8538       else if (unformat (i, "via-label %d", &next_hop_via_label))
8539         ;
8540       else if (unformat (i, "out-label %d", &next_hop_out_label))
8541         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8542       else
8543         {
8544           clib_warning ("parse error '%U'", format_unformat_error, i);
8545           return -99;
8546         }
8547     }
8548
8549   if (!next_hop_set && !is_classify)
8550     {
8551       errmsg ("next hop / classify not set");
8552       return -99;
8553     }
8554
8555   if (MPLS_LABEL_INVALID == local_label)
8556     {
8557       errmsg ("missing label");
8558       return -99;
8559     }
8560
8561   if (count > 1)
8562     {
8563       /* Turn on async mode */
8564       vam->async_mode = 1;
8565       vam->async_errors = 0;
8566       before = vat_time_now (vam);
8567     }
8568
8569   for (j = 0; j < count; j++)
8570     {
8571       /* Construct the API message */
8572       M2 (MPLS_ROUTE_ADD_DEL, mp,
8573           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8574
8575       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8576       mp->mr_table_id = ntohl (table_id);
8577       mp->mr_create_table_if_needed = create_table_if_needed;
8578
8579       mp->mr_is_add = is_add;
8580       mp->mr_next_hop_proto = next_hop_proto;
8581       mp->mr_is_classify = is_classify;
8582       mp->mr_is_multipath = is_multipath;
8583       mp->mr_is_resolve_host = resolve_host;
8584       mp->mr_is_resolve_attached = resolve_attached;
8585       mp->mr_next_hop_weight = next_hop_weight;
8586       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8587       mp->mr_classify_table_index = ntohl (classify_table_index);
8588       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8589       mp->mr_label = ntohl (local_label);
8590       mp->mr_eos = is_eos;
8591
8592       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8593       if (0 != mp->mr_next_hop_n_out_labels)
8594         {
8595           memcpy (mp->mr_next_hop_out_label_stack,
8596                   next_hop_out_label_stack,
8597                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8598           vec_free (next_hop_out_label_stack);
8599         }
8600
8601       if (next_hop_set)
8602         {
8603           if (DPO_PROTO_IP4 == next_hop_proto)
8604             {
8605               clib_memcpy (mp->mr_next_hop,
8606                            &v4_next_hop_address,
8607                            sizeof (v4_next_hop_address));
8608             }
8609           else if (DPO_PROTO_IP6 == next_hop_proto)
8610
8611             {
8612               clib_memcpy (mp->mr_next_hop,
8613                            &v6_next_hop_address,
8614                            sizeof (v6_next_hop_address));
8615             }
8616         }
8617       local_label++;
8618
8619       /* send it... */
8620       S (mp);
8621       /* If we receive SIGTERM, stop now... */
8622       if (vam->do_exit)
8623         break;
8624     }
8625
8626   /* When testing multiple add/del ops, use a control-ping to sync */
8627   if (count > 1)
8628     {
8629       vl_api_control_ping_t *mp_ping;
8630       f64 after;
8631       f64 timeout;
8632
8633       /* Shut off async mode */
8634       vam->async_mode = 0;
8635
8636       MPING (CONTROL_PING, mp_ping);
8637       S (mp_ping);
8638
8639       timeout = vat_time_now (vam) + 1.0;
8640       while (vat_time_now (vam) < timeout)
8641         if (vam->result_ready == 1)
8642           goto out;
8643       vam->retval = -99;
8644
8645     out:
8646       if (vam->retval == -99)
8647         errmsg ("timeout");
8648
8649       if (vam->async_errors > 0)
8650         {
8651           errmsg ("%d asynchronous errors", vam->async_errors);
8652           vam->retval = -98;
8653         }
8654       vam->async_errors = 0;
8655       after = vat_time_now (vam);
8656
8657       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8658       if (j > 0)
8659         count = j;
8660
8661       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8662              count, after - before, count / (after - before));
8663     }
8664   else
8665     {
8666       int ret;
8667
8668       /* Wait for a reply... */
8669       W (ret);
8670       return ret;
8671     }
8672
8673   /* Return the good/bad news */
8674   return (vam->retval);
8675 }
8676
8677 static int
8678 api_mpls_ip_bind_unbind (vat_main_t * vam)
8679 {
8680   unformat_input_t *i = vam->input;
8681   vl_api_mpls_ip_bind_unbind_t *mp;
8682   u32 ip_table_id = 0;
8683   u8 create_table_if_needed = 0;
8684   u8 is_bind = 1;
8685   u8 is_ip4 = 1;
8686   ip4_address_t v4_address;
8687   ip6_address_t v6_address;
8688   u32 address_length;
8689   u8 address_set = 0;
8690   mpls_label_t local_label = MPLS_LABEL_INVALID;
8691   int ret;
8692
8693   /* Parse args required to build the message */
8694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8695     {
8696       if (unformat (i, "%U/%d", unformat_ip4_address,
8697                     &v4_address, &address_length))
8698         {
8699           is_ip4 = 1;
8700           address_set = 1;
8701         }
8702       else if (unformat (i, "%U/%d", unformat_ip6_address,
8703                          &v6_address, &address_length))
8704         {
8705           is_ip4 = 0;
8706           address_set = 1;
8707         }
8708       else if (unformat (i, "%d", &local_label))
8709         ;
8710       else if (unformat (i, "create-table"))
8711         create_table_if_needed = 1;
8712       else if (unformat (i, "table-id %d", &ip_table_id))
8713         ;
8714       else if (unformat (i, "unbind"))
8715         is_bind = 0;
8716       else if (unformat (i, "bind"))
8717         is_bind = 1;
8718       else
8719         {
8720           clib_warning ("parse error '%U'", format_unformat_error, i);
8721           return -99;
8722         }
8723     }
8724
8725   if (!address_set)
8726     {
8727       errmsg ("IP addres not set");
8728       return -99;
8729     }
8730
8731   if (MPLS_LABEL_INVALID == local_label)
8732     {
8733       errmsg ("missing label");
8734       return -99;
8735     }
8736
8737   /* Construct the API message */
8738   M (MPLS_IP_BIND_UNBIND, mp);
8739
8740   mp->mb_create_table_if_needed = create_table_if_needed;
8741   mp->mb_is_bind = is_bind;
8742   mp->mb_is_ip4 = is_ip4;
8743   mp->mb_ip_table_id = ntohl (ip_table_id);
8744   mp->mb_mpls_table_id = 0;
8745   mp->mb_label = ntohl (local_label);
8746   mp->mb_address_length = address_length;
8747
8748   if (is_ip4)
8749     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8750   else
8751     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8752
8753   /* send it... */
8754   S (mp);
8755
8756   /* Wait for a reply... */
8757   W (ret);
8758   return ret;
8759 }
8760
8761 static int
8762 api_bier_table_add_del (vat_main_t * vam)
8763 {
8764   unformat_input_t *i = vam->input;
8765   vl_api_bier_table_add_del_t *mp;
8766   u8 is_add = 1;
8767   u32 set = 0, sub_domain = 0, hdr_len = 3;
8768   mpls_label_t local_label = MPLS_LABEL_INVALID;
8769   int ret;
8770
8771   /* Parse args required to build the message */
8772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (i, "sub-domain %d", &sub_domain))
8775         ;
8776       else if (unformat (i, "set %d", &set))
8777         ;
8778       else if (unformat (i, "label %d", &local_label))
8779         ;
8780       else if (unformat (i, "hdr-len %d", &hdr_len))
8781         ;
8782       else if (unformat (i, "add"))
8783         is_add = 1;
8784       else if (unformat (i, "del"))
8785         is_add = 0;
8786       else
8787         {
8788           clib_warning ("parse error '%U'", format_unformat_error, i);
8789           return -99;
8790         }
8791     }
8792
8793   if (MPLS_LABEL_INVALID == local_label)
8794     {
8795       errmsg ("missing label\n");
8796       return -99;
8797     }
8798
8799   /* Construct the API message */
8800   M (BIER_TABLE_ADD_DEL, mp);
8801
8802   mp->bt_is_add = is_add;
8803   mp->bt_label = ntohl (local_label);
8804   mp->bt_tbl_id.bt_set = set;
8805   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8806   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8807
8808   /* send it... */
8809   S (mp);
8810
8811   /* Wait for a reply... */
8812   W (ret);
8813
8814   return (ret);
8815 }
8816
8817 static int
8818 api_bier_route_add_del (vat_main_t * vam)
8819 {
8820   unformat_input_t *i = vam->input;
8821   vl_api_bier_route_add_del_t *mp;
8822   u8 is_add = 1;
8823   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8824   ip4_address_t v4_next_hop_address;
8825   ip6_address_t v6_next_hop_address;
8826   u8 next_hop_set = 0;
8827   u8 next_hop_proto_is_ip4 = 1;
8828   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8829   int ret;
8830
8831   /* Parse args required to build the message */
8832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8833     {
8834       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8835         {
8836           next_hop_proto_is_ip4 = 1;
8837           next_hop_set = 1;
8838         }
8839       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8840         {
8841           next_hop_proto_is_ip4 = 0;
8842           next_hop_set = 1;
8843         }
8844       if (unformat (i, "sub-domain %d", &sub_domain))
8845         ;
8846       else if (unformat (i, "set %d", &set))
8847         ;
8848       else if (unformat (i, "hdr-len %d", &hdr_len))
8849         ;
8850       else if (unformat (i, "bp %d", &bp))
8851         ;
8852       else if (unformat (i, "add"))
8853         is_add = 1;
8854       else if (unformat (i, "del"))
8855         is_add = 0;
8856       else if (unformat (i, "out-label %d", &next_hop_out_label))
8857         ;
8858       else
8859         {
8860           clib_warning ("parse error '%U'", format_unformat_error, i);
8861           return -99;
8862         }
8863     }
8864
8865   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8866     {
8867       errmsg ("next hop / label set\n");
8868       return -99;
8869     }
8870   if (0 == bp)
8871     {
8872       errmsg ("bit=position not set\n");
8873       return -99;
8874     }
8875
8876   /* Construct the API message */
8877   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8878
8879   mp->br_is_add = is_add;
8880   mp->br_tbl_id.bt_set = set;
8881   mp->br_tbl_id.bt_sub_domain = sub_domain;
8882   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8883   mp->br_bp = ntohs (bp);
8884   mp->br_n_paths = 1;
8885   mp->br_paths[0].n_labels = 1;
8886   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8887   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8888
8889   if (next_hop_proto_is_ip4)
8890     {
8891       clib_memcpy (mp->br_paths[0].next_hop,
8892                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8893     }
8894   else
8895     {
8896       clib_memcpy (mp->br_paths[0].next_hop,
8897                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8898     }
8899
8900   /* send it... */
8901   S (mp);
8902
8903   /* Wait for a reply... */
8904   W (ret);
8905
8906   return (ret);
8907 }
8908
8909 static int
8910 api_proxy_arp_add_del (vat_main_t * vam)
8911 {
8912   unformat_input_t *i = vam->input;
8913   vl_api_proxy_arp_add_del_t *mp;
8914   u32 vrf_id = 0;
8915   u8 is_add = 1;
8916   ip4_address_t lo, hi;
8917   u8 range_set = 0;
8918   int ret;
8919
8920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8921     {
8922       if (unformat (i, "vrf %d", &vrf_id))
8923         ;
8924       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8925                          unformat_ip4_address, &hi))
8926         range_set = 1;
8927       else if (unformat (i, "del"))
8928         is_add = 0;
8929       else
8930         {
8931           clib_warning ("parse error '%U'", format_unformat_error, i);
8932           return -99;
8933         }
8934     }
8935
8936   if (range_set == 0)
8937     {
8938       errmsg ("address range not set");
8939       return -99;
8940     }
8941
8942   M (PROXY_ARP_ADD_DEL, mp);
8943
8944   mp->vrf_id = ntohl (vrf_id);
8945   mp->is_add = is_add;
8946   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8947   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8948
8949   S (mp);
8950   W (ret);
8951   return ret;
8952 }
8953
8954 static int
8955 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8956 {
8957   unformat_input_t *i = vam->input;
8958   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8959   u32 sw_if_index;
8960   u8 enable = 1;
8961   u8 sw_if_index_set = 0;
8962   int ret;
8963
8964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8965     {
8966       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8969         sw_if_index_set = 1;
8970       else if (unformat (i, "enable"))
8971         enable = 1;
8972       else if (unformat (i, "disable"))
8973         enable = 0;
8974       else
8975         {
8976           clib_warning ("parse error '%U'", format_unformat_error, i);
8977           return -99;
8978         }
8979     }
8980
8981   if (sw_if_index_set == 0)
8982     {
8983       errmsg ("missing interface name or sw_if_index");
8984       return -99;
8985     }
8986
8987   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8988
8989   mp->sw_if_index = ntohl (sw_if_index);
8990   mp->enable_disable = enable;
8991
8992   S (mp);
8993   W (ret);
8994   return ret;
8995 }
8996
8997 static int
8998 api_mpls_tunnel_add_del (vat_main_t * vam)
8999 {
9000   unformat_input_t *i = vam->input;
9001   vl_api_mpls_tunnel_add_del_t *mp;
9002
9003   u8 is_add = 1;
9004   u8 l2_only = 0;
9005   u32 sw_if_index = ~0;
9006   u32 next_hop_sw_if_index = ~0;
9007   u32 next_hop_proto_is_ip4 = 1;
9008
9009   u32 next_hop_table_id = 0;
9010   ip4_address_t v4_next_hop_address = {
9011     .as_u32 = 0,
9012   };
9013   ip6_address_t v6_next_hop_address = { {0} };
9014   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9015   int ret;
9016
9017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9018     {
9019       if (unformat (i, "add"))
9020         is_add = 1;
9021       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9022         is_add = 0;
9023       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9024         ;
9025       else if (unformat (i, "via %U",
9026                          unformat_ip4_address, &v4_next_hop_address))
9027         {
9028           next_hop_proto_is_ip4 = 1;
9029         }
9030       else if (unformat (i, "via %U",
9031                          unformat_ip6_address, &v6_next_hop_address))
9032         {
9033           next_hop_proto_is_ip4 = 0;
9034         }
9035       else if (unformat (i, "l2-only"))
9036         l2_only = 1;
9037       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9038         ;
9039       else if (unformat (i, "out-label %d", &next_hop_out_label))
9040         vec_add1 (labels, ntohl (next_hop_out_label));
9041       else
9042         {
9043           clib_warning ("parse error '%U'", format_unformat_error, i);
9044           return -99;
9045         }
9046     }
9047
9048   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9049
9050   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9051   mp->mt_sw_if_index = ntohl (sw_if_index);
9052   mp->mt_is_add = is_add;
9053   mp->mt_l2_only = l2_only;
9054   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9055   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9056
9057   mp->mt_next_hop_n_out_labels = vec_len (labels);
9058
9059   if (0 != mp->mt_next_hop_n_out_labels)
9060     {
9061       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9062                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9063       vec_free (labels);
9064     }
9065
9066   if (next_hop_proto_is_ip4)
9067     {
9068       clib_memcpy (mp->mt_next_hop,
9069                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9070     }
9071   else
9072     {
9073       clib_memcpy (mp->mt_next_hop,
9074                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9075     }
9076
9077   S (mp);
9078   W (ret);
9079   return ret;
9080 }
9081
9082 static int
9083 api_sw_interface_set_unnumbered (vat_main_t * vam)
9084 {
9085   unformat_input_t *i = vam->input;
9086   vl_api_sw_interface_set_unnumbered_t *mp;
9087   u32 sw_if_index;
9088   u32 unnum_sw_index = ~0;
9089   u8 is_add = 1;
9090   u8 sw_if_index_set = 0;
9091   int ret;
9092
9093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9094     {
9095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9098         sw_if_index_set = 1;
9099       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9100         ;
9101       else if (unformat (i, "del"))
9102         is_add = 0;
9103       else
9104         {
9105           clib_warning ("parse error '%U'", format_unformat_error, i);
9106           return -99;
9107         }
9108     }
9109
9110   if (sw_if_index_set == 0)
9111     {
9112       errmsg ("missing interface name or sw_if_index");
9113       return -99;
9114     }
9115
9116   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9117
9118   mp->sw_if_index = ntohl (sw_if_index);
9119   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9120   mp->is_add = is_add;
9121
9122   S (mp);
9123   W (ret);
9124   return ret;
9125 }
9126
9127 static int
9128 api_ip_neighbor_add_del (vat_main_t * vam)
9129 {
9130   unformat_input_t *i = vam->input;
9131   vl_api_ip_neighbor_add_del_t *mp;
9132   u32 sw_if_index;
9133   u8 sw_if_index_set = 0;
9134   u8 is_add = 1;
9135   u8 is_static = 0;
9136   u8 is_no_fib_entry = 0;
9137   u8 mac_address[6];
9138   u8 mac_set = 0;
9139   u8 v4_address_set = 0;
9140   u8 v6_address_set = 0;
9141   ip4_address_t v4address;
9142   ip6_address_t v6address;
9143   int ret;
9144
9145   memset (mac_address, 0, sizeof (mac_address));
9146
9147   /* Parse args required to build the message */
9148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9149     {
9150       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9151         {
9152           mac_set = 1;
9153         }
9154       else if (unformat (i, "del"))
9155         is_add = 0;
9156       else
9157         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9160         sw_if_index_set = 1;
9161       else if (unformat (i, "is_static"))
9162         is_static = 1;
9163       else if (unformat (i, "no-fib-entry"))
9164         is_no_fib_entry = 1;
9165       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9166         v4_address_set = 1;
9167       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9168         v6_address_set = 1;
9169       else
9170         {
9171           clib_warning ("parse error '%U'", format_unformat_error, i);
9172           return -99;
9173         }
9174     }
9175
9176   if (sw_if_index_set == 0)
9177     {
9178       errmsg ("missing interface name or sw_if_index");
9179       return -99;
9180     }
9181   if (v4_address_set && v6_address_set)
9182     {
9183       errmsg ("both v4 and v6 addresses set");
9184       return -99;
9185     }
9186   if (!v4_address_set && !v6_address_set)
9187     {
9188       errmsg ("no address set");
9189       return -99;
9190     }
9191
9192   /* Construct the API message */
9193   M (IP_NEIGHBOR_ADD_DEL, mp);
9194
9195   mp->sw_if_index = ntohl (sw_if_index);
9196   mp->is_add = is_add;
9197   mp->is_static = is_static;
9198   mp->is_no_adj_fib = is_no_fib_entry;
9199   if (mac_set)
9200     clib_memcpy (mp->mac_address, mac_address, 6);
9201   if (v6_address_set)
9202     {
9203       mp->is_ipv6 = 1;
9204       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9205     }
9206   else
9207     {
9208       /* mp->is_ipv6 = 0; via memset in M macro above */
9209       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9210     }
9211
9212   /* send it... */
9213   S (mp);
9214
9215   /* Wait for a reply, return good/bad news  */
9216   W (ret);
9217   return ret;
9218 }
9219
9220 static int
9221 api_create_vlan_subif (vat_main_t * vam)
9222 {
9223   unformat_input_t *i = vam->input;
9224   vl_api_create_vlan_subif_t *mp;
9225   u32 sw_if_index;
9226   u8 sw_if_index_set = 0;
9227   u32 vlan_id;
9228   u8 vlan_id_set = 0;
9229   int ret;
9230
9231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9232     {
9233       if (unformat (i, "sw_if_index %d", &sw_if_index))
9234         sw_if_index_set = 1;
9235       else
9236         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9237         sw_if_index_set = 1;
9238       else if (unformat (i, "vlan %d", &vlan_id))
9239         vlan_id_set = 1;
9240       else
9241         {
9242           clib_warning ("parse error '%U'", format_unformat_error, i);
9243           return -99;
9244         }
9245     }
9246
9247   if (sw_if_index_set == 0)
9248     {
9249       errmsg ("missing interface name or sw_if_index");
9250       return -99;
9251     }
9252
9253   if (vlan_id_set == 0)
9254     {
9255       errmsg ("missing vlan_id");
9256       return -99;
9257     }
9258   M (CREATE_VLAN_SUBIF, mp);
9259
9260   mp->sw_if_index = ntohl (sw_if_index);
9261   mp->vlan_id = ntohl (vlan_id);
9262
9263   S (mp);
9264   W (ret);
9265   return ret;
9266 }
9267
9268 #define foreach_create_subif_bit                \
9269 _(no_tags)                                      \
9270 _(one_tag)                                      \
9271 _(two_tags)                                     \
9272 _(dot1ad)                                       \
9273 _(exact_match)                                  \
9274 _(default_sub)                                  \
9275 _(outer_vlan_id_any)                            \
9276 _(inner_vlan_id_any)
9277
9278 static int
9279 api_create_subif (vat_main_t * vam)
9280 {
9281   unformat_input_t *i = vam->input;
9282   vl_api_create_subif_t *mp;
9283   u32 sw_if_index;
9284   u8 sw_if_index_set = 0;
9285   u32 sub_id;
9286   u8 sub_id_set = 0;
9287   u32 no_tags = 0;
9288   u32 one_tag = 0;
9289   u32 two_tags = 0;
9290   u32 dot1ad = 0;
9291   u32 exact_match = 0;
9292   u32 default_sub = 0;
9293   u32 outer_vlan_id_any = 0;
9294   u32 inner_vlan_id_any = 0;
9295   u32 tmp;
9296   u16 outer_vlan_id = 0;
9297   u16 inner_vlan_id = 0;
9298   int ret;
9299
9300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9301     {
9302       if (unformat (i, "sw_if_index %d", &sw_if_index))
9303         sw_if_index_set = 1;
9304       else
9305         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9306         sw_if_index_set = 1;
9307       else if (unformat (i, "sub_id %d", &sub_id))
9308         sub_id_set = 1;
9309       else if (unformat (i, "outer_vlan_id %d", &tmp))
9310         outer_vlan_id = tmp;
9311       else if (unformat (i, "inner_vlan_id %d", &tmp))
9312         inner_vlan_id = tmp;
9313
9314 #define _(a) else if (unformat (i, #a)) a = 1 ;
9315       foreach_create_subif_bit
9316 #undef _
9317         else
9318         {
9319           clib_warning ("parse error '%U'", format_unformat_error, i);
9320           return -99;
9321         }
9322     }
9323
9324   if (sw_if_index_set == 0)
9325     {
9326       errmsg ("missing interface name or sw_if_index");
9327       return -99;
9328     }
9329
9330   if (sub_id_set == 0)
9331     {
9332       errmsg ("missing sub_id");
9333       return -99;
9334     }
9335   M (CREATE_SUBIF, mp);
9336
9337   mp->sw_if_index = ntohl (sw_if_index);
9338   mp->sub_id = ntohl (sub_id);
9339
9340 #define _(a) mp->a = a;
9341   foreach_create_subif_bit;
9342 #undef _
9343
9344   mp->outer_vlan_id = ntohs (outer_vlan_id);
9345   mp->inner_vlan_id = ntohs (inner_vlan_id);
9346
9347   S (mp);
9348   W (ret);
9349   return ret;
9350 }
9351
9352 static int
9353 api_oam_add_del (vat_main_t * vam)
9354 {
9355   unformat_input_t *i = vam->input;
9356   vl_api_oam_add_del_t *mp;
9357   u32 vrf_id = 0;
9358   u8 is_add = 1;
9359   ip4_address_t src, dst;
9360   u8 src_set = 0;
9361   u8 dst_set = 0;
9362   int ret;
9363
9364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9365     {
9366       if (unformat (i, "vrf %d", &vrf_id))
9367         ;
9368       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9369         src_set = 1;
9370       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9371         dst_set = 1;
9372       else if (unformat (i, "del"))
9373         is_add = 0;
9374       else
9375         {
9376           clib_warning ("parse error '%U'", format_unformat_error, i);
9377           return -99;
9378         }
9379     }
9380
9381   if (src_set == 0)
9382     {
9383       errmsg ("missing src addr");
9384       return -99;
9385     }
9386
9387   if (dst_set == 0)
9388     {
9389       errmsg ("missing dst addr");
9390       return -99;
9391     }
9392
9393   M (OAM_ADD_DEL, mp);
9394
9395   mp->vrf_id = ntohl (vrf_id);
9396   mp->is_add = is_add;
9397   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9398   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9399
9400   S (mp);
9401   W (ret);
9402   return ret;
9403 }
9404
9405 static int
9406 api_reset_fib (vat_main_t * vam)
9407 {
9408   unformat_input_t *i = vam->input;
9409   vl_api_reset_fib_t *mp;
9410   u32 vrf_id = 0;
9411   u8 is_ipv6 = 0;
9412   u8 vrf_id_set = 0;
9413
9414   int ret;
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "vrf %d", &vrf_id))
9418         vrf_id_set = 1;
9419       else if (unformat (i, "ipv6"))
9420         is_ipv6 = 1;
9421       else
9422         {
9423           clib_warning ("parse error '%U'", format_unformat_error, i);
9424           return -99;
9425         }
9426     }
9427
9428   if (vrf_id_set == 0)
9429     {
9430       errmsg ("missing vrf id");
9431       return -99;
9432     }
9433
9434   M (RESET_FIB, mp);
9435
9436   mp->vrf_id = ntohl (vrf_id);
9437   mp->is_ipv6 = is_ipv6;
9438
9439   S (mp);
9440   W (ret);
9441   return ret;
9442 }
9443
9444 static int
9445 api_dhcp_proxy_config (vat_main_t * vam)
9446 {
9447   unformat_input_t *i = vam->input;
9448   vl_api_dhcp_proxy_config_t *mp;
9449   u32 rx_vrf_id = 0;
9450   u32 server_vrf_id = 0;
9451   u8 is_add = 1;
9452   u8 v4_address_set = 0;
9453   u8 v6_address_set = 0;
9454   ip4_address_t v4address;
9455   ip6_address_t v6address;
9456   u8 v4_src_address_set = 0;
9457   u8 v6_src_address_set = 0;
9458   ip4_address_t v4srcaddress;
9459   ip6_address_t v6srcaddress;
9460   int ret;
9461
9462   /* Parse args required to build the message */
9463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9464     {
9465       if (unformat (i, "del"))
9466         is_add = 0;
9467       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9468         ;
9469       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9470         ;
9471       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9472         v4_address_set = 1;
9473       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9474         v6_address_set = 1;
9475       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9476         v4_src_address_set = 1;
9477       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9478         v6_src_address_set = 1;
9479       else
9480         break;
9481     }
9482
9483   if (v4_address_set && v6_address_set)
9484     {
9485       errmsg ("both v4 and v6 server addresses set");
9486       return -99;
9487     }
9488   if (!v4_address_set && !v6_address_set)
9489     {
9490       errmsg ("no server addresses set");
9491       return -99;
9492     }
9493
9494   if (v4_src_address_set && v6_src_address_set)
9495     {
9496       errmsg ("both v4 and v6  src addresses set");
9497       return -99;
9498     }
9499   if (!v4_src_address_set && !v6_src_address_set)
9500     {
9501       errmsg ("no src addresses set");
9502       return -99;
9503     }
9504
9505   if (!(v4_src_address_set && v4_address_set) &&
9506       !(v6_src_address_set && v6_address_set))
9507     {
9508       errmsg ("no matching server and src addresses set");
9509       return -99;
9510     }
9511
9512   /* Construct the API message */
9513   M (DHCP_PROXY_CONFIG, mp);
9514
9515   mp->is_add = is_add;
9516   mp->rx_vrf_id = ntohl (rx_vrf_id);
9517   mp->server_vrf_id = ntohl (server_vrf_id);
9518   if (v6_address_set)
9519     {
9520       mp->is_ipv6 = 1;
9521       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9522       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9523     }
9524   else
9525     {
9526       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9527       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9528     }
9529
9530   /* send it... */
9531   S (mp);
9532
9533   /* Wait for a reply, return good/bad news  */
9534   W (ret);
9535   return ret;
9536 }
9537
9538 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9539 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9540
9541 static void
9542 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9543 {
9544   vat_main_t *vam = &vat_main;
9545   u32 i, count = mp->count;
9546   vl_api_dhcp_server_t *s;
9547
9548   if (mp->is_ipv6)
9549     print (vam->ofp,
9550            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9551            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9552            ntohl (mp->rx_vrf_id),
9553            format_ip6_address, mp->dhcp_src_address,
9554            mp->vss_type, mp->vss_vpn_ascii_id,
9555            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9556   else
9557     print (vam->ofp,
9558            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9559            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9560            ntohl (mp->rx_vrf_id),
9561            format_ip4_address, mp->dhcp_src_address,
9562            mp->vss_type, mp->vss_vpn_ascii_id,
9563            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9564
9565   for (i = 0; i < count; i++)
9566     {
9567       s = &mp->servers[i];
9568
9569       if (mp->is_ipv6)
9570         print (vam->ofp,
9571                " Server Table-ID %d, Server Address %U",
9572                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9573       else
9574         print (vam->ofp,
9575                " Server Table-ID %d, Server Address %U",
9576                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9577     }
9578 }
9579
9580 static void vl_api_dhcp_proxy_details_t_handler_json
9581   (vl_api_dhcp_proxy_details_t * mp)
9582 {
9583   vat_main_t *vam = &vat_main;
9584   vat_json_node_t *node = NULL;
9585   u32 i, count = mp->count;
9586   struct in_addr ip4;
9587   struct in6_addr ip6;
9588   vl_api_dhcp_server_t *s;
9589
9590   if (VAT_JSON_ARRAY != vam->json_tree.type)
9591     {
9592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9593       vat_json_init_array (&vam->json_tree);
9594     }
9595   node = vat_json_array_add (&vam->json_tree);
9596
9597   vat_json_init_object (node);
9598   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9599   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9600                              sizeof (mp->vss_type));
9601   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9602                                    mp->vss_vpn_ascii_id);
9603   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9604   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9605
9606   if (mp->is_ipv6)
9607     {
9608       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9609       vat_json_object_add_ip6 (node, "src_address", ip6);
9610     }
9611   else
9612     {
9613       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9614       vat_json_object_add_ip4 (node, "src_address", ip4);
9615     }
9616
9617   for (i = 0; i < count; i++)
9618     {
9619       s = &mp->servers[i];
9620
9621       vat_json_object_add_uint (node, "server-table-id",
9622                                 ntohl (s->server_vrf_id));
9623
9624       if (mp->is_ipv6)
9625         {
9626           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9627           vat_json_object_add_ip4 (node, "src_address", ip4);
9628         }
9629       else
9630         {
9631           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9632           vat_json_object_add_ip6 (node, "server_address", ip6);
9633         }
9634     }
9635 }
9636
9637 static int
9638 api_dhcp_proxy_dump (vat_main_t * vam)
9639 {
9640   unformat_input_t *i = vam->input;
9641   vl_api_control_ping_t *mp_ping;
9642   vl_api_dhcp_proxy_dump_t *mp;
9643   u8 is_ipv6 = 0;
9644   int ret;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "ipv6"))
9649         is_ipv6 = 1;
9650       else
9651         {
9652           clib_warning ("parse error '%U'", format_unformat_error, i);
9653           return -99;
9654         }
9655     }
9656
9657   M (DHCP_PROXY_DUMP, mp);
9658
9659   mp->is_ip6 = is_ipv6;
9660   S (mp);
9661
9662   /* Use a control ping for synchronization */
9663   MPING (CONTROL_PING, mp_ping);
9664   S (mp_ping);
9665
9666   W (ret);
9667   return ret;
9668 }
9669
9670 static int
9671 api_dhcp_proxy_set_vss (vat_main_t * vam)
9672 {
9673   unformat_input_t *i = vam->input;
9674   vl_api_dhcp_proxy_set_vss_t *mp;
9675   u8 is_ipv6 = 0;
9676   u8 is_add = 1;
9677   u32 tbl_id = ~0;
9678   u8 vss_type = VSS_TYPE_DEFAULT;
9679   u8 *vpn_ascii_id = 0;
9680   u32 oui = 0;
9681   u32 fib_id = 0;
9682   int ret;
9683
9684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9685     {
9686       if (unformat (i, "tbl_id %d", &tbl_id))
9687         ;
9688       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9689         vss_type = VSS_TYPE_ASCII;
9690       else if (unformat (i, "fib_id %d", &fib_id))
9691         vss_type = VSS_TYPE_VPN_ID;
9692       else if (unformat (i, "oui %d", &oui))
9693         vss_type = VSS_TYPE_VPN_ID;
9694       else if (unformat (i, "ipv6"))
9695         is_ipv6 = 1;
9696       else if (unformat (i, "del"))
9697         is_add = 0;
9698       else
9699         break;
9700     }
9701
9702   if (tbl_id == ~0)
9703     {
9704       errmsg ("missing tbl_id ");
9705       vec_free (vpn_ascii_id);
9706       return -99;
9707     }
9708
9709   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9710     {
9711       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9712       vec_free (vpn_ascii_id);
9713       return -99;
9714     }
9715
9716   M (DHCP_PROXY_SET_VSS, mp);
9717   mp->tbl_id = ntohl (tbl_id);
9718   mp->vss_type = vss_type;
9719   if (vpn_ascii_id)
9720     {
9721       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9722       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9723     }
9724   mp->vpn_index = ntohl (fib_id);
9725   mp->oui = ntohl (oui);
9726   mp->is_ipv6 = is_ipv6;
9727   mp->is_add = is_add;
9728
9729   S (mp);
9730   W (ret);
9731
9732   vec_free (vpn_ascii_id);
9733   return ret;
9734 }
9735
9736 static int
9737 api_dhcp_client_config (vat_main_t * vam)
9738 {
9739   unformat_input_t *i = vam->input;
9740   vl_api_dhcp_client_config_t *mp;
9741   u32 sw_if_index;
9742   u8 sw_if_index_set = 0;
9743   u8 is_add = 1;
9744   u8 *hostname = 0;
9745   u8 disable_event = 0;
9746   int ret;
9747
9748   /* Parse args required to build the message */
9749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9750     {
9751       if (unformat (i, "del"))
9752         is_add = 0;
9753       else
9754         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9755         sw_if_index_set = 1;
9756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9757         sw_if_index_set = 1;
9758       else if (unformat (i, "hostname %s", &hostname))
9759         ;
9760       else if (unformat (i, "disable_event"))
9761         disable_event = 1;
9762       else
9763         break;
9764     }
9765
9766   if (sw_if_index_set == 0)
9767     {
9768       errmsg ("missing interface name or sw_if_index");
9769       return -99;
9770     }
9771
9772   if (vec_len (hostname) > 63)
9773     {
9774       errmsg ("hostname too long");
9775     }
9776   vec_add1 (hostname, 0);
9777
9778   /* Construct the API message */
9779   M (DHCP_CLIENT_CONFIG, mp);
9780
9781   mp->sw_if_index = htonl (sw_if_index);
9782   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9783   vec_free (hostname);
9784   mp->is_add = is_add;
9785   mp->want_dhcp_event = disable_event ? 0 : 1;
9786   mp->pid = htonl (getpid ());
9787
9788   /* send it... */
9789   S (mp);
9790
9791   /* Wait for a reply, return good/bad news  */
9792   W (ret);
9793   return ret;
9794 }
9795
9796 static int
9797 api_set_ip_flow_hash (vat_main_t * vam)
9798 {
9799   unformat_input_t *i = vam->input;
9800   vl_api_set_ip_flow_hash_t *mp;
9801   u32 vrf_id = 0;
9802   u8 is_ipv6 = 0;
9803   u8 vrf_id_set = 0;
9804   u8 src = 0;
9805   u8 dst = 0;
9806   u8 sport = 0;
9807   u8 dport = 0;
9808   u8 proto = 0;
9809   u8 reverse = 0;
9810   int ret;
9811
9812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9813     {
9814       if (unformat (i, "vrf %d", &vrf_id))
9815         vrf_id_set = 1;
9816       else if (unformat (i, "ipv6"))
9817         is_ipv6 = 1;
9818       else if (unformat (i, "src"))
9819         src = 1;
9820       else if (unformat (i, "dst"))
9821         dst = 1;
9822       else if (unformat (i, "sport"))
9823         sport = 1;
9824       else if (unformat (i, "dport"))
9825         dport = 1;
9826       else if (unformat (i, "proto"))
9827         proto = 1;
9828       else if (unformat (i, "reverse"))
9829         reverse = 1;
9830
9831       else
9832         {
9833           clib_warning ("parse error '%U'", format_unformat_error, i);
9834           return -99;
9835         }
9836     }
9837
9838   if (vrf_id_set == 0)
9839     {
9840       errmsg ("missing vrf id");
9841       return -99;
9842     }
9843
9844   M (SET_IP_FLOW_HASH, mp);
9845   mp->src = src;
9846   mp->dst = dst;
9847   mp->sport = sport;
9848   mp->dport = dport;
9849   mp->proto = proto;
9850   mp->reverse = reverse;
9851   mp->vrf_id = ntohl (vrf_id);
9852   mp->is_ipv6 = is_ipv6;
9853
9854   S (mp);
9855   W (ret);
9856   return ret;
9857 }
9858
9859 static int
9860 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9861 {
9862   unformat_input_t *i = vam->input;
9863   vl_api_sw_interface_ip6_enable_disable_t *mp;
9864   u32 sw_if_index;
9865   u8 sw_if_index_set = 0;
9866   u8 enable = 0;
9867   int ret;
9868
9869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9870     {
9871       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9874         sw_if_index_set = 1;
9875       else if (unformat (i, "enable"))
9876         enable = 1;
9877       else if (unformat (i, "disable"))
9878         enable = 0;
9879       else
9880         {
9881           clib_warning ("parse error '%U'", format_unformat_error, i);
9882           return -99;
9883         }
9884     }
9885
9886   if (sw_if_index_set == 0)
9887     {
9888       errmsg ("missing interface name or sw_if_index");
9889       return -99;
9890     }
9891
9892   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9893
9894   mp->sw_if_index = ntohl (sw_if_index);
9895   mp->enable = enable;
9896
9897   S (mp);
9898   W (ret);
9899   return ret;
9900 }
9901
9902 static int
9903 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9904 {
9905   unformat_input_t *i = vam->input;
9906   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9907   u32 sw_if_index;
9908   u8 sw_if_index_set = 0;
9909   u8 v6_address_set = 0;
9910   ip6_address_t v6address;
9911   int ret;
9912
9913   /* Parse args required to build the message */
9914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9915     {
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, "sw_if_index %d", &sw_if_index))
9919         sw_if_index_set = 1;
9920       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9921         v6_address_set = 1;
9922       else
9923         break;
9924     }
9925
9926   if (sw_if_index_set == 0)
9927     {
9928       errmsg ("missing interface name or sw_if_index");
9929       return -99;
9930     }
9931   if (!v6_address_set)
9932     {
9933       errmsg ("no address set");
9934       return -99;
9935     }
9936
9937   /* Construct the API message */
9938   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9939
9940   mp->sw_if_index = ntohl (sw_if_index);
9941   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9942
9943   /* send it... */
9944   S (mp);
9945
9946   /* Wait for a reply, return good/bad news  */
9947   W (ret);
9948   return ret;
9949 }
9950
9951 static int
9952 api_ip6nd_proxy_add_del (vat_main_t * vam)
9953 {
9954   unformat_input_t *i = vam->input;
9955   vl_api_ip6nd_proxy_add_del_t *mp;
9956   u32 sw_if_index = ~0;
9957   u8 v6_address_set = 0;
9958   ip6_address_t v6address;
9959   u8 is_del = 0;
9960   int ret;
9961
9962   /* Parse args required to build the message */
9963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9966         ;
9967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9968         ;
9969       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9970         v6_address_set = 1;
9971       if (unformat (i, "del"))
9972         is_del = 1;
9973       else
9974         {
9975           clib_warning ("parse error '%U'", format_unformat_error, i);
9976           return -99;
9977         }
9978     }
9979
9980   if (sw_if_index == ~0)
9981     {
9982       errmsg ("missing interface name or sw_if_index");
9983       return -99;
9984     }
9985   if (!v6_address_set)
9986     {
9987       errmsg ("no address set");
9988       return -99;
9989     }
9990
9991   /* Construct the API message */
9992   M (IP6ND_PROXY_ADD_DEL, mp);
9993
9994   mp->is_del = is_del;
9995   mp->sw_if_index = ntohl (sw_if_index);
9996   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9997
9998   /* send it... */
9999   S (mp);
10000
10001   /* Wait for a reply, return good/bad news  */
10002   W (ret);
10003   return ret;
10004 }
10005
10006 static int
10007 api_ip6nd_proxy_dump (vat_main_t * vam)
10008 {
10009   vl_api_ip6nd_proxy_dump_t *mp;
10010   vl_api_control_ping_t *mp_ping;
10011   int ret;
10012
10013   M (IP6ND_PROXY_DUMP, mp);
10014
10015   S (mp);
10016
10017   /* Use a control ping for synchronization */
10018   MPING (CONTROL_PING, mp_ping);
10019   S (mp_ping);
10020
10021   W (ret);
10022   return ret;
10023 }
10024
10025 static void vl_api_ip6nd_proxy_details_t_handler
10026   (vl_api_ip6nd_proxy_details_t * mp)
10027 {
10028   vat_main_t *vam = &vat_main;
10029
10030   print (vam->ofp, "host %U sw_if_index %d",
10031          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10032 }
10033
10034 static void vl_api_ip6nd_proxy_details_t_handler_json
10035   (vl_api_ip6nd_proxy_details_t * mp)
10036 {
10037   vat_main_t *vam = &vat_main;
10038   struct in6_addr ip6;
10039   vat_json_node_t *node = NULL;
10040
10041   if (VAT_JSON_ARRAY != vam->json_tree.type)
10042     {
10043       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10044       vat_json_init_array (&vam->json_tree);
10045     }
10046   node = vat_json_array_add (&vam->json_tree);
10047
10048   vat_json_init_object (node);
10049   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10050
10051   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10052   vat_json_object_add_ip6 (node, "host", ip6);
10053 }
10054
10055 static int
10056 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10057 {
10058   unformat_input_t *i = vam->input;
10059   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10060   u32 sw_if_index;
10061   u8 sw_if_index_set = 0;
10062   u32 address_length = 0;
10063   u8 v6_address_set = 0;
10064   ip6_address_t v6address;
10065   u8 use_default = 0;
10066   u8 no_advertise = 0;
10067   u8 off_link = 0;
10068   u8 no_autoconfig = 0;
10069   u8 no_onlink = 0;
10070   u8 is_no = 0;
10071   u32 val_lifetime = 0;
10072   u32 pref_lifetime = 0;
10073   int ret;
10074
10075   /* Parse args required to build the message */
10076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10077     {
10078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10079         sw_if_index_set = 1;
10080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10081         sw_if_index_set = 1;
10082       else if (unformat (i, "%U/%d",
10083                          unformat_ip6_address, &v6address, &address_length))
10084         v6_address_set = 1;
10085       else if (unformat (i, "val_life %d", &val_lifetime))
10086         ;
10087       else if (unformat (i, "pref_life %d", &pref_lifetime))
10088         ;
10089       else if (unformat (i, "def"))
10090         use_default = 1;
10091       else if (unformat (i, "noadv"))
10092         no_advertise = 1;
10093       else if (unformat (i, "offl"))
10094         off_link = 1;
10095       else if (unformat (i, "noauto"))
10096         no_autoconfig = 1;
10097       else if (unformat (i, "nolink"))
10098         no_onlink = 1;
10099       else if (unformat (i, "isno"))
10100         is_no = 1;
10101       else
10102         {
10103           clib_warning ("parse error '%U'", format_unformat_error, i);
10104           return -99;
10105         }
10106     }
10107
10108   if (sw_if_index_set == 0)
10109     {
10110       errmsg ("missing interface name or sw_if_index");
10111       return -99;
10112     }
10113   if (!v6_address_set)
10114     {
10115       errmsg ("no address set");
10116       return -99;
10117     }
10118
10119   /* Construct the API message */
10120   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10121
10122   mp->sw_if_index = ntohl (sw_if_index);
10123   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10124   mp->address_length = address_length;
10125   mp->use_default = use_default;
10126   mp->no_advertise = no_advertise;
10127   mp->off_link = off_link;
10128   mp->no_autoconfig = no_autoconfig;
10129   mp->no_onlink = no_onlink;
10130   mp->is_no = is_no;
10131   mp->val_lifetime = ntohl (val_lifetime);
10132   mp->pref_lifetime = ntohl (pref_lifetime);
10133
10134   /* send it... */
10135   S (mp);
10136
10137   /* Wait for a reply, return good/bad news  */
10138   W (ret);
10139   return ret;
10140 }
10141
10142 static int
10143 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10144 {
10145   unformat_input_t *i = vam->input;
10146   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10147   u32 sw_if_index;
10148   u8 sw_if_index_set = 0;
10149   u8 suppress = 0;
10150   u8 managed = 0;
10151   u8 other = 0;
10152   u8 ll_option = 0;
10153   u8 send_unicast = 0;
10154   u8 cease = 0;
10155   u8 is_no = 0;
10156   u8 default_router = 0;
10157   u32 max_interval = 0;
10158   u32 min_interval = 0;
10159   u32 lifetime = 0;
10160   u32 initial_count = 0;
10161   u32 initial_interval = 0;
10162   int ret;
10163
10164
10165   /* Parse args required to build the message */
10166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10167     {
10168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10169         sw_if_index_set = 1;
10170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10171         sw_if_index_set = 1;
10172       else if (unformat (i, "maxint %d", &max_interval))
10173         ;
10174       else if (unformat (i, "minint %d", &min_interval))
10175         ;
10176       else if (unformat (i, "life %d", &lifetime))
10177         ;
10178       else if (unformat (i, "count %d", &initial_count))
10179         ;
10180       else if (unformat (i, "interval %d", &initial_interval))
10181         ;
10182       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10183         suppress = 1;
10184       else if (unformat (i, "managed"))
10185         managed = 1;
10186       else if (unformat (i, "other"))
10187         other = 1;
10188       else if (unformat (i, "ll"))
10189         ll_option = 1;
10190       else if (unformat (i, "send"))
10191         send_unicast = 1;
10192       else if (unformat (i, "cease"))
10193         cease = 1;
10194       else if (unformat (i, "isno"))
10195         is_no = 1;
10196       else if (unformat (i, "def"))
10197         default_router = 1;
10198       else
10199         {
10200           clib_warning ("parse error '%U'", format_unformat_error, i);
10201           return -99;
10202         }
10203     }
10204
10205   if (sw_if_index_set == 0)
10206     {
10207       errmsg ("missing interface name or sw_if_index");
10208       return -99;
10209     }
10210
10211   /* Construct the API message */
10212   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10213
10214   mp->sw_if_index = ntohl (sw_if_index);
10215   mp->max_interval = ntohl (max_interval);
10216   mp->min_interval = ntohl (min_interval);
10217   mp->lifetime = ntohl (lifetime);
10218   mp->initial_count = ntohl (initial_count);
10219   mp->initial_interval = ntohl (initial_interval);
10220   mp->suppress = suppress;
10221   mp->managed = managed;
10222   mp->other = other;
10223   mp->ll_option = ll_option;
10224   mp->send_unicast = send_unicast;
10225   mp->cease = cease;
10226   mp->is_no = is_no;
10227   mp->default_router = default_router;
10228
10229   /* send it... */
10230   S (mp);
10231
10232   /* Wait for a reply, return good/bad news  */
10233   W (ret);
10234   return ret;
10235 }
10236
10237 static int
10238 api_set_arp_neighbor_limit (vat_main_t * vam)
10239 {
10240   unformat_input_t *i = vam->input;
10241   vl_api_set_arp_neighbor_limit_t *mp;
10242   u32 arp_nbr_limit;
10243   u8 limit_set = 0;
10244   u8 is_ipv6 = 0;
10245   int ret;
10246
10247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10248     {
10249       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10250         limit_set = 1;
10251       else if (unformat (i, "ipv6"))
10252         is_ipv6 = 1;
10253       else
10254         {
10255           clib_warning ("parse error '%U'", format_unformat_error, i);
10256           return -99;
10257         }
10258     }
10259
10260   if (limit_set == 0)
10261     {
10262       errmsg ("missing limit value");
10263       return -99;
10264     }
10265
10266   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10267
10268   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10269   mp->is_ipv6 = is_ipv6;
10270
10271   S (mp);
10272   W (ret);
10273   return ret;
10274 }
10275
10276 static int
10277 api_l2_patch_add_del (vat_main_t * vam)
10278 {
10279   unformat_input_t *i = vam->input;
10280   vl_api_l2_patch_add_del_t *mp;
10281   u32 rx_sw_if_index;
10282   u8 rx_sw_if_index_set = 0;
10283   u32 tx_sw_if_index;
10284   u8 tx_sw_if_index_set = 0;
10285   u8 is_add = 1;
10286   int ret;
10287
10288   /* Parse args required to build the message */
10289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10290     {
10291       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10292         rx_sw_if_index_set = 1;
10293       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10294         tx_sw_if_index_set = 1;
10295       else if (unformat (i, "rx"))
10296         {
10297           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10298             {
10299               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10300                             &rx_sw_if_index))
10301                 rx_sw_if_index_set = 1;
10302             }
10303           else
10304             break;
10305         }
10306       else if (unformat (i, "tx"))
10307         {
10308           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10309             {
10310               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10311                             &tx_sw_if_index))
10312                 tx_sw_if_index_set = 1;
10313             }
10314           else
10315             break;
10316         }
10317       else if (unformat (i, "del"))
10318         is_add = 0;
10319       else
10320         break;
10321     }
10322
10323   if (rx_sw_if_index_set == 0)
10324     {
10325       errmsg ("missing rx interface name or rx_sw_if_index");
10326       return -99;
10327     }
10328
10329   if (tx_sw_if_index_set == 0)
10330     {
10331       errmsg ("missing tx interface name or tx_sw_if_index");
10332       return -99;
10333     }
10334
10335   M (L2_PATCH_ADD_DEL, mp);
10336
10337   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10338   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10339   mp->is_add = is_add;
10340
10341   S (mp);
10342   W (ret);
10343   return ret;
10344 }
10345
10346 u8 is_del;
10347 u8 localsid_addr[16];
10348 u8 end_psp;
10349 u8 behavior;
10350 u32 sw_if_index;
10351 u32 vlan_index;
10352 u32 fib_table;
10353 u8 nh_addr[16];
10354
10355 static int
10356 api_sr_localsid_add_del (vat_main_t * vam)
10357 {
10358   unformat_input_t *i = vam->input;
10359   vl_api_sr_localsid_add_del_t *mp;
10360
10361   u8 is_del;
10362   ip6_address_t localsid;
10363   u8 end_psp = 0;
10364   u8 behavior = ~0;
10365   u32 sw_if_index;
10366   u32 fib_table = ~(u32) 0;
10367   ip6_address_t next_hop;
10368
10369   bool nexthop_set = 0;
10370
10371   int ret;
10372
10373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (i, "del"))
10376         is_del = 1;
10377       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10378       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10379         nexthop_set = 1;
10380       else if (unformat (i, "behavior %u", &behavior));
10381       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10382       else if (unformat (i, "fib-table %u", &fib_table));
10383       else if (unformat (i, "end.psp %u", &behavior));
10384       else
10385         break;
10386     }
10387
10388   M (SR_LOCALSID_ADD_DEL, mp);
10389
10390   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10391   if (nexthop_set)
10392     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10393   mp->behavior = behavior;
10394   mp->sw_if_index = ntohl (sw_if_index);
10395   mp->fib_table = ntohl (fib_table);
10396   mp->end_psp = end_psp;
10397   mp->is_del = is_del;
10398
10399   S (mp);
10400   W (ret);
10401   return ret;
10402 }
10403
10404 static int
10405 api_ioam_enable (vat_main_t * vam)
10406 {
10407   unformat_input_t *input = vam->input;
10408   vl_api_ioam_enable_t *mp;
10409   u32 id = 0;
10410   int has_trace_option = 0;
10411   int has_pot_option = 0;
10412   int has_seqno_option = 0;
10413   int has_analyse_option = 0;
10414   int ret;
10415
10416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10417     {
10418       if (unformat (input, "trace"))
10419         has_trace_option = 1;
10420       else if (unformat (input, "pot"))
10421         has_pot_option = 1;
10422       else if (unformat (input, "seqno"))
10423         has_seqno_option = 1;
10424       else if (unformat (input, "analyse"))
10425         has_analyse_option = 1;
10426       else
10427         break;
10428     }
10429   M (IOAM_ENABLE, mp);
10430   mp->id = htons (id);
10431   mp->seqno = has_seqno_option;
10432   mp->analyse = has_analyse_option;
10433   mp->pot_enable = has_pot_option;
10434   mp->trace_enable = has_trace_option;
10435
10436   S (mp);
10437   W (ret);
10438   return ret;
10439 }
10440
10441
10442 static int
10443 api_ioam_disable (vat_main_t * vam)
10444 {
10445   vl_api_ioam_disable_t *mp;
10446   int ret;
10447
10448   M (IOAM_DISABLE, mp);
10449   S (mp);
10450   W (ret);
10451   return ret;
10452 }
10453
10454 #define foreach_tcp_proto_field                 \
10455 _(src_port)                                     \
10456 _(dst_port)
10457
10458 #define foreach_udp_proto_field                 \
10459 _(src_port)                                     \
10460 _(dst_port)
10461
10462 #define foreach_ip4_proto_field                 \
10463 _(src_address)                                  \
10464 _(dst_address)                                  \
10465 _(tos)                                          \
10466 _(length)                                       \
10467 _(fragment_id)                                  \
10468 _(ttl)                                          \
10469 _(protocol)                                     \
10470 _(checksum)
10471
10472 typedef struct
10473 {
10474   u16 src_port, dst_port;
10475 } tcpudp_header_t;
10476
10477 #if VPP_API_TEST_BUILTIN == 0
10478 uword
10479 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10480 {
10481   u8 **maskp = va_arg (*args, u8 **);
10482   u8 *mask = 0;
10483   u8 found_something = 0;
10484   tcp_header_t *tcp;
10485
10486 #define _(a) u8 a=0;
10487   foreach_tcp_proto_field;
10488 #undef _
10489
10490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10491     {
10492       if (0);
10493 #define _(a) else if (unformat (input, #a)) a=1;
10494       foreach_tcp_proto_field
10495 #undef _
10496         else
10497         break;
10498     }
10499
10500 #define _(a) found_something += a;
10501   foreach_tcp_proto_field;
10502 #undef _
10503
10504   if (found_something == 0)
10505     return 0;
10506
10507   vec_validate (mask, sizeof (*tcp) - 1);
10508
10509   tcp = (tcp_header_t *) mask;
10510
10511 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10512   foreach_tcp_proto_field;
10513 #undef _
10514
10515   *maskp = mask;
10516   return 1;
10517 }
10518
10519 uword
10520 unformat_udp_mask (unformat_input_t * input, va_list * args)
10521 {
10522   u8 **maskp = va_arg (*args, u8 **);
10523   u8 *mask = 0;
10524   u8 found_something = 0;
10525   udp_header_t *udp;
10526
10527 #define _(a) u8 a=0;
10528   foreach_udp_proto_field;
10529 #undef _
10530
10531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10532     {
10533       if (0);
10534 #define _(a) else if (unformat (input, #a)) a=1;
10535       foreach_udp_proto_field
10536 #undef _
10537         else
10538         break;
10539     }
10540
10541 #define _(a) found_something += a;
10542   foreach_udp_proto_field;
10543 #undef _
10544
10545   if (found_something == 0)
10546     return 0;
10547
10548   vec_validate (mask, sizeof (*udp) - 1);
10549
10550   udp = (udp_header_t *) mask;
10551
10552 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10553   foreach_udp_proto_field;
10554 #undef _
10555
10556   *maskp = mask;
10557   return 1;
10558 }
10559
10560 uword
10561 unformat_l4_mask (unformat_input_t * input, va_list * args)
10562 {
10563   u8 **maskp = va_arg (*args, u8 **);
10564   u16 src_port = 0, dst_port = 0;
10565   tcpudp_header_t *tcpudp;
10566
10567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10568     {
10569       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10570         return 1;
10571       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10572         return 1;
10573       else if (unformat (input, "src_port"))
10574         src_port = 0xFFFF;
10575       else if (unformat (input, "dst_port"))
10576         dst_port = 0xFFFF;
10577       else
10578         return 0;
10579     }
10580
10581   if (!src_port && !dst_port)
10582     return 0;
10583
10584   u8 *mask = 0;
10585   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10586
10587   tcpudp = (tcpudp_header_t *) mask;
10588   tcpudp->src_port = src_port;
10589   tcpudp->dst_port = dst_port;
10590
10591   *maskp = mask;
10592
10593   return 1;
10594 }
10595
10596 uword
10597 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10598 {
10599   u8 **maskp = va_arg (*args, u8 **);
10600   u8 *mask = 0;
10601   u8 found_something = 0;
10602   ip4_header_t *ip;
10603
10604 #define _(a) u8 a=0;
10605   foreach_ip4_proto_field;
10606 #undef _
10607   u8 version = 0;
10608   u8 hdr_length = 0;
10609
10610
10611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10612     {
10613       if (unformat (input, "version"))
10614         version = 1;
10615       else if (unformat (input, "hdr_length"))
10616         hdr_length = 1;
10617       else if (unformat (input, "src"))
10618         src_address = 1;
10619       else if (unformat (input, "dst"))
10620         dst_address = 1;
10621       else if (unformat (input, "proto"))
10622         protocol = 1;
10623
10624 #define _(a) else if (unformat (input, #a)) a=1;
10625       foreach_ip4_proto_field
10626 #undef _
10627         else
10628         break;
10629     }
10630
10631 #define _(a) found_something += a;
10632   foreach_ip4_proto_field;
10633 #undef _
10634
10635   if (found_something == 0)
10636     return 0;
10637
10638   vec_validate (mask, sizeof (*ip) - 1);
10639
10640   ip = (ip4_header_t *) mask;
10641
10642 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10643   foreach_ip4_proto_field;
10644 #undef _
10645
10646   ip->ip_version_and_header_length = 0;
10647
10648   if (version)
10649     ip->ip_version_and_header_length |= 0xF0;
10650
10651   if (hdr_length)
10652     ip->ip_version_and_header_length |= 0x0F;
10653
10654   *maskp = mask;
10655   return 1;
10656 }
10657
10658 #define foreach_ip6_proto_field                 \
10659 _(src_address)                                  \
10660 _(dst_address)                                  \
10661 _(payload_length)                               \
10662 _(hop_limit)                                    \
10663 _(protocol)
10664
10665 uword
10666 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10667 {
10668   u8 **maskp = va_arg (*args, u8 **);
10669   u8 *mask = 0;
10670   u8 found_something = 0;
10671   ip6_header_t *ip;
10672   u32 ip_version_traffic_class_and_flow_label;
10673
10674 #define _(a) u8 a=0;
10675   foreach_ip6_proto_field;
10676 #undef _
10677   u8 version = 0;
10678   u8 traffic_class = 0;
10679   u8 flow_label = 0;
10680
10681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10682     {
10683       if (unformat (input, "version"))
10684         version = 1;
10685       else if (unformat (input, "traffic-class"))
10686         traffic_class = 1;
10687       else if (unformat (input, "flow-label"))
10688         flow_label = 1;
10689       else if (unformat (input, "src"))
10690         src_address = 1;
10691       else if (unformat (input, "dst"))
10692         dst_address = 1;
10693       else if (unformat (input, "proto"))
10694         protocol = 1;
10695
10696 #define _(a) else if (unformat (input, #a)) a=1;
10697       foreach_ip6_proto_field
10698 #undef _
10699         else
10700         break;
10701     }
10702
10703 #define _(a) found_something += a;
10704   foreach_ip6_proto_field;
10705 #undef _
10706
10707   if (found_something == 0)
10708     return 0;
10709
10710   vec_validate (mask, sizeof (*ip) - 1);
10711
10712   ip = (ip6_header_t *) mask;
10713
10714 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10715   foreach_ip6_proto_field;
10716 #undef _
10717
10718   ip_version_traffic_class_and_flow_label = 0;
10719
10720   if (version)
10721     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10722
10723   if (traffic_class)
10724     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10725
10726   if (flow_label)
10727     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10728
10729   ip->ip_version_traffic_class_and_flow_label =
10730     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10731
10732   *maskp = mask;
10733   return 1;
10734 }
10735
10736 uword
10737 unformat_l3_mask (unformat_input_t * input, va_list * args)
10738 {
10739   u8 **maskp = va_arg (*args, u8 **);
10740
10741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10742     {
10743       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10744         return 1;
10745       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10746         return 1;
10747       else
10748         break;
10749     }
10750   return 0;
10751 }
10752
10753 uword
10754 unformat_l2_mask (unformat_input_t * input, va_list * args)
10755 {
10756   u8 **maskp = va_arg (*args, u8 **);
10757   u8 *mask = 0;
10758   u8 src = 0;
10759   u8 dst = 0;
10760   u8 proto = 0;
10761   u8 tag1 = 0;
10762   u8 tag2 = 0;
10763   u8 ignore_tag1 = 0;
10764   u8 ignore_tag2 = 0;
10765   u8 cos1 = 0;
10766   u8 cos2 = 0;
10767   u8 dot1q = 0;
10768   u8 dot1ad = 0;
10769   int len = 14;
10770
10771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10772     {
10773       if (unformat (input, "src"))
10774         src = 1;
10775       else if (unformat (input, "dst"))
10776         dst = 1;
10777       else if (unformat (input, "proto"))
10778         proto = 1;
10779       else if (unformat (input, "tag1"))
10780         tag1 = 1;
10781       else if (unformat (input, "tag2"))
10782         tag2 = 1;
10783       else if (unformat (input, "ignore-tag1"))
10784         ignore_tag1 = 1;
10785       else if (unformat (input, "ignore-tag2"))
10786         ignore_tag2 = 1;
10787       else if (unformat (input, "cos1"))
10788         cos1 = 1;
10789       else if (unformat (input, "cos2"))
10790         cos2 = 1;
10791       else if (unformat (input, "dot1q"))
10792         dot1q = 1;
10793       else if (unformat (input, "dot1ad"))
10794         dot1ad = 1;
10795       else
10796         break;
10797     }
10798   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10799        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10800     return 0;
10801
10802   if (tag1 || ignore_tag1 || cos1 || dot1q)
10803     len = 18;
10804   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10805     len = 22;
10806
10807   vec_validate (mask, len - 1);
10808
10809   if (dst)
10810     memset (mask, 0xff, 6);
10811
10812   if (src)
10813     memset (mask + 6, 0xff, 6);
10814
10815   if (tag2 || dot1ad)
10816     {
10817       /* inner vlan tag */
10818       if (tag2)
10819         {
10820           mask[19] = 0xff;
10821           mask[18] = 0x0f;
10822         }
10823       if (cos2)
10824         mask[18] |= 0xe0;
10825       if (proto)
10826         mask[21] = mask[20] = 0xff;
10827       if (tag1)
10828         {
10829           mask[15] = 0xff;
10830           mask[14] = 0x0f;
10831         }
10832       if (cos1)
10833         mask[14] |= 0xe0;
10834       *maskp = mask;
10835       return 1;
10836     }
10837   if (tag1 | dot1q)
10838     {
10839       if (tag1)
10840         {
10841           mask[15] = 0xff;
10842           mask[14] = 0x0f;
10843         }
10844       if (cos1)
10845         mask[14] |= 0xe0;
10846       if (proto)
10847         mask[16] = mask[17] = 0xff;
10848
10849       *maskp = mask;
10850       return 1;
10851     }
10852   if (cos2)
10853     mask[18] |= 0xe0;
10854   if (cos1)
10855     mask[14] |= 0xe0;
10856   if (proto)
10857     mask[12] = mask[13] = 0xff;
10858
10859   *maskp = mask;
10860   return 1;
10861 }
10862
10863 uword
10864 unformat_classify_mask (unformat_input_t * input, va_list * args)
10865 {
10866   u8 **maskp = va_arg (*args, u8 **);
10867   u32 *skipp = va_arg (*args, u32 *);
10868   u32 *matchp = va_arg (*args, u32 *);
10869   u32 match;
10870   u8 *mask = 0;
10871   u8 *l2 = 0;
10872   u8 *l3 = 0;
10873   u8 *l4 = 0;
10874   int i;
10875
10876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10879         ;
10880       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10881         ;
10882       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10883         ;
10884       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10885         ;
10886       else
10887         break;
10888     }
10889
10890   if (l4 && !l3)
10891     {
10892       vec_free (mask);
10893       vec_free (l2);
10894       vec_free (l4);
10895       return 0;
10896     }
10897
10898   if (mask || l2 || l3 || l4)
10899     {
10900       if (l2 || l3 || l4)
10901         {
10902           /* "With a free Ethernet header in every package" */
10903           if (l2 == 0)
10904             vec_validate (l2, 13);
10905           mask = l2;
10906           if (vec_len (l3))
10907             {
10908               vec_append (mask, l3);
10909               vec_free (l3);
10910             }
10911           if (vec_len (l4))
10912             {
10913               vec_append (mask, l4);
10914               vec_free (l4);
10915             }
10916         }
10917
10918       /* Scan forward looking for the first significant mask octet */
10919       for (i = 0; i < vec_len (mask); i++)
10920         if (mask[i])
10921           break;
10922
10923       /* compute (skip, match) params */
10924       *skipp = i / sizeof (u32x4);
10925       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10926
10927       /* Pad mask to an even multiple of the vector size */
10928       while (vec_len (mask) % sizeof (u32x4))
10929         vec_add1 (mask, 0);
10930
10931       match = vec_len (mask) / sizeof (u32x4);
10932
10933       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10934         {
10935           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10936           if (*tmp || *(tmp + 1))
10937             break;
10938           match--;
10939         }
10940       if (match == 0)
10941         clib_warning ("BUG: match 0");
10942
10943       _vec_len (mask) = match * sizeof (u32x4);
10944
10945       *matchp = match;
10946       *maskp = mask;
10947
10948       return 1;
10949     }
10950
10951   return 0;
10952 }
10953 #endif /* VPP_API_TEST_BUILTIN */
10954
10955 #define foreach_l2_next                         \
10956 _(drop, DROP)                                   \
10957 _(ethernet, ETHERNET_INPUT)                     \
10958 _(ip4, IP4_INPUT)                               \
10959 _(ip6, IP6_INPUT)
10960
10961 uword
10962 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10963 {
10964   u32 *miss_next_indexp = va_arg (*args, u32 *);
10965   u32 next_index = 0;
10966   u32 tmp;
10967
10968 #define _(n,N) \
10969   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10970   foreach_l2_next;
10971 #undef _
10972
10973   if (unformat (input, "%d", &tmp))
10974     {
10975       next_index = tmp;
10976       goto out;
10977     }
10978
10979   return 0;
10980
10981 out:
10982   *miss_next_indexp = next_index;
10983   return 1;
10984 }
10985
10986 #define foreach_ip_next                         \
10987 _(drop, DROP)                                   \
10988 _(local, LOCAL)                                 \
10989 _(rewrite, REWRITE)
10990
10991 uword
10992 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10993 {
10994   u32 *miss_next_indexp = va_arg (*args, u32 *);
10995   u32 next_index = 0;
10996   u32 tmp;
10997
10998 #define _(n,N) \
10999   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11000   foreach_ip_next;
11001 #undef _
11002
11003   if (unformat (input, "%d", &tmp))
11004     {
11005       next_index = tmp;
11006       goto out;
11007     }
11008
11009   return 0;
11010
11011 out:
11012   *miss_next_indexp = next_index;
11013   return 1;
11014 }
11015
11016 #define foreach_acl_next                        \
11017 _(deny, DENY)
11018
11019 uword
11020 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11021 {
11022   u32 *miss_next_indexp = va_arg (*args, u32 *);
11023   u32 next_index = 0;
11024   u32 tmp;
11025
11026 #define _(n,N) \
11027   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11028   foreach_acl_next;
11029 #undef _
11030
11031   if (unformat (input, "permit"))
11032     {
11033       next_index = ~0;
11034       goto out;
11035     }
11036   else if (unformat (input, "%d", &tmp))
11037     {
11038       next_index = tmp;
11039       goto out;
11040     }
11041
11042   return 0;
11043
11044 out:
11045   *miss_next_indexp = next_index;
11046   return 1;
11047 }
11048
11049 uword
11050 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11051 {
11052   u32 *r = va_arg (*args, u32 *);
11053
11054   if (unformat (input, "conform-color"))
11055     *r = POLICE_CONFORM;
11056   else if (unformat (input, "exceed-color"))
11057     *r = POLICE_EXCEED;
11058   else
11059     return 0;
11060
11061   return 1;
11062 }
11063
11064 static int
11065 api_classify_add_del_table (vat_main_t * vam)
11066 {
11067   unformat_input_t *i = vam->input;
11068   vl_api_classify_add_del_table_t *mp;
11069
11070   u32 nbuckets = 2;
11071   u32 skip = ~0;
11072   u32 match = ~0;
11073   int is_add = 1;
11074   int del_chain = 0;
11075   u32 table_index = ~0;
11076   u32 next_table_index = ~0;
11077   u32 miss_next_index = ~0;
11078   u32 memory_size = 32 << 20;
11079   u8 *mask = 0;
11080   u32 current_data_flag = 0;
11081   int current_data_offset = 0;
11082   int ret;
11083
11084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11085     {
11086       if (unformat (i, "del"))
11087         is_add = 0;
11088       else if (unformat (i, "del-chain"))
11089         {
11090           is_add = 0;
11091           del_chain = 1;
11092         }
11093       else if (unformat (i, "buckets %d", &nbuckets))
11094         ;
11095       else if (unformat (i, "memory_size %d", &memory_size))
11096         ;
11097       else if (unformat (i, "skip %d", &skip))
11098         ;
11099       else if (unformat (i, "match %d", &match))
11100         ;
11101       else if (unformat (i, "table %d", &table_index))
11102         ;
11103       else if (unformat (i, "mask %U", unformat_classify_mask,
11104                          &mask, &skip, &match))
11105         ;
11106       else if (unformat (i, "next-table %d", &next_table_index))
11107         ;
11108       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11109                          &miss_next_index))
11110         ;
11111       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11112                          &miss_next_index))
11113         ;
11114       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11115                          &miss_next_index))
11116         ;
11117       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11118         ;
11119       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11120         ;
11121       else
11122         break;
11123     }
11124
11125   if (is_add && mask == 0)
11126     {
11127       errmsg ("Mask required");
11128       return -99;
11129     }
11130
11131   if (is_add && skip == ~0)
11132     {
11133       errmsg ("skip count required");
11134       return -99;
11135     }
11136
11137   if (is_add && match == ~0)
11138     {
11139       errmsg ("match count required");
11140       return -99;
11141     }
11142
11143   if (!is_add && table_index == ~0)
11144     {
11145       errmsg ("table index required for delete");
11146       return -99;
11147     }
11148
11149   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11150
11151   mp->is_add = is_add;
11152   mp->del_chain = del_chain;
11153   mp->table_index = ntohl (table_index);
11154   mp->nbuckets = ntohl (nbuckets);
11155   mp->memory_size = ntohl (memory_size);
11156   mp->skip_n_vectors = ntohl (skip);
11157   mp->match_n_vectors = ntohl (match);
11158   mp->next_table_index = ntohl (next_table_index);
11159   mp->miss_next_index = ntohl (miss_next_index);
11160   mp->current_data_flag = ntohl (current_data_flag);
11161   mp->current_data_offset = ntohl (current_data_offset);
11162   clib_memcpy (mp->mask, mask, vec_len (mask));
11163
11164   vec_free (mask);
11165
11166   S (mp);
11167   W (ret);
11168   return ret;
11169 }
11170
11171 #if VPP_API_TEST_BUILTIN == 0
11172 uword
11173 unformat_l4_match (unformat_input_t * input, va_list * args)
11174 {
11175   u8 **matchp = va_arg (*args, u8 **);
11176
11177   u8 *proto_header = 0;
11178   int src_port = 0;
11179   int dst_port = 0;
11180
11181   tcpudp_header_t h;
11182
11183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11184     {
11185       if (unformat (input, "src_port %d", &src_port))
11186         ;
11187       else if (unformat (input, "dst_port %d", &dst_port))
11188         ;
11189       else
11190         return 0;
11191     }
11192
11193   h.src_port = clib_host_to_net_u16 (src_port);
11194   h.dst_port = clib_host_to_net_u16 (dst_port);
11195   vec_validate (proto_header, sizeof (h) - 1);
11196   memcpy (proto_header, &h, sizeof (h));
11197
11198   *matchp = proto_header;
11199
11200   return 1;
11201 }
11202
11203 uword
11204 unformat_ip4_match (unformat_input_t * input, va_list * args)
11205 {
11206   u8 **matchp = va_arg (*args, u8 **);
11207   u8 *match = 0;
11208   ip4_header_t *ip;
11209   int version = 0;
11210   u32 version_val;
11211   int hdr_length = 0;
11212   u32 hdr_length_val;
11213   int src = 0, dst = 0;
11214   ip4_address_t src_val, dst_val;
11215   int proto = 0;
11216   u32 proto_val;
11217   int tos = 0;
11218   u32 tos_val;
11219   int length = 0;
11220   u32 length_val;
11221   int fragment_id = 0;
11222   u32 fragment_id_val;
11223   int ttl = 0;
11224   int ttl_val;
11225   int checksum = 0;
11226   u32 checksum_val;
11227
11228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11229     {
11230       if (unformat (input, "version %d", &version_val))
11231         version = 1;
11232       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11233         hdr_length = 1;
11234       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11235         src = 1;
11236       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11237         dst = 1;
11238       else if (unformat (input, "proto %d", &proto_val))
11239         proto = 1;
11240       else if (unformat (input, "tos %d", &tos_val))
11241         tos = 1;
11242       else if (unformat (input, "length %d", &length_val))
11243         length = 1;
11244       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11245         fragment_id = 1;
11246       else if (unformat (input, "ttl %d", &ttl_val))
11247         ttl = 1;
11248       else if (unformat (input, "checksum %d", &checksum_val))
11249         checksum = 1;
11250       else
11251         break;
11252     }
11253
11254   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11255       + ttl + checksum == 0)
11256     return 0;
11257
11258   /*
11259    * Aligned because we use the real comparison functions
11260    */
11261   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11262
11263   ip = (ip4_header_t *) match;
11264
11265   /* These are realistically matched in practice */
11266   if (src)
11267     ip->src_address.as_u32 = src_val.as_u32;
11268
11269   if (dst)
11270     ip->dst_address.as_u32 = dst_val.as_u32;
11271
11272   if (proto)
11273     ip->protocol = proto_val;
11274
11275
11276   /* These are not, but they're included for completeness */
11277   if (version)
11278     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11279
11280   if (hdr_length)
11281     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11282
11283   if (tos)
11284     ip->tos = tos_val;
11285
11286   if (length)
11287     ip->length = clib_host_to_net_u16 (length_val);
11288
11289   if (ttl)
11290     ip->ttl = ttl_val;
11291
11292   if (checksum)
11293     ip->checksum = clib_host_to_net_u16 (checksum_val);
11294
11295   *matchp = match;
11296   return 1;
11297 }
11298
11299 uword
11300 unformat_ip6_match (unformat_input_t * input, va_list * args)
11301 {
11302   u8 **matchp = va_arg (*args, u8 **);
11303   u8 *match = 0;
11304   ip6_header_t *ip;
11305   int version = 0;
11306   u32 version_val;
11307   u8 traffic_class = 0;
11308   u32 traffic_class_val = 0;
11309   u8 flow_label = 0;
11310   u8 flow_label_val;
11311   int src = 0, dst = 0;
11312   ip6_address_t src_val, dst_val;
11313   int proto = 0;
11314   u32 proto_val;
11315   int payload_length = 0;
11316   u32 payload_length_val;
11317   int hop_limit = 0;
11318   int hop_limit_val;
11319   u32 ip_version_traffic_class_and_flow_label;
11320
11321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11322     {
11323       if (unformat (input, "version %d", &version_val))
11324         version = 1;
11325       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11326         traffic_class = 1;
11327       else if (unformat (input, "flow_label %d", &flow_label_val))
11328         flow_label = 1;
11329       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11330         src = 1;
11331       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11332         dst = 1;
11333       else if (unformat (input, "proto %d", &proto_val))
11334         proto = 1;
11335       else if (unformat (input, "payload_length %d", &payload_length_val))
11336         payload_length = 1;
11337       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11338         hop_limit = 1;
11339       else
11340         break;
11341     }
11342
11343   if (version + traffic_class + flow_label + src + dst + proto +
11344       payload_length + hop_limit == 0)
11345     return 0;
11346
11347   /*
11348    * Aligned because we use the real comparison functions
11349    */
11350   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11351
11352   ip = (ip6_header_t *) match;
11353
11354   if (src)
11355     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11356
11357   if (dst)
11358     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11359
11360   if (proto)
11361     ip->protocol = proto_val;
11362
11363   ip_version_traffic_class_and_flow_label = 0;
11364
11365   if (version)
11366     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11367
11368   if (traffic_class)
11369     ip_version_traffic_class_and_flow_label |=
11370       (traffic_class_val & 0xFF) << 20;
11371
11372   if (flow_label)
11373     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11374
11375   ip->ip_version_traffic_class_and_flow_label =
11376     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11377
11378   if (payload_length)
11379     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11380
11381   if (hop_limit)
11382     ip->hop_limit = hop_limit_val;
11383
11384   *matchp = match;
11385   return 1;
11386 }
11387
11388 uword
11389 unformat_l3_match (unformat_input_t * input, va_list * args)
11390 {
11391   u8 **matchp = va_arg (*args, u8 **);
11392
11393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11394     {
11395       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11396         return 1;
11397       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11398         return 1;
11399       else
11400         break;
11401     }
11402   return 0;
11403 }
11404
11405 uword
11406 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11407 {
11408   u8 *tagp = va_arg (*args, u8 *);
11409   u32 tag;
11410
11411   if (unformat (input, "%d", &tag))
11412     {
11413       tagp[0] = (tag >> 8) & 0x0F;
11414       tagp[1] = tag & 0xFF;
11415       return 1;
11416     }
11417
11418   return 0;
11419 }
11420
11421 uword
11422 unformat_l2_match (unformat_input_t * input, va_list * args)
11423 {
11424   u8 **matchp = va_arg (*args, u8 **);
11425   u8 *match = 0;
11426   u8 src = 0;
11427   u8 src_val[6];
11428   u8 dst = 0;
11429   u8 dst_val[6];
11430   u8 proto = 0;
11431   u16 proto_val;
11432   u8 tag1 = 0;
11433   u8 tag1_val[2];
11434   u8 tag2 = 0;
11435   u8 tag2_val[2];
11436   int len = 14;
11437   u8 ignore_tag1 = 0;
11438   u8 ignore_tag2 = 0;
11439   u8 cos1 = 0;
11440   u8 cos2 = 0;
11441   u32 cos1_val = 0;
11442   u32 cos2_val = 0;
11443
11444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11447         src = 1;
11448       else
11449         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11450         dst = 1;
11451       else if (unformat (input, "proto %U",
11452                          unformat_ethernet_type_host_byte_order, &proto_val))
11453         proto = 1;
11454       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11455         tag1 = 1;
11456       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11457         tag2 = 1;
11458       else if (unformat (input, "ignore-tag1"))
11459         ignore_tag1 = 1;
11460       else if (unformat (input, "ignore-tag2"))
11461         ignore_tag2 = 1;
11462       else if (unformat (input, "cos1 %d", &cos1_val))
11463         cos1 = 1;
11464       else if (unformat (input, "cos2 %d", &cos2_val))
11465         cos2 = 1;
11466       else
11467         break;
11468     }
11469   if ((src + dst + proto + tag1 + tag2 +
11470        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11471     return 0;
11472
11473   if (tag1 || ignore_tag1 || cos1)
11474     len = 18;
11475   if (tag2 || ignore_tag2 || cos2)
11476     len = 22;
11477
11478   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11479
11480   if (dst)
11481     clib_memcpy (match, dst_val, 6);
11482
11483   if (src)
11484     clib_memcpy (match + 6, src_val, 6);
11485
11486   if (tag2)
11487     {
11488       /* inner vlan tag */
11489       match[19] = tag2_val[1];
11490       match[18] = tag2_val[0];
11491       if (cos2)
11492         match[18] |= (cos2_val & 0x7) << 5;
11493       if (proto)
11494         {
11495           match[21] = proto_val & 0xff;
11496           match[20] = proto_val >> 8;
11497         }
11498       if (tag1)
11499         {
11500           match[15] = tag1_val[1];
11501           match[14] = tag1_val[0];
11502         }
11503       if (cos1)
11504         match[14] |= (cos1_val & 0x7) << 5;
11505       *matchp = match;
11506       return 1;
11507     }
11508   if (tag1)
11509     {
11510       match[15] = tag1_val[1];
11511       match[14] = tag1_val[0];
11512       if (proto)
11513         {
11514           match[17] = proto_val & 0xff;
11515           match[16] = proto_val >> 8;
11516         }
11517       if (cos1)
11518         match[14] |= (cos1_val & 0x7) << 5;
11519
11520       *matchp = match;
11521       return 1;
11522     }
11523   if (cos2)
11524     match[18] |= (cos2_val & 0x7) << 5;
11525   if (cos1)
11526     match[14] |= (cos1_val & 0x7) << 5;
11527   if (proto)
11528     {
11529       match[13] = proto_val & 0xff;
11530       match[12] = proto_val >> 8;
11531     }
11532
11533   *matchp = match;
11534   return 1;
11535 }
11536 #endif
11537
11538 uword
11539 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11540 {
11541   u8 **matchp = va_arg (*args, u8 **);
11542   u32 skip_n_vectors = va_arg (*args, u32);
11543   u32 match_n_vectors = va_arg (*args, u32);
11544
11545   u8 *match = 0;
11546   u8 *l2 = 0;
11547   u8 *l3 = 0;
11548   u8 *l4 = 0;
11549
11550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11551     {
11552       if (unformat (input, "hex %U", unformat_hex_string, &match))
11553         ;
11554       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11555         ;
11556       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11557         ;
11558       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11559         ;
11560       else
11561         break;
11562     }
11563
11564   if (l4 && !l3)
11565     {
11566       vec_free (match);
11567       vec_free (l2);
11568       vec_free (l4);
11569       return 0;
11570     }
11571
11572   if (match || l2 || l3 || l4)
11573     {
11574       if (l2 || l3 || l4)
11575         {
11576           /* "Win a free Ethernet header in every packet" */
11577           if (l2 == 0)
11578             vec_validate_aligned (l2, 13, sizeof (u32x4));
11579           match = l2;
11580           if (vec_len (l3))
11581             {
11582               vec_append_aligned (match, l3, sizeof (u32x4));
11583               vec_free (l3);
11584             }
11585           if (vec_len (l4))
11586             {
11587               vec_append_aligned (match, l4, sizeof (u32x4));
11588               vec_free (l4);
11589             }
11590         }
11591
11592       /* Make sure the vector is big enough even if key is all 0's */
11593       vec_validate_aligned
11594         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11595          sizeof (u32x4));
11596
11597       /* Set size, include skipped vectors */
11598       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11599
11600       *matchp = match;
11601
11602       return 1;
11603     }
11604
11605   return 0;
11606 }
11607
11608 static int
11609 api_classify_add_del_session (vat_main_t * vam)
11610 {
11611   unformat_input_t *i = vam->input;
11612   vl_api_classify_add_del_session_t *mp;
11613   int is_add = 1;
11614   u32 table_index = ~0;
11615   u32 hit_next_index = ~0;
11616   u32 opaque_index = ~0;
11617   u8 *match = 0;
11618   i32 advance = 0;
11619   u32 skip_n_vectors = 0;
11620   u32 match_n_vectors = 0;
11621   u32 action = 0;
11622   u32 metadata = 0;
11623   int ret;
11624
11625   /*
11626    * Warning: you have to supply skip_n and match_n
11627    * because the API client cant simply look at the classify
11628    * table object.
11629    */
11630
11631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11632     {
11633       if (unformat (i, "del"))
11634         is_add = 0;
11635       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11636                          &hit_next_index))
11637         ;
11638       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11639                          &hit_next_index))
11640         ;
11641       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11642                          &hit_next_index))
11643         ;
11644       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11645         ;
11646       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11647         ;
11648       else if (unformat (i, "opaque-index %d", &opaque_index))
11649         ;
11650       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11651         ;
11652       else if (unformat (i, "match_n %d", &match_n_vectors))
11653         ;
11654       else if (unformat (i, "match %U", api_unformat_classify_match,
11655                          &match, skip_n_vectors, match_n_vectors))
11656         ;
11657       else if (unformat (i, "advance %d", &advance))
11658         ;
11659       else if (unformat (i, "table-index %d", &table_index))
11660         ;
11661       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11662         action = 1;
11663       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11664         action = 2;
11665       else if (unformat (i, "action %d", &action))
11666         ;
11667       else if (unformat (i, "metadata %d", &metadata))
11668         ;
11669       else
11670         break;
11671     }
11672
11673   if (table_index == ~0)
11674     {
11675       errmsg ("Table index required");
11676       return -99;
11677     }
11678
11679   if (is_add && match == 0)
11680     {
11681       errmsg ("Match value required");
11682       return -99;
11683     }
11684
11685   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11686
11687   mp->is_add = is_add;
11688   mp->table_index = ntohl (table_index);
11689   mp->hit_next_index = ntohl (hit_next_index);
11690   mp->opaque_index = ntohl (opaque_index);
11691   mp->advance = ntohl (advance);
11692   mp->action = action;
11693   mp->metadata = ntohl (metadata);
11694   clib_memcpy (mp->match, match, vec_len (match));
11695   vec_free (match);
11696
11697   S (mp);
11698   W (ret);
11699   return ret;
11700 }
11701
11702 static int
11703 api_classify_set_interface_ip_table (vat_main_t * vam)
11704 {
11705   unformat_input_t *i = vam->input;
11706   vl_api_classify_set_interface_ip_table_t *mp;
11707   u32 sw_if_index;
11708   int sw_if_index_set;
11709   u32 table_index = ~0;
11710   u8 is_ipv6 = 0;
11711   int ret;
11712
11713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11714     {
11715       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11718         sw_if_index_set = 1;
11719       else if (unformat (i, "table %d", &table_index))
11720         ;
11721       else
11722         {
11723           clib_warning ("parse error '%U'", format_unformat_error, i);
11724           return -99;
11725         }
11726     }
11727
11728   if (sw_if_index_set == 0)
11729     {
11730       errmsg ("missing interface name or sw_if_index");
11731       return -99;
11732     }
11733
11734
11735   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11736
11737   mp->sw_if_index = ntohl (sw_if_index);
11738   mp->table_index = ntohl (table_index);
11739   mp->is_ipv6 = is_ipv6;
11740
11741   S (mp);
11742   W (ret);
11743   return ret;
11744 }
11745
11746 static int
11747 api_classify_set_interface_l2_tables (vat_main_t * vam)
11748 {
11749   unformat_input_t *i = vam->input;
11750   vl_api_classify_set_interface_l2_tables_t *mp;
11751   u32 sw_if_index;
11752   int sw_if_index_set;
11753   u32 ip4_table_index = ~0;
11754   u32 ip6_table_index = ~0;
11755   u32 other_table_index = ~0;
11756   u32 is_input = 1;
11757   int ret;
11758
11759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11760     {
11761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11762         sw_if_index_set = 1;
11763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11764         sw_if_index_set = 1;
11765       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11766         ;
11767       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11768         ;
11769       else if (unformat (i, "other-table %d", &other_table_index))
11770         ;
11771       else if (unformat (i, "is-input %d", &is_input))
11772         ;
11773       else
11774         {
11775           clib_warning ("parse error '%U'", format_unformat_error, i);
11776           return -99;
11777         }
11778     }
11779
11780   if (sw_if_index_set == 0)
11781     {
11782       errmsg ("missing interface name or sw_if_index");
11783       return -99;
11784     }
11785
11786
11787   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11788
11789   mp->sw_if_index = ntohl (sw_if_index);
11790   mp->ip4_table_index = ntohl (ip4_table_index);
11791   mp->ip6_table_index = ntohl (ip6_table_index);
11792   mp->other_table_index = ntohl (other_table_index);
11793   mp->is_input = (u8) is_input;
11794
11795   S (mp);
11796   W (ret);
11797   return ret;
11798 }
11799
11800 static int
11801 api_set_ipfix_exporter (vat_main_t * vam)
11802 {
11803   unformat_input_t *i = vam->input;
11804   vl_api_set_ipfix_exporter_t *mp;
11805   ip4_address_t collector_address;
11806   u8 collector_address_set = 0;
11807   u32 collector_port = ~0;
11808   ip4_address_t src_address;
11809   u8 src_address_set = 0;
11810   u32 vrf_id = ~0;
11811   u32 path_mtu = ~0;
11812   u32 template_interval = ~0;
11813   u8 udp_checksum = 0;
11814   int ret;
11815
11816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (i, "collector_address %U", unformat_ip4_address,
11819                     &collector_address))
11820         collector_address_set = 1;
11821       else if (unformat (i, "collector_port %d", &collector_port))
11822         ;
11823       else if (unformat (i, "src_address %U", unformat_ip4_address,
11824                          &src_address))
11825         src_address_set = 1;
11826       else if (unformat (i, "vrf_id %d", &vrf_id))
11827         ;
11828       else if (unformat (i, "path_mtu %d", &path_mtu))
11829         ;
11830       else if (unformat (i, "template_interval %d", &template_interval))
11831         ;
11832       else if (unformat (i, "udp_checksum"))
11833         udp_checksum = 1;
11834       else
11835         break;
11836     }
11837
11838   if (collector_address_set == 0)
11839     {
11840       errmsg ("collector_address required");
11841       return -99;
11842     }
11843
11844   if (src_address_set == 0)
11845     {
11846       errmsg ("src_address required");
11847       return -99;
11848     }
11849
11850   M (SET_IPFIX_EXPORTER, mp);
11851
11852   memcpy (mp->collector_address, collector_address.data,
11853           sizeof (collector_address.data));
11854   mp->collector_port = htons ((u16) collector_port);
11855   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11856   mp->vrf_id = htonl (vrf_id);
11857   mp->path_mtu = htonl (path_mtu);
11858   mp->template_interval = htonl (template_interval);
11859   mp->udp_checksum = udp_checksum;
11860
11861   S (mp);
11862   W (ret);
11863   return ret;
11864 }
11865
11866 static int
11867 api_set_ipfix_classify_stream (vat_main_t * vam)
11868 {
11869   unformat_input_t *i = vam->input;
11870   vl_api_set_ipfix_classify_stream_t *mp;
11871   u32 domain_id = 0;
11872   u32 src_port = UDP_DST_PORT_ipfix;
11873   int ret;
11874
11875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (i, "domain %d", &domain_id))
11878         ;
11879       else if (unformat (i, "src_port %d", &src_port))
11880         ;
11881       else
11882         {
11883           errmsg ("unknown input `%U'", format_unformat_error, i);
11884           return -99;
11885         }
11886     }
11887
11888   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11889
11890   mp->domain_id = htonl (domain_id);
11891   mp->src_port = htons ((u16) src_port);
11892
11893   S (mp);
11894   W (ret);
11895   return ret;
11896 }
11897
11898 static int
11899 api_ipfix_classify_table_add_del (vat_main_t * vam)
11900 {
11901   unformat_input_t *i = vam->input;
11902   vl_api_ipfix_classify_table_add_del_t *mp;
11903   int is_add = -1;
11904   u32 classify_table_index = ~0;
11905   u8 ip_version = 0;
11906   u8 transport_protocol = 255;
11907   int ret;
11908
11909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11910     {
11911       if (unformat (i, "add"))
11912         is_add = 1;
11913       else if (unformat (i, "del"))
11914         is_add = 0;
11915       else if (unformat (i, "table %d", &classify_table_index))
11916         ;
11917       else if (unformat (i, "ip4"))
11918         ip_version = 4;
11919       else if (unformat (i, "ip6"))
11920         ip_version = 6;
11921       else if (unformat (i, "tcp"))
11922         transport_protocol = 6;
11923       else if (unformat (i, "udp"))
11924         transport_protocol = 17;
11925       else
11926         {
11927           errmsg ("unknown input `%U'", format_unformat_error, i);
11928           return -99;
11929         }
11930     }
11931
11932   if (is_add == -1)
11933     {
11934       errmsg ("expecting: add|del");
11935       return -99;
11936     }
11937   if (classify_table_index == ~0)
11938     {
11939       errmsg ("classifier table not specified");
11940       return -99;
11941     }
11942   if (ip_version == 0)
11943     {
11944       errmsg ("IP version not specified");
11945       return -99;
11946     }
11947
11948   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11949
11950   mp->is_add = is_add;
11951   mp->table_id = htonl (classify_table_index);
11952   mp->ip_version = ip_version;
11953   mp->transport_protocol = transport_protocol;
11954
11955   S (mp);
11956   W (ret);
11957   return ret;
11958 }
11959
11960 static int
11961 api_get_node_index (vat_main_t * vam)
11962 {
11963   unformat_input_t *i = vam->input;
11964   vl_api_get_node_index_t *mp;
11965   u8 *name = 0;
11966   int ret;
11967
11968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11969     {
11970       if (unformat (i, "node %s", &name))
11971         ;
11972       else
11973         break;
11974     }
11975   if (name == 0)
11976     {
11977       errmsg ("node name required");
11978       return -99;
11979     }
11980   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11981     {
11982       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11983       return -99;
11984     }
11985
11986   M (GET_NODE_INDEX, mp);
11987   clib_memcpy (mp->node_name, name, vec_len (name));
11988   vec_free (name);
11989
11990   S (mp);
11991   W (ret);
11992   return ret;
11993 }
11994
11995 static int
11996 api_get_next_index (vat_main_t * vam)
11997 {
11998   unformat_input_t *i = vam->input;
11999   vl_api_get_next_index_t *mp;
12000   u8 *node_name = 0, *next_node_name = 0;
12001   int ret;
12002
12003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12004     {
12005       if (unformat (i, "node-name %s", &node_name))
12006         ;
12007       else if (unformat (i, "next-node-name %s", &next_node_name))
12008         break;
12009     }
12010
12011   if (node_name == 0)
12012     {
12013       errmsg ("node name required");
12014       return -99;
12015     }
12016   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12017     {
12018       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12019       return -99;
12020     }
12021
12022   if (next_node_name == 0)
12023     {
12024       errmsg ("next node name required");
12025       return -99;
12026     }
12027   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12028     {
12029       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12030       return -99;
12031     }
12032
12033   M (GET_NEXT_INDEX, mp);
12034   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12035   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12036   vec_free (node_name);
12037   vec_free (next_node_name);
12038
12039   S (mp);
12040   W (ret);
12041   return ret;
12042 }
12043
12044 static int
12045 api_add_node_next (vat_main_t * vam)
12046 {
12047   unformat_input_t *i = vam->input;
12048   vl_api_add_node_next_t *mp;
12049   u8 *name = 0;
12050   u8 *next = 0;
12051   int ret;
12052
12053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12054     {
12055       if (unformat (i, "node %s", &name))
12056         ;
12057       else if (unformat (i, "next %s", &next))
12058         ;
12059       else
12060         break;
12061     }
12062   if (name == 0)
12063     {
12064       errmsg ("node name required");
12065       return -99;
12066     }
12067   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12068     {
12069       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12070       return -99;
12071     }
12072   if (next == 0)
12073     {
12074       errmsg ("next node required");
12075       return -99;
12076     }
12077   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12078     {
12079       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12080       return -99;
12081     }
12082
12083   M (ADD_NODE_NEXT, mp);
12084   clib_memcpy (mp->node_name, name, vec_len (name));
12085   clib_memcpy (mp->next_name, next, vec_len (next));
12086   vec_free (name);
12087   vec_free (next);
12088
12089   S (mp);
12090   W (ret);
12091   return ret;
12092 }
12093
12094 static int
12095 api_l2tpv3_create_tunnel (vat_main_t * vam)
12096 {
12097   unformat_input_t *i = vam->input;
12098   ip6_address_t client_address, our_address;
12099   int client_address_set = 0;
12100   int our_address_set = 0;
12101   u32 local_session_id = 0;
12102   u32 remote_session_id = 0;
12103   u64 local_cookie = 0;
12104   u64 remote_cookie = 0;
12105   u8 l2_sublayer_present = 0;
12106   vl_api_l2tpv3_create_tunnel_t *mp;
12107   int ret;
12108
12109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (i, "client_address %U", unformat_ip6_address,
12112                     &client_address))
12113         client_address_set = 1;
12114       else if (unformat (i, "our_address %U", unformat_ip6_address,
12115                          &our_address))
12116         our_address_set = 1;
12117       else if (unformat (i, "local_session_id %d", &local_session_id))
12118         ;
12119       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12120         ;
12121       else if (unformat (i, "local_cookie %lld", &local_cookie))
12122         ;
12123       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12124         ;
12125       else if (unformat (i, "l2-sublayer-present"))
12126         l2_sublayer_present = 1;
12127       else
12128         break;
12129     }
12130
12131   if (client_address_set == 0)
12132     {
12133       errmsg ("client_address required");
12134       return -99;
12135     }
12136
12137   if (our_address_set == 0)
12138     {
12139       errmsg ("our_address required");
12140       return -99;
12141     }
12142
12143   M (L2TPV3_CREATE_TUNNEL, mp);
12144
12145   clib_memcpy (mp->client_address, client_address.as_u8,
12146                sizeof (mp->client_address));
12147
12148   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12149
12150   mp->local_session_id = ntohl (local_session_id);
12151   mp->remote_session_id = ntohl (remote_session_id);
12152   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12153   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12154   mp->l2_sublayer_present = l2_sublayer_present;
12155   mp->is_ipv6 = 1;
12156
12157   S (mp);
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static int
12163 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   u32 sw_if_index;
12167   u8 sw_if_index_set = 0;
12168   u64 new_local_cookie = 0;
12169   u64 new_remote_cookie = 0;
12170   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12171   int ret;
12172
12173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12174     {
12175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12178         sw_if_index_set = 1;
12179       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12180         ;
12181       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12182         ;
12183       else
12184         break;
12185     }
12186
12187   if (sw_if_index_set == 0)
12188     {
12189       errmsg ("missing interface name or sw_if_index");
12190       return -99;
12191     }
12192
12193   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12194
12195   mp->sw_if_index = ntohl (sw_if_index);
12196   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12197   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12198
12199   S (mp);
12200   W (ret);
12201   return ret;
12202 }
12203
12204 static int
12205 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12206 {
12207   unformat_input_t *i = vam->input;
12208   vl_api_l2tpv3_interface_enable_disable_t *mp;
12209   u32 sw_if_index;
12210   u8 sw_if_index_set = 0;
12211   u8 enable_disable = 1;
12212   int ret;
12213
12214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12215     {
12216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12219         sw_if_index_set = 1;
12220       else if (unformat (i, "enable"))
12221         enable_disable = 1;
12222       else if (unformat (i, "disable"))
12223         enable_disable = 0;
12224       else
12225         break;
12226     }
12227
12228   if (sw_if_index_set == 0)
12229     {
12230       errmsg ("missing interface name or sw_if_index");
12231       return -99;
12232     }
12233
12234   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12235
12236   mp->sw_if_index = ntohl (sw_if_index);
12237   mp->enable_disable = enable_disable;
12238
12239   S (mp);
12240   W (ret);
12241   return ret;
12242 }
12243
12244 static int
12245 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12246 {
12247   unformat_input_t *i = vam->input;
12248   vl_api_l2tpv3_set_lookup_key_t *mp;
12249   u8 key = ~0;
12250   int ret;
12251
12252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12253     {
12254       if (unformat (i, "lookup_v6_src"))
12255         key = L2T_LOOKUP_SRC_ADDRESS;
12256       else if (unformat (i, "lookup_v6_dst"))
12257         key = L2T_LOOKUP_DST_ADDRESS;
12258       else if (unformat (i, "lookup_session_id"))
12259         key = L2T_LOOKUP_SESSION_ID;
12260       else
12261         break;
12262     }
12263
12264   if (key == (u8) ~ 0)
12265     {
12266       errmsg ("l2tp session lookup key unset");
12267       return -99;
12268     }
12269
12270   M (L2TPV3_SET_LOOKUP_KEY, mp);
12271
12272   mp->key = key;
12273
12274   S (mp);
12275   W (ret);
12276   return ret;
12277 }
12278
12279 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12280   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12281 {
12282   vat_main_t *vam = &vat_main;
12283
12284   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12285          format_ip6_address, mp->our_address,
12286          format_ip6_address, mp->client_address,
12287          clib_net_to_host_u32 (mp->sw_if_index));
12288
12289   print (vam->ofp,
12290          "   local cookies %016llx %016llx remote cookie %016llx",
12291          clib_net_to_host_u64 (mp->local_cookie[0]),
12292          clib_net_to_host_u64 (mp->local_cookie[1]),
12293          clib_net_to_host_u64 (mp->remote_cookie));
12294
12295   print (vam->ofp, "   local session-id %d remote session-id %d",
12296          clib_net_to_host_u32 (mp->local_session_id),
12297          clib_net_to_host_u32 (mp->remote_session_id));
12298
12299   print (vam->ofp, "   l2 specific sublayer %s\n",
12300          mp->l2_sublayer_present ? "preset" : "absent");
12301
12302 }
12303
12304 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12305   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12306 {
12307   vat_main_t *vam = &vat_main;
12308   vat_json_node_t *node = NULL;
12309   struct in6_addr addr;
12310
12311   if (VAT_JSON_ARRAY != vam->json_tree.type)
12312     {
12313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12314       vat_json_init_array (&vam->json_tree);
12315     }
12316   node = vat_json_array_add (&vam->json_tree);
12317
12318   vat_json_init_object (node);
12319
12320   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12321   vat_json_object_add_ip6 (node, "our_address", addr);
12322   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12323   vat_json_object_add_ip6 (node, "client_address", addr);
12324
12325   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12326   vat_json_init_array (lc);
12327   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12328   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12329   vat_json_object_add_uint (node, "remote_cookie",
12330                             clib_net_to_host_u64 (mp->remote_cookie));
12331
12332   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12333   vat_json_object_add_uint (node, "local_session_id",
12334                             clib_net_to_host_u32 (mp->local_session_id));
12335   vat_json_object_add_uint (node, "remote_session_id",
12336                             clib_net_to_host_u32 (mp->remote_session_id));
12337   vat_json_object_add_string_copy (node, "l2_sublayer",
12338                                    mp->l2_sublayer_present ? (u8 *) "present"
12339                                    : (u8 *) "absent");
12340 }
12341
12342 static int
12343 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12344 {
12345   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12346   vl_api_control_ping_t *mp_ping;
12347   int ret;
12348
12349   /* Get list of l2tpv3-tunnel interfaces */
12350   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12351   S (mp);
12352
12353   /* Use a control ping for synchronization */
12354   MPING (CONTROL_PING, mp_ping);
12355   S (mp_ping);
12356
12357   W (ret);
12358   return ret;
12359 }
12360
12361
12362 static void vl_api_sw_interface_tap_details_t_handler
12363   (vl_api_sw_interface_tap_details_t * mp)
12364 {
12365   vat_main_t *vam = &vat_main;
12366
12367   print (vam->ofp, "%-16s %d",
12368          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12369 }
12370
12371 static void vl_api_sw_interface_tap_details_t_handler_json
12372   (vl_api_sw_interface_tap_details_t * mp)
12373 {
12374   vat_main_t *vam = &vat_main;
12375   vat_json_node_t *node = NULL;
12376
12377   if (VAT_JSON_ARRAY != vam->json_tree.type)
12378     {
12379       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12380       vat_json_init_array (&vam->json_tree);
12381     }
12382   node = vat_json_array_add (&vam->json_tree);
12383
12384   vat_json_init_object (node);
12385   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12386   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12387 }
12388
12389 static int
12390 api_sw_interface_tap_dump (vat_main_t * vam)
12391 {
12392   vl_api_sw_interface_tap_dump_t *mp;
12393   vl_api_control_ping_t *mp_ping;
12394   int ret;
12395
12396   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12397   /* Get list of tap interfaces */
12398   M (SW_INTERFACE_TAP_DUMP, mp);
12399   S (mp);
12400
12401   /* Use a control ping for synchronization */
12402   MPING (CONTROL_PING, mp_ping);
12403   S (mp_ping);
12404
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static void vl_api_sw_interface_tap_v2_details_t_handler
12410   (vl_api_sw_interface_tap_v2_details_t * mp)
12411 {
12412   vat_main_t *vam = &vat_main;
12413
12414   print (vam->ofp, "%-16s %d",
12415          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12416 }
12417
12418 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12419   (vl_api_sw_interface_tap_v2_details_t * mp)
12420 {
12421   vat_main_t *vam = &vat_main;
12422   vat_json_node_t *node = NULL;
12423
12424   if (VAT_JSON_ARRAY != vam->json_tree.type)
12425     {
12426       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12427       vat_json_init_array (&vam->json_tree);
12428     }
12429   node = vat_json_array_add (&vam->json_tree);
12430
12431   vat_json_init_object (node);
12432   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12433   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12434 }
12435
12436 static int
12437 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12438 {
12439   vl_api_sw_interface_tap_v2_dump_t *mp;
12440   vl_api_control_ping_t *mp_ping;
12441   int ret;
12442
12443   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12444   /* Get list of tap interfaces */
12445   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12446   S (mp);
12447
12448   /* Use a control ping for synchronization */
12449   MPING (CONTROL_PING, mp_ping);
12450   S (mp_ping);
12451
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static uword unformat_vxlan_decap_next
12457   (unformat_input_t * input, va_list * args)
12458 {
12459   u32 *result = va_arg (*args, u32 *);
12460   u32 tmp;
12461
12462   if (unformat (input, "l2"))
12463     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12464   else if (unformat (input, "%d", &tmp))
12465     *result = tmp;
12466   else
12467     return 0;
12468   return 1;
12469 }
12470
12471 static int
12472 api_vxlan_add_del_tunnel (vat_main_t * vam)
12473 {
12474   unformat_input_t *line_input = vam->input;
12475   vl_api_vxlan_add_del_tunnel_t *mp;
12476   ip46_address_t src, dst;
12477   u8 is_add = 1;
12478   u8 ipv4_set = 0, ipv6_set = 0;
12479   u8 src_set = 0;
12480   u8 dst_set = 0;
12481   u8 grp_set = 0;
12482   u32 mcast_sw_if_index = ~0;
12483   u32 encap_vrf_id = 0;
12484   u32 decap_next_index = ~0;
12485   u32 vni = 0;
12486   int ret;
12487
12488   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12489   memset (&src, 0, sizeof src);
12490   memset (&dst, 0, sizeof dst);
12491
12492   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12493     {
12494       if (unformat (line_input, "del"))
12495         is_add = 0;
12496       else
12497         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12498         {
12499           ipv4_set = 1;
12500           src_set = 1;
12501         }
12502       else
12503         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12504         {
12505           ipv4_set = 1;
12506           dst_set = 1;
12507         }
12508       else
12509         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12510         {
12511           ipv6_set = 1;
12512           src_set = 1;
12513         }
12514       else
12515         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12516         {
12517           ipv6_set = 1;
12518           dst_set = 1;
12519         }
12520       else if (unformat (line_input, "group %U %U",
12521                          unformat_ip4_address, &dst.ip4,
12522                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12523         {
12524           grp_set = dst_set = 1;
12525           ipv4_set = 1;
12526         }
12527       else if (unformat (line_input, "group %U",
12528                          unformat_ip4_address, &dst.ip4))
12529         {
12530           grp_set = dst_set = 1;
12531           ipv4_set = 1;
12532         }
12533       else if (unformat (line_input, "group %U %U",
12534                          unformat_ip6_address, &dst.ip6,
12535                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12536         {
12537           grp_set = dst_set = 1;
12538           ipv6_set = 1;
12539         }
12540       else if (unformat (line_input, "group %U",
12541                          unformat_ip6_address, &dst.ip6))
12542         {
12543           grp_set = dst_set = 1;
12544           ipv6_set = 1;
12545         }
12546       else
12547         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12548         ;
12549       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12550         ;
12551       else if (unformat (line_input, "decap-next %U",
12552                          unformat_vxlan_decap_next, &decap_next_index))
12553         ;
12554       else if (unformat (line_input, "vni %d", &vni))
12555         ;
12556       else
12557         {
12558           errmsg ("parse error '%U'", format_unformat_error, line_input);
12559           return -99;
12560         }
12561     }
12562
12563   if (src_set == 0)
12564     {
12565       errmsg ("tunnel src address not specified");
12566       return -99;
12567     }
12568   if (dst_set == 0)
12569     {
12570       errmsg ("tunnel dst address not specified");
12571       return -99;
12572     }
12573
12574   if (grp_set && !ip46_address_is_multicast (&dst))
12575     {
12576       errmsg ("tunnel group address not multicast");
12577       return -99;
12578     }
12579   if (grp_set && mcast_sw_if_index == ~0)
12580     {
12581       errmsg ("tunnel nonexistent multicast device");
12582       return -99;
12583     }
12584   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12585     {
12586       errmsg ("tunnel dst address must be unicast");
12587       return -99;
12588     }
12589
12590
12591   if (ipv4_set && ipv6_set)
12592     {
12593       errmsg ("both IPv4 and IPv6 addresses specified");
12594       return -99;
12595     }
12596
12597   if ((vni == 0) || (vni >> 24))
12598     {
12599       errmsg ("vni not specified or out of range");
12600       return -99;
12601     }
12602
12603   M (VXLAN_ADD_DEL_TUNNEL, mp);
12604
12605   if (ipv6_set)
12606     {
12607       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12608       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12609     }
12610   else
12611     {
12612       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12613       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12614     }
12615   mp->encap_vrf_id = ntohl (encap_vrf_id);
12616   mp->decap_next_index = ntohl (decap_next_index);
12617   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12618   mp->vni = ntohl (vni);
12619   mp->is_add = is_add;
12620   mp->is_ipv6 = ipv6_set;
12621
12622   S (mp);
12623   W (ret);
12624   return ret;
12625 }
12626
12627 static void vl_api_vxlan_tunnel_details_t_handler
12628   (vl_api_vxlan_tunnel_details_t * mp)
12629 {
12630   vat_main_t *vam = &vat_main;
12631   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12632   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12633
12634   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12635          ntohl (mp->sw_if_index),
12636          format_ip46_address, &src, IP46_TYPE_ANY,
12637          format_ip46_address, &dst, IP46_TYPE_ANY,
12638          ntohl (mp->encap_vrf_id),
12639          ntohl (mp->decap_next_index), ntohl (mp->vni),
12640          ntohl (mp->mcast_sw_if_index));
12641 }
12642
12643 static void vl_api_vxlan_tunnel_details_t_handler_json
12644   (vl_api_vxlan_tunnel_details_t * mp)
12645 {
12646   vat_main_t *vam = &vat_main;
12647   vat_json_node_t *node = NULL;
12648
12649   if (VAT_JSON_ARRAY != vam->json_tree.type)
12650     {
12651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12652       vat_json_init_array (&vam->json_tree);
12653     }
12654   node = vat_json_array_add (&vam->json_tree);
12655
12656   vat_json_init_object (node);
12657   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12658   if (mp->is_ipv6)
12659     {
12660       struct in6_addr ip6;
12661
12662       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12663       vat_json_object_add_ip6 (node, "src_address", ip6);
12664       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12665       vat_json_object_add_ip6 (node, "dst_address", ip6);
12666     }
12667   else
12668     {
12669       struct in_addr ip4;
12670
12671       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12672       vat_json_object_add_ip4 (node, "src_address", ip4);
12673       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12674       vat_json_object_add_ip4 (node, "dst_address", ip4);
12675     }
12676   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12677   vat_json_object_add_uint (node, "decap_next_index",
12678                             ntohl (mp->decap_next_index));
12679   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12680   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12681   vat_json_object_add_uint (node, "mcast_sw_if_index",
12682                             ntohl (mp->mcast_sw_if_index));
12683 }
12684
12685 static int
12686 api_vxlan_tunnel_dump (vat_main_t * vam)
12687 {
12688   unformat_input_t *i = vam->input;
12689   vl_api_vxlan_tunnel_dump_t *mp;
12690   vl_api_control_ping_t *mp_ping;
12691   u32 sw_if_index;
12692   u8 sw_if_index_set = 0;
12693   int ret;
12694
12695   /* Parse args required to build the message */
12696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12697     {
12698       if (unformat (i, "sw_if_index %d", &sw_if_index))
12699         sw_if_index_set = 1;
12700       else
12701         break;
12702     }
12703
12704   if (sw_if_index_set == 0)
12705     {
12706       sw_if_index = ~0;
12707     }
12708
12709   if (!vam->json_output)
12710     {
12711       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12712              "sw_if_index", "src_address", "dst_address",
12713              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12714     }
12715
12716   /* Get list of vxlan-tunnel interfaces */
12717   M (VXLAN_TUNNEL_DUMP, mp);
12718
12719   mp->sw_if_index = htonl (sw_if_index);
12720
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   MPING (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731 static uword unformat_geneve_decap_next
12732   (unformat_input_t * input, va_list * args)
12733 {
12734   u32 *result = va_arg (*args, u32 *);
12735   u32 tmp;
12736
12737   if (unformat (input, "l2"))
12738     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12739   else if (unformat (input, "%d", &tmp))
12740     *result = tmp;
12741   else
12742     return 0;
12743   return 1;
12744 }
12745
12746 static int
12747 api_geneve_add_del_tunnel (vat_main_t * vam)
12748 {
12749   unformat_input_t *line_input = vam->input;
12750   vl_api_geneve_add_del_tunnel_t *mp;
12751   ip46_address_t src, dst;
12752   u8 is_add = 1;
12753   u8 ipv4_set = 0, ipv6_set = 0;
12754   u8 src_set = 0;
12755   u8 dst_set = 0;
12756   u8 grp_set = 0;
12757   u32 mcast_sw_if_index = ~0;
12758   u32 encap_vrf_id = 0;
12759   u32 decap_next_index = ~0;
12760   u32 vni = 0;
12761   int ret;
12762
12763   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12764   memset (&src, 0, sizeof src);
12765   memset (&dst, 0, sizeof dst);
12766
12767   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (line_input, "del"))
12770         is_add = 0;
12771       else
12772         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12773         {
12774           ipv4_set = 1;
12775           src_set = 1;
12776         }
12777       else
12778         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12779         {
12780           ipv4_set = 1;
12781           dst_set = 1;
12782         }
12783       else
12784         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12785         {
12786           ipv6_set = 1;
12787           src_set = 1;
12788         }
12789       else
12790         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12791         {
12792           ipv6_set = 1;
12793           dst_set = 1;
12794         }
12795       else if (unformat (line_input, "group %U %U",
12796                          unformat_ip4_address, &dst.ip4,
12797                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12798         {
12799           grp_set = dst_set = 1;
12800           ipv4_set = 1;
12801         }
12802       else if (unformat (line_input, "group %U",
12803                          unformat_ip4_address, &dst.ip4))
12804         {
12805           grp_set = dst_set = 1;
12806           ipv4_set = 1;
12807         }
12808       else if (unformat (line_input, "group %U %U",
12809                          unformat_ip6_address, &dst.ip6,
12810                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12811         {
12812           grp_set = dst_set = 1;
12813           ipv6_set = 1;
12814         }
12815       else if (unformat (line_input, "group %U",
12816                          unformat_ip6_address, &dst.ip6))
12817         {
12818           grp_set = dst_set = 1;
12819           ipv6_set = 1;
12820         }
12821       else
12822         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12823         ;
12824       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12825         ;
12826       else if (unformat (line_input, "decap-next %U",
12827                          unformat_geneve_decap_next, &decap_next_index))
12828         ;
12829       else if (unformat (line_input, "vni %d", &vni))
12830         ;
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, line_input);
12834           return -99;
12835         }
12836     }
12837
12838   if (src_set == 0)
12839     {
12840       errmsg ("tunnel src address not specified");
12841       return -99;
12842     }
12843   if (dst_set == 0)
12844     {
12845       errmsg ("tunnel dst address not specified");
12846       return -99;
12847     }
12848
12849   if (grp_set && !ip46_address_is_multicast (&dst))
12850     {
12851       errmsg ("tunnel group address not multicast");
12852       return -99;
12853     }
12854   if (grp_set && mcast_sw_if_index == ~0)
12855     {
12856       errmsg ("tunnel nonexistent multicast device");
12857       return -99;
12858     }
12859   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12860     {
12861       errmsg ("tunnel dst address must be unicast");
12862       return -99;
12863     }
12864
12865
12866   if (ipv4_set && ipv6_set)
12867     {
12868       errmsg ("both IPv4 and IPv6 addresses specified");
12869       return -99;
12870     }
12871
12872   if ((vni == 0) || (vni >> 24))
12873     {
12874       errmsg ("vni not specified or out of range");
12875       return -99;
12876     }
12877
12878   M (GENEVE_ADD_DEL_TUNNEL, mp);
12879
12880   if (ipv6_set)
12881     {
12882       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12883       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12884     }
12885   else
12886     {
12887       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12888       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12889     }
12890   mp->encap_vrf_id = ntohl (encap_vrf_id);
12891   mp->decap_next_index = ntohl (decap_next_index);
12892   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12893   mp->vni = ntohl (vni);
12894   mp->is_add = is_add;
12895   mp->is_ipv6 = ipv6_set;
12896
12897   S (mp);
12898   W (ret);
12899   return ret;
12900 }
12901
12902 static void vl_api_geneve_tunnel_details_t_handler
12903   (vl_api_geneve_tunnel_details_t * mp)
12904 {
12905   vat_main_t *vam = &vat_main;
12906   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12907   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12908
12909   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12910          ntohl (mp->sw_if_index),
12911          format_ip46_address, &src, IP46_TYPE_ANY,
12912          format_ip46_address, &dst, IP46_TYPE_ANY,
12913          ntohl (mp->encap_vrf_id),
12914          ntohl (mp->decap_next_index), ntohl (mp->vni),
12915          ntohl (mp->mcast_sw_if_index));
12916 }
12917
12918 static void vl_api_geneve_tunnel_details_t_handler_json
12919   (vl_api_geneve_tunnel_details_t * mp)
12920 {
12921   vat_main_t *vam = &vat_main;
12922   vat_json_node_t *node = NULL;
12923
12924   if (VAT_JSON_ARRAY != vam->json_tree.type)
12925     {
12926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12927       vat_json_init_array (&vam->json_tree);
12928     }
12929   node = vat_json_array_add (&vam->json_tree);
12930
12931   vat_json_init_object (node);
12932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12933   if (mp->is_ipv6)
12934     {
12935       struct in6_addr ip6;
12936
12937       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12938       vat_json_object_add_ip6 (node, "src_address", ip6);
12939       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12940       vat_json_object_add_ip6 (node, "dst_address", ip6);
12941     }
12942   else
12943     {
12944       struct in_addr ip4;
12945
12946       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12947       vat_json_object_add_ip4 (node, "src_address", ip4);
12948       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12949       vat_json_object_add_ip4 (node, "dst_address", ip4);
12950     }
12951   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12952   vat_json_object_add_uint (node, "decap_next_index",
12953                             ntohl (mp->decap_next_index));
12954   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12955   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12956   vat_json_object_add_uint (node, "mcast_sw_if_index",
12957                             ntohl (mp->mcast_sw_if_index));
12958 }
12959
12960 static int
12961 api_geneve_tunnel_dump (vat_main_t * vam)
12962 {
12963   unformat_input_t *i = vam->input;
12964   vl_api_geneve_tunnel_dump_t *mp;
12965   vl_api_control_ping_t *mp_ping;
12966   u32 sw_if_index;
12967   u8 sw_if_index_set = 0;
12968   int ret;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (i, "sw_if_index %d", &sw_if_index))
12974         sw_if_index_set = 1;
12975       else
12976         break;
12977     }
12978
12979   if (sw_if_index_set == 0)
12980     {
12981       sw_if_index = ~0;
12982     }
12983
12984   if (!vam->json_output)
12985     {
12986       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12987              "sw_if_index", "local_address", "remote_address",
12988              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12989     }
12990
12991   /* Get list of geneve-tunnel interfaces */
12992   M (GENEVE_TUNNEL_DUMP, mp);
12993
12994   mp->sw_if_index = htonl (sw_if_index);
12995
12996   S (mp);
12997
12998   /* Use a control ping for synchronization */
12999   M (CONTROL_PING, mp_ping);
13000   S (mp_ping);
13001
13002   W (ret);
13003   return ret;
13004 }
13005
13006 static int
13007 api_gre_add_del_tunnel (vat_main_t * vam)
13008 {
13009   unformat_input_t *line_input = vam->input;
13010   vl_api_gre_add_del_tunnel_t *mp;
13011   ip4_address_t src4, dst4;
13012   ip6_address_t src6, dst6;
13013   u8 is_add = 1;
13014   u8 ipv4_set = 0;
13015   u8 ipv6_set = 0;
13016   u8 teb = 0;
13017   u8 src_set = 0;
13018   u8 dst_set = 0;
13019   u32 outer_fib_id = 0;
13020   int ret;
13021
13022   memset (&src4, 0, sizeof src4);
13023   memset (&dst4, 0, sizeof dst4);
13024   memset (&src6, 0, sizeof src6);
13025   memset (&dst6, 0, sizeof dst6);
13026
13027   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13028     {
13029       if (unformat (line_input, "del"))
13030         is_add = 0;
13031       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13032         {
13033           src_set = 1;
13034           ipv4_set = 1;
13035         }
13036       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13037         {
13038           dst_set = 1;
13039           ipv4_set = 1;
13040         }
13041       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13042         {
13043           src_set = 1;
13044           ipv6_set = 1;
13045         }
13046       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13047         {
13048           dst_set = 1;
13049           ipv6_set = 1;
13050         }
13051       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13052         ;
13053       else if (unformat (line_input, "teb"))
13054         teb = 1;
13055       else
13056         {
13057           errmsg ("parse error '%U'", format_unformat_error, line_input);
13058           return -99;
13059         }
13060     }
13061
13062   if (src_set == 0)
13063     {
13064       errmsg ("tunnel src address not specified");
13065       return -99;
13066     }
13067   if (dst_set == 0)
13068     {
13069       errmsg ("tunnel dst address not specified");
13070       return -99;
13071     }
13072   if (ipv4_set && ipv6_set)
13073     {
13074       errmsg ("both IPv4 and IPv6 addresses specified");
13075       return -99;
13076     }
13077
13078
13079   M (GRE_ADD_DEL_TUNNEL, mp);
13080
13081   if (ipv4_set)
13082     {
13083       clib_memcpy (&mp->src_address, &src4, 4);
13084       clib_memcpy (&mp->dst_address, &dst4, 4);
13085     }
13086   else
13087     {
13088       clib_memcpy (&mp->src_address, &src6, 16);
13089       clib_memcpy (&mp->dst_address, &dst6, 16);
13090     }
13091   mp->outer_fib_id = ntohl (outer_fib_id);
13092   mp->is_add = is_add;
13093   mp->teb = teb;
13094   mp->is_ipv6 = ipv6_set;
13095
13096   S (mp);
13097   W (ret);
13098   return ret;
13099 }
13100
13101 static void vl_api_gre_tunnel_details_t_handler
13102   (vl_api_gre_tunnel_details_t * mp)
13103 {
13104   vat_main_t *vam = &vat_main;
13105   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13106   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13107
13108   print (vam->ofp, "%11d%24U%24U%6d%14d",
13109          ntohl (mp->sw_if_index),
13110          format_ip46_address, &src, IP46_TYPE_ANY,
13111          format_ip46_address, &dst, IP46_TYPE_ANY,
13112          mp->teb, ntohl (mp->outer_fib_id));
13113 }
13114
13115 static void vl_api_gre_tunnel_details_t_handler_json
13116   (vl_api_gre_tunnel_details_t * mp)
13117 {
13118   vat_main_t *vam = &vat_main;
13119   vat_json_node_t *node = NULL;
13120   struct in_addr ip4;
13121   struct in6_addr ip6;
13122
13123   if (VAT_JSON_ARRAY != vam->json_tree.type)
13124     {
13125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13126       vat_json_init_array (&vam->json_tree);
13127     }
13128   node = vat_json_array_add (&vam->json_tree);
13129
13130   vat_json_init_object (node);
13131   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13132   if (!mp->is_ipv6)
13133     {
13134       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13135       vat_json_object_add_ip4 (node, "src_address", ip4);
13136       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13137       vat_json_object_add_ip4 (node, "dst_address", ip4);
13138     }
13139   else
13140     {
13141       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13142       vat_json_object_add_ip6 (node, "src_address", ip6);
13143       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13144       vat_json_object_add_ip6 (node, "dst_address", ip6);
13145     }
13146   vat_json_object_add_uint (node, "teb", mp->teb);
13147   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13148   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13149 }
13150
13151 static int
13152 api_gre_tunnel_dump (vat_main_t * vam)
13153 {
13154   unformat_input_t *i = vam->input;
13155   vl_api_gre_tunnel_dump_t *mp;
13156   vl_api_control_ping_t *mp_ping;
13157   u32 sw_if_index;
13158   u8 sw_if_index_set = 0;
13159   int ret;
13160
13161   /* Parse args required to build the message */
13162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13163     {
13164       if (unformat (i, "sw_if_index %d", &sw_if_index))
13165         sw_if_index_set = 1;
13166       else
13167         break;
13168     }
13169
13170   if (sw_if_index_set == 0)
13171     {
13172       sw_if_index = ~0;
13173     }
13174
13175   if (!vam->json_output)
13176     {
13177       print (vam->ofp, "%11s%24s%24s%6s%14s",
13178              "sw_if_index", "src_address", "dst_address", "teb",
13179              "outer_fib_id");
13180     }
13181
13182   /* Get list of gre-tunnel interfaces */
13183   M (GRE_TUNNEL_DUMP, mp);
13184
13185   mp->sw_if_index = htonl (sw_if_index);
13186
13187   S (mp);
13188
13189   /* Use a control ping for synchronization */
13190   MPING (CONTROL_PING, mp_ping);
13191   S (mp_ping);
13192
13193   W (ret);
13194   return ret;
13195 }
13196
13197 static int
13198 api_l2_fib_clear_table (vat_main_t * vam)
13199 {
13200 //  unformat_input_t * i = vam->input;
13201   vl_api_l2_fib_clear_table_t *mp;
13202   int ret;
13203
13204   M (L2_FIB_CLEAR_TABLE, mp);
13205
13206   S (mp);
13207   W (ret);
13208   return ret;
13209 }
13210
13211 static int
13212 api_l2_interface_efp_filter (vat_main_t * vam)
13213 {
13214   unformat_input_t *i = vam->input;
13215   vl_api_l2_interface_efp_filter_t *mp;
13216   u32 sw_if_index;
13217   u8 enable = 1;
13218   u8 sw_if_index_set = 0;
13219   int ret;
13220
13221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13222     {
13223       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13224         sw_if_index_set = 1;
13225       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13226         sw_if_index_set = 1;
13227       else if (unformat (i, "enable"))
13228         enable = 1;
13229       else if (unformat (i, "disable"))
13230         enable = 0;
13231       else
13232         {
13233           clib_warning ("parse error '%U'", format_unformat_error, i);
13234           return -99;
13235         }
13236     }
13237
13238   if (sw_if_index_set == 0)
13239     {
13240       errmsg ("missing sw_if_index");
13241       return -99;
13242     }
13243
13244   M (L2_INTERFACE_EFP_FILTER, mp);
13245
13246   mp->sw_if_index = ntohl (sw_if_index);
13247   mp->enable_disable = enable;
13248
13249   S (mp);
13250   W (ret);
13251   return ret;
13252 }
13253
13254 #define foreach_vtr_op                          \
13255 _("disable",  L2_VTR_DISABLED)                  \
13256 _("push-1",  L2_VTR_PUSH_1)                     \
13257 _("push-2",  L2_VTR_PUSH_2)                     \
13258 _("pop-1",  L2_VTR_POP_1)                       \
13259 _("pop-2",  L2_VTR_POP_2)                       \
13260 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13261 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13262 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13263 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13264
13265 static int
13266 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13267 {
13268   unformat_input_t *i = vam->input;
13269   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13270   u32 sw_if_index;
13271   u8 sw_if_index_set = 0;
13272   u8 vtr_op_set = 0;
13273   u32 vtr_op = 0;
13274   u32 push_dot1q = 1;
13275   u32 tag1 = ~0;
13276   u32 tag2 = ~0;
13277   int ret;
13278
13279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13280     {
13281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13282         sw_if_index_set = 1;
13283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13284         sw_if_index_set = 1;
13285       else if (unformat (i, "vtr_op %d", &vtr_op))
13286         vtr_op_set = 1;
13287 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13288       foreach_vtr_op
13289 #undef _
13290         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13291         ;
13292       else if (unformat (i, "tag1 %d", &tag1))
13293         ;
13294       else if (unformat (i, "tag2 %d", &tag2))
13295         ;
13296       else
13297         {
13298           clib_warning ("parse error '%U'", format_unformat_error, i);
13299           return -99;
13300         }
13301     }
13302
13303   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13304     {
13305       errmsg ("missing vtr operation or sw_if_index");
13306       return -99;
13307     }
13308
13309   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13310   mp->sw_if_index = ntohl (sw_if_index);
13311   mp->vtr_op = ntohl (vtr_op);
13312   mp->push_dot1q = ntohl (push_dot1q);
13313   mp->tag1 = ntohl (tag1);
13314   mp->tag2 = ntohl (tag2);
13315
13316   S (mp);
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static int
13322 api_create_vhost_user_if (vat_main_t * vam)
13323 {
13324   unformat_input_t *i = vam->input;
13325   vl_api_create_vhost_user_if_t *mp;
13326   u8 *file_name;
13327   u8 is_server = 0;
13328   u8 file_name_set = 0;
13329   u32 custom_dev_instance = ~0;
13330   u8 hwaddr[6];
13331   u8 use_custom_mac = 0;
13332   u8 *tag = 0;
13333   int ret;
13334
13335   /* Shut up coverity */
13336   memset (hwaddr, 0, sizeof (hwaddr));
13337
13338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13339     {
13340       if (unformat (i, "socket %s", &file_name))
13341         {
13342           file_name_set = 1;
13343         }
13344       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13345         ;
13346       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13347         use_custom_mac = 1;
13348       else if (unformat (i, "server"))
13349         is_server = 1;
13350       else if (unformat (i, "tag %s", &tag))
13351         ;
13352       else
13353         break;
13354     }
13355
13356   if (file_name_set == 0)
13357     {
13358       errmsg ("missing socket file name");
13359       return -99;
13360     }
13361
13362   if (vec_len (file_name) > 255)
13363     {
13364       errmsg ("socket file name too long");
13365       return -99;
13366     }
13367   vec_add1 (file_name, 0);
13368
13369   M (CREATE_VHOST_USER_IF, mp);
13370
13371   mp->is_server = is_server;
13372   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13373   vec_free (file_name);
13374   if (custom_dev_instance != ~0)
13375     {
13376       mp->renumber = 1;
13377       mp->custom_dev_instance = ntohl (custom_dev_instance);
13378     }
13379   mp->use_custom_mac = use_custom_mac;
13380   clib_memcpy (mp->mac_address, hwaddr, 6);
13381   if (tag)
13382     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13383   vec_free (tag);
13384
13385   S (mp);
13386   W (ret);
13387   return ret;
13388 }
13389
13390 static int
13391 api_modify_vhost_user_if (vat_main_t * vam)
13392 {
13393   unformat_input_t *i = vam->input;
13394   vl_api_modify_vhost_user_if_t *mp;
13395   u8 *file_name;
13396   u8 is_server = 0;
13397   u8 file_name_set = 0;
13398   u32 custom_dev_instance = ~0;
13399   u8 sw_if_index_set = 0;
13400   u32 sw_if_index = (u32) ~ 0;
13401   int ret;
13402
13403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13404     {
13405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13406         sw_if_index_set = 1;
13407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13408         sw_if_index_set = 1;
13409       else if (unformat (i, "socket %s", &file_name))
13410         {
13411           file_name_set = 1;
13412         }
13413       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13414         ;
13415       else if (unformat (i, "server"))
13416         is_server = 1;
13417       else
13418         break;
13419     }
13420
13421   if (sw_if_index_set == 0)
13422     {
13423       errmsg ("missing sw_if_index or interface name");
13424       return -99;
13425     }
13426
13427   if (file_name_set == 0)
13428     {
13429       errmsg ("missing socket file name");
13430       return -99;
13431     }
13432
13433   if (vec_len (file_name) > 255)
13434     {
13435       errmsg ("socket file name too long");
13436       return -99;
13437     }
13438   vec_add1 (file_name, 0);
13439
13440   M (MODIFY_VHOST_USER_IF, mp);
13441
13442   mp->sw_if_index = ntohl (sw_if_index);
13443   mp->is_server = is_server;
13444   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13445   vec_free (file_name);
13446   if (custom_dev_instance != ~0)
13447     {
13448       mp->renumber = 1;
13449       mp->custom_dev_instance = ntohl (custom_dev_instance);
13450     }
13451
13452   S (mp);
13453   W (ret);
13454   return ret;
13455 }
13456
13457 static int
13458 api_delete_vhost_user_if (vat_main_t * vam)
13459 {
13460   unformat_input_t *i = vam->input;
13461   vl_api_delete_vhost_user_if_t *mp;
13462   u32 sw_if_index = ~0;
13463   u8 sw_if_index_set = 0;
13464   int ret;
13465
13466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13467     {
13468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13469         sw_if_index_set = 1;
13470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13471         sw_if_index_set = 1;
13472       else
13473         break;
13474     }
13475
13476   if (sw_if_index_set == 0)
13477     {
13478       errmsg ("missing sw_if_index or interface name");
13479       return -99;
13480     }
13481
13482
13483   M (DELETE_VHOST_USER_IF, mp);
13484
13485   mp->sw_if_index = ntohl (sw_if_index);
13486
13487   S (mp);
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static void vl_api_sw_interface_vhost_user_details_t_handler
13493   (vl_api_sw_interface_vhost_user_details_t * mp)
13494 {
13495   vat_main_t *vam = &vat_main;
13496
13497   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13498          (char *) mp->interface_name,
13499          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13500          clib_net_to_host_u64 (mp->features), mp->is_server,
13501          ntohl (mp->num_regions), (char *) mp->sock_filename);
13502   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13503 }
13504
13505 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13506   (vl_api_sw_interface_vhost_user_details_t * mp)
13507 {
13508   vat_main_t *vam = &vat_main;
13509   vat_json_node_t *node = NULL;
13510
13511   if (VAT_JSON_ARRAY != vam->json_tree.type)
13512     {
13513       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13514       vat_json_init_array (&vam->json_tree);
13515     }
13516   node = vat_json_array_add (&vam->json_tree);
13517
13518   vat_json_init_object (node);
13519   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13520   vat_json_object_add_string_copy (node, "interface_name",
13521                                    mp->interface_name);
13522   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13523                             ntohl (mp->virtio_net_hdr_sz));
13524   vat_json_object_add_uint (node, "features",
13525                             clib_net_to_host_u64 (mp->features));
13526   vat_json_object_add_uint (node, "is_server", mp->is_server);
13527   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13528   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13529   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13530 }
13531
13532 static int
13533 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13534 {
13535   vl_api_sw_interface_vhost_user_dump_t *mp;
13536   vl_api_control_ping_t *mp_ping;
13537   int ret;
13538   print (vam->ofp,
13539          "Interface name            idx hdr_sz features server regions filename");
13540
13541   /* Get list of vhost-user interfaces */
13542   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13543   S (mp);
13544
13545   /* Use a control ping for synchronization */
13546   MPING (CONTROL_PING, mp_ping);
13547   S (mp_ping);
13548
13549   W (ret);
13550   return ret;
13551 }
13552
13553 static int
13554 api_show_version (vat_main_t * vam)
13555 {
13556   vl_api_show_version_t *mp;
13557   int ret;
13558
13559   M (SHOW_VERSION, mp);
13560
13561   S (mp);
13562   W (ret);
13563   return ret;
13564 }
13565
13566
13567 static int
13568 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13569 {
13570   unformat_input_t *line_input = vam->input;
13571   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13572   ip4_address_t local4, remote4;
13573   ip6_address_t local6, remote6;
13574   u8 is_add = 1;
13575   u8 ipv4_set = 0, ipv6_set = 0;
13576   u8 local_set = 0;
13577   u8 remote_set = 0;
13578   u8 grp_set = 0;
13579   u32 mcast_sw_if_index = ~0;
13580   u32 encap_vrf_id = 0;
13581   u32 decap_vrf_id = 0;
13582   u8 protocol = ~0;
13583   u32 vni;
13584   u8 vni_set = 0;
13585   int ret;
13586
13587   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13588   memset (&local4, 0, sizeof local4);
13589   memset (&remote4, 0, sizeof remote4);
13590   memset (&local6, 0, sizeof local6);
13591   memset (&remote6, 0, sizeof remote6);
13592
13593   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13594     {
13595       if (unformat (line_input, "del"))
13596         is_add = 0;
13597       else if (unformat (line_input, "local %U",
13598                          unformat_ip4_address, &local4))
13599         {
13600           local_set = 1;
13601           ipv4_set = 1;
13602         }
13603       else if (unformat (line_input, "remote %U",
13604                          unformat_ip4_address, &remote4))
13605         {
13606           remote_set = 1;
13607           ipv4_set = 1;
13608         }
13609       else if (unformat (line_input, "local %U",
13610                          unformat_ip6_address, &local6))
13611         {
13612           local_set = 1;
13613           ipv6_set = 1;
13614         }
13615       else if (unformat (line_input, "remote %U",
13616                          unformat_ip6_address, &remote6))
13617         {
13618           remote_set = 1;
13619           ipv6_set = 1;
13620         }
13621       else if (unformat (line_input, "group %U %U",
13622                          unformat_ip4_address, &remote4,
13623                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13624         {
13625           grp_set = remote_set = 1;
13626           ipv4_set = 1;
13627         }
13628       else if (unformat (line_input, "group %U",
13629                          unformat_ip4_address, &remote4))
13630         {
13631           grp_set = remote_set = 1;
13632           ipv4_set = 1;
13633         }
13634       else if (unformat (line_input, "group %U %U",
13635                          unformat_ip6_address, &remote6,
13636                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13637         {
13638           grp_set = remote_set = 1;
13639           ipv6_set = 1;
13640         }
13641       else if (unformat (line_input, "group %U",
13642                          unformat_ip6_address, &remote6))
13643         {
13644           grp_set = remote_set = 1;
13645           ipv6_set = 1;
13646         }
13647       else
13648         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13649         ;
13650       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13651         ;
13652       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13653         ;
13654       else if (unformat (line_input, "vni %d", &vni))
13655         vni_set = 1;
13656       else if (unformat (line_input, "next-ip4"))
13657         protocol = 1;
13658       else if (unformat (line_input, "next-ip6"))
13659         protocol = 2;
13660       else if (unformat (line_input, "next-ethernet"))
13661         protocol = 3;
13662       else if (unformat (line_input, "next-nsh"))
13663         protocol = 4;
13664       else
13665         {
13666           errmsg ("parse error '%U'", format_unformat_error, line_input);
13667           return -99;
13668         }
13669     }
13670
13671   if (local_set == 0)
13672     {
13673       errmsg ("tunnel local address not specified");
13674       return -99;
13675     }
13676   if (remote_set == 0)
13677     {
13678       errmsg ("tunnel remote address not specified");
13679       return -99;
13680     }
13681   if (grp_set && mcast_sw_if_index == ~0)
13682     {
13683       errmsg ("tunnel nonexistent multicast device");
13684       return -99;
13685     }
13686   if (ipv4_set && ipv6_set)
13687     {
13688       errmsg ("both IPv4 and IPv6 addresses specified");
13689       return -99;
13690     }
13691
13692   if (vni_set == 0)
13693     {
13694       errmsg ("vni not specified");
13695       return -99;
13696     }
13697
13698   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13699
13700
13701   if (ipv6_set)
13702     {
13703       clib_memcpy (&mp->local, &local6, sizeof (local6));
13704       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13705     }
13706   else
13707     {
13708       clib_memcpy (&mp->local, &local4, sizeof (local4));
13709       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13710     }
13711
13712   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13713   mp->encap_vrf_id = ntohl (encap_vrf_id);
13714   mp->decap_vrf_id = ntohl (decap_vrf_id);
13715   mp->protocol = protocol;
13716   mp->vni = ntohl (vni);
13717   mp->is_add = is_add;
13718   mp->is_ipv6 = ipv6_set;
13719
13720   S (mp);
13721   W (ret);
13722   return ret;
13723 }
13724
13725 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13726   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13727 {
13728   vat_main_t *vam = &vat_main;
13729   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13730   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13731
13732   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13733          ntohl (mp->sw_if_index),
13734          format_ip46_address, &local, IP46_TYPE_ANY,
13735          format_ip46_address, &remote, IP46_TYPE_ANY,
13736          ntohl (mp->vni), mp->protocol,
13737          ntohl (mp->mcast_sw_if_index),
13738          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13739 }
13740
13741
13742 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13743   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13744 {
13745   vat_main_t *vam = &vat_main;
13746   vat_json_node_t *node = NULL;
13747   struct in_addr ip4;
13748   struct in6_addr ip6;
13749
13750   if (VAT_JSON_ARRAY != vam->json_tree.type)
13751     {
13752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13753       vat_json_init_array (&vam->json_tree);
13754     }
13755   node = vat_json_array_add (&vam->json_tree);
13756
13757   vat_json_init_object (node);
13758   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13759   if (mp->is_ipv6)
13760     {
13761       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13762       vat_json_object_add_ip6 (node, "local", ip6);
13763       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13764       vat_json_object_add_ip6 (node, "remote", ip6);
13765     }
13766   else
13767     {
13768       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13769       vat_json_object_add_ip4 (node, "local", ip4);
13770       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13771       vat_json_object_add_ip4 (node, "remote", ip4);
13772     }
13773   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13774   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13775   vat_json_object_add_uint (node, "mcast_sw_if_index",
13776                             ntohl (mp->mcast_sw_if_index));
13777   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13778   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13779   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13780 }
13781
13782 static int
13783 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13784 {
13785   unformat_input_t *i = vam->input;
13786   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13787   vl_api_control_ping_t *mp_ping;
13788   u32 sw_if_index;
13789   u8 sw_if_index_set = 0;
13790   int ret;
13791
13792   /* Parse args required to build the message */
13793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13794     {
13795       if (unformat (i, "sw_if_index %d", &sw_if_index))
13796         sw_if_index_set = 1;
13797       else
13798         break;
13799     }
13800
13801   if (sw_if_index_set == 0)
13802     {
13803       sw_if_index = ~0;
13804     }
13805
13806   if (!vam->json_output)
13807     {
13808       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13809              "sw_if_index", "local", "remote", "vni",
13810              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13811     }
13812
13813   /* Get list of vxlan-tunnel interfaces */
13814   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13815
13816   mp->sw_if_index = htonl (sw_if_index);
13817
13818   S (mp);
13819
13820   /* Use a control ping for synchronization */
13821   MPING (CONTROL_PING, mp_ping);
13822   S (mp_ping);
13823
13824   W (ret);
13825   return ret;
13826 }
13827
13828 static void vl_api_l2_fib_table_details_t_handler
13829   (vl_api_l2_fib_table_details_t * mp)
13830 {
13831   vat_main_t *vam = &vat_main;
13832
13833   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13834          "       %d       %d     %d",
13835          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13836          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13837          mp->bvi_mac);
13838 }
13839
13840 static void vl_api_l2_fib_table_details_t_handler_json
13841   (vl_api_l2_fib_table_details_t * mp)
13842 {
13843   vat_main_t *vam = &vat_main;
13844   vat_json_node_t *node = NULL;
13845
13846   if (VAT_JSON_ARRAY != vam->json_tree.type)
13847     {
13848       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13849       vat_json_init_array (&vam->json_tree);
13850     }
13851   node = vat_json_array_add (&vam->json_tree);
13852
13853   vat_json_init_object (node);
13854   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13855   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13856   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13857   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13858   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13859   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13860 }
13861
13862 static int
13863 api_l2_fib_table_dump (vat_main_t * vam)
13864 {
13865   unformat_input_t *i = vam->input;
13866   vl_api_l2_fib_table_dump_t *mp;
13867   vl_api_control_ping_t *mp_ping;
13868   u32 bd_id;
13869   u8 bd_id_set = 0;
13870   int ret;
13871
13872   /* Parse args required to build the message */
13873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13874     {
13875       if (unformat (i, "bd_id %d", &bd_id))
13876         bd_id_set = 1;
13877       else
13878         break;
13879     }
13880
13881   if (bd_id_set == 0)
13882     {
13883       errmsg ("missing bridge domain");
13884       return -99;
13885     }
13886
13887   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13888
13889   /* Get list of l2 fib entries */
13890   M (L2_FIB_TABLE_DUMP, mp);
13891
13892   mp->bd_id = ntohl (bd_id);
13893   S (mp);
13894
13895   /* Use a control ping for synchronization */
13896   MPING (CONTROL_PING, mp_ping);
13897   S (mp_ping);
13898
13899   W (ret);
13900   return ret;
13901 }
13902
13903
13904 static int
13905 api_interface_name_renumber (vat_main_t * vam)
13906 {
13907   unformat_input_t *line_input = vam->input;
13908   vl_api_interface_name_renumber_t *mp;
13909   u32 sw_if_index = ~0;
13910   u32 new_show_dev_instance = ~0;
13911   int ret;
13912
13913   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13916                     &sw_if_index))
13917         ;
13918       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13919         ;
13920       else if (unformat (line_input, "new_show_dev_instance %d",
13921                          &new_show_dev_instance))
13922         ;
13923       else
13924         break;
13925     }
13926
13927   if (sw_if_index == ~0)
13928     {
13929       errmsg ("missing interface name or sw_if_index");
13930       return -99;
13931     }
13932
13933   if (new_show_dev_instance == ~0)
13934     {
13935       errmsg ("missing new_show_dev_instance");
13936       return -99;
13937     }
13938
13939   M (INTERFACE_NAME_RENUMBER, mp);
13940
13941   mp->sw_if_index = ntohl (sw_if_index);
13942   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13943
13944   S (mp);
13945   W (ret);
13946   return ret;
13947 }
13948
13949 static int
13950 api_want_ip4_arp_events (vat_main_t * vam)
13951 {
13952   unformat_input_t *line_input = vam->input;
13953   vl_api_want_ip4_arp_events_t *mp;
13954   ip4_address_t address;
13955   int address_set = 0;
13956   u32 enable_disable = 1;
13957   int ret;
13958
13959   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13960     {
13961       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13962         address_set = 1;
13963       else if (unformat (line_input, "del"))
13964         enable_disable = 0;
13965       else
13966         break;
13967     }
13968
13969   if (address_set == 0)
13970     {
13971       errmsg ("missing addresses");
13972       return -99;
13973     }
13974
13975   M (WANT_IP4_ARP_EVENTS, mp);
13976   mp->enable_disable = enable_disable;
13977   mp->pid = htonl (getpid ());
13978   mp->address = address.as_u32;
13979
13980   S (mp);
13981   W (ret);
13982   return ret;
13983 }
13984
13985 static int
13986 api_want_ip6_nd_events (vat_main_t * vam)
13987 {
13988   unformat_input_t *line_input = vam->input;
13989   vl_api_want_ip6_nd_events_t *mp;
13990   ip6_address_t address;
13991   int address_set = 0;
13992   u32 enable_disable = 1;
13993   int ret;
13994
13995   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13996     {
13997       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13998         address_set = 1;
13999       else if (unformat (line_input, "del"))
14000         enable_disable = 0;
14001       else
14002         break;
14003     }
14004
14005   if (address_set == 0)
14006     {
14007       errmsg ("missing addresses");
14008       return -99;
14009     }
14010
14011   M (WANT_IP6_ND_EVENTS, mp);
14012   mp->enable_disable = enable_disable;
14013   mp->pid = htonl (getpid ());
14014   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14015
14016   S (mp);
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static int
14022 api_want_l2_macs_events (vat_main_t * vam)
14023 {
14024   unformat_input_t *line_input = vam->input;
14025   vl_api_want_l2_macs_events_t *mp;
14026   u8 enable_disable = 1;
14027   u32 scan_delay = 0;
14028   u32 max_macs_in_event = 0;
14029   u32 learn_limit = 0;
14030   int ret;
14031
14032   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14033     {
14034       if (unformat (line_input, "learn-limit %d", &learn_limit))
14035         ;
14036       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14037         ;
14038       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14039         ;
14040       else if (unformat (line_input, "disable"))
14041         enable_disable = 0;
14042       else
14043         break;
14044     }
14045
14046   M (WANT_L2_MACS_EVENTS, mp);
14047   mp->enable_disable = enable_disable;
14048   mp->pid = htonl (getpid ());
14049   mp->learn_limit = htonl (learn_limit);
14050   mp->scan_delay = (u8) scan_delay;
14051   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14052   S (mp);
14053   W (ret);
14054   return ret;
14055 }
14056
14057 static int
14058 api_input_acl_set_interface (vat_main_t * vam)
14059 {
14060   unformat_input_t *i = vam->input;
14061   vl_api_input_acl_set_interface_t *mp;
14062   u32 sw_if_index;
14063   int sw_if_index_set;
14064   u32 ip4_table_index = ~0;
14065   u32 ip6_table_index = ~0;
14066   u32 l2_table_index = ~0;
14067   u8 is_add = 1;
14068   int ret;
14069
14070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14071     {
14072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14073         sw_if_index_set = 1;
14074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14075         sw_if_index_set = 1;
14076       else if (unformat (i, "del"))
14077         is_add = 0;
14078       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14079         ;
14080       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14081         ;
14082       else if (unformat (i, "l2-table %d", &l2_table_index))
14083         ;
14084       else
14085         {
14086           clib_warning ("parse error '%U'", format_unformat_error, i);
14087           return -99;
14088         }
14089     }
14090
14091   if (sw_if_index_set == 0)
14092     {
14093       errmsg ("missing interface name or sw_if_index");
14094       return -99;
14095     }
14096
14097   M (INPUT_ACL_SET_INTERFACE, mp);
14098
14099   mp->sw_if_index = ntohl (sw_if_index);
14100   mp->ip4_table_index = ntohl (ip4_table_index);
14101   mp->ip6_table_index = ntohl (ip6_table_index);
14102   mp->l2_table_index = ntohl (l2_table_index);
14103   mp->is_add = is_add;
14104
14105   S (mp);
14106   W (ret);
14107   return ret;
14108 }
14109
14110 static int
14111 api_ip_address_dump (vat_main_t * vam)
14112 {
14113   unformat_input_t *i = vam->input;
14114   vl_api_ip_address_dump_t *mp;
14115   vl_api_control_ping_t *mp_ping;
14116   u32 sw_if_index = ~0;
14117   u8 sw_if_index_set = 0;
14118   u8 ipv4_set = 0;
14119   u8 ipv6_set = 0;
14120   int ret;
14121
14122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14123     {
14124       if (unformat (i, "sw_if_index %d", &sw_if_index))
14125         sw_if_index_set = 1;
14126       else
14127         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14128         sw_if_index_set = 1;
14129       else if (unformat (i, "ipv4"))
14130         ipv4_set = 1;
14131       else if (unformat (i, "ipv6"))
14132         ipv6_set = 1;
14133       else
14134         break;
14135     }
14136
14137   if (ipv4_set && ipv6_set)
14138     {
14139       errmsg ("ipv4 and ipv6 flags cannot be both set");
14140       return -99;
14141     }
14142
14143   if ((!ipv4_set) && (!ipv6_set))
14144     {
14145       errmsg ("no ipv4 nor ipv6 flag set");
14146       return -99;
14147     }
14148
14149   if (sw_if_index_set == 0)
14150     {
14151       errmsg ("missing interface name or sw_if_index");
14152       return -99;
14153     }
14154
14155   vam->current_sw_if_index = sw_if_index;
14156   vam->is_ipv6 = ipv6_set;
14157
14158   M (IP_ADDRESS_DUMP, mp);
14159   mp->sw_if_index = ntohl (sw_if_index);
14160   mp->is_ipv6 = ipv6_set;
14161   S (mp);
14162
14163   /* Use a control ping for synchronization */
14164   MPING (CONTROL_PING, mp_ping);
14165   S (mp_ping);
14166
14167   W (ret);
14168   return ret;
14169 }
14170
14171 static int
14172 api_ip_dump (vat_main_t * vam)
14173 {
14174   vl_api_ip_dump_t *mp;
14175   vl_api_control_ping_t *mp_ping;
14176   unformat_input_t *in = vam->input;
14177   int ipv4_set = 0;
14178   int ipv6_set = 0;
14179   int is_ipv6;
14180   int i;
14181   int ret;
14182
14183   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14184     {
14185       if (unformat (in, "ipv4"))
14186         ipv4_set = 1;
14187       else if (unformat (in, "ipv6"))
14188         ipv6_set = 1;
14189       else
14190         break;
14191     }
14192
14193   if (ipv4_set && ipv6_set)
14194     {
14195       errmsg ("ipv4 and ipv6 flags cannot be both set");
14196       return -99;
14197     }
14198
14199   if ((!ipv4_set) && (!ipv6_set))
14200     {
14201       errmsg ("no ipv4 nor ipv6 flag set");
14202       return -99;
14203     }
14204
14205   is_ipv6 = ipv6_set;
14206   vam->is_ipv6 = is_ipv6;
14207
14208   /* free old data */
14209   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14210     {
14211       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14212     }
14213   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14214
14215   M (IP_DUMP, mp);
14216   mp->is_ipv6 = ipv6_set;
14217   S (mp);
14218
14219   /* Use a control ping for synchronization */
14220   MPING (CONTROL_PING, mp_ping);
14221   S (mp_ping);
14222
14223   W (ret);
14224   return ret;
14225 }
14226
14227 static int
14228 api_ipsec_spd_add_del (vat_main_t * vam)
14229 {
14230   unformat_input_t *i = vam->input;
14231   vl_api_ipsec_spd_add_del_t *mp;
14232   u32 spd_id = ~0;
14233   u8 is_add = 1;
14234   int ret;
14235
14236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14237     {
14238       if (unformat (i, "spd_id %d", &spd_id))
14239         ;
14240       else if (unformat (i, "del"))
14241         is_add = 0;
14242       else
14243         {
14244           clib_warning ("parse error '%U'", format_unformat_error, i);
14245           return -99;
14246         }
14247     }
14248   if (spd_id == ~0)
14249     {
14250       errmsg ("spd_id must be set");
14251       return -99;
14252     }
14253
14254   M (IPSEC_SPD_ADD_DEL, mp);
14255
14256   mp->spd_id = ntohl (spd_id);
14257   mp->is_add = is_add;
14258
14259   S (mp);
14260   W (ret);
14261   return ret;
14262 }
14263
14264 static int
14265 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14266 {
14267   unformat_input_t *i = vam->input;
14268   vl_api_ipsec_interface_add_del_spd_t *mp;
14269   u32 sw_if_index;
14270   u8 sw_if_index_set = 0;
14271   u32 spd_id = (u32) ~ 0;
14272   u8 is_add = 1;
14273   int ret;
14274
14275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14276     {
14277       if (unformat (i, "del"))
14278         is_add = 0;
14279       else if (unformat (i, "spd_id %d", &spd_id))
14280         ;
14281       else
14282         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14283         sw_if_index_set = 1;
14284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14285         sw_if_index_set = 1;
14286       else
14287         {
14288           clib_warning ("parse error '%U'", format_unformat_error, i);
14289           return -99;
14290         }
14291
14292     }
14293
14294   if (spd_id == (u32) ~ 0)
14295     {
14296       errmsg ("spd_id must be set");
14297       return -99;
14298     }
14299
14300   if (sw_if_index_set == 0)
14301     {
14302       errmsg ("missing interface name or sw_if_index");
14303       return -99;
14304     }
14305
14306   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14307
14308   mp->spd_id = ntohl (spd_id);
14309   mp->sw_if_index = ntohl (sw_if_index);
14310   mp->is_add = is_add;
14311
14312   S (mp);
14313   W (ret);
14314   return ret;
14315 }
14316
14317 static int
14318 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14319 {
14320   unformat_input_t *i = vam->input;
14321   vl_api_ipsec_spd_add_del_entry_t *mp;
14322   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14323   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14324   i32 priority = 0;
14325   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14326   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14327   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14328   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14329   int ret;
14330
14331   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14332   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14333   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14334   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14335   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14336   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14337
14338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (i, "del"))
14341         is_add = 0;
14342       if (unformat (i, "outbound"))
14343         is_outbound = 1;
14344       if (unformat (i, "inbound"))
14345         is_outbound = 0;
14346       else if (unformat (i, "spd_id %d", &spd_id))
14347         ;
14348       else if (unformat (i, "sa_id %d", &sa_id))
14349         ;
14350       else if (unformat (i, "priority %d", &priority))
14351         ;
14352       else if (unformat (i, "protocol %d", &protocol))
14353         ;
14354       else if (unformat (i, "lport_start %d", &lport_start))
14355         ;
14356       else if (unformat (i, "lport_stop %d", &lport_stop))
14357         ;
14358       else if (unformat (i, "rport_start %d", &rport_start))
14359         ;
14360       else if (unformat (i, "rport_stop %d", &rport_stop))
14361         ;
14362       else
14363         if (unformat
14364             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14365         {
14366           is_ipv6 = 0;
14367           is_ip_any = 0;
14368         }
14369       else
14370         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14371         {
14372           is_ipv6 = 0;
14373           is_ip_any = 0;
14374         }
14375       else
14376         if (unformat
14377             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14378         {
14379           is_ipv6 = 0;
14380           is_ip_any = 0;
14381         }
14382       else
14383         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14384         {
14385           is_ipv6 = 0;
14386           is_ip_any = 0;
14387         }
14388       else
14389         if (unformat
14390             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14391         {
14392           is_ipv6 = 1;
14393           is_ip_any = 0;
14394         }
14395       else
14396         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14397         {
14398           is_ipv6 = 1;
14399           is_ip_any = 0;
14400         }
14401       else
14402         if (unformat
14403             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14404         {
14405           is_ipv6 = 1;
14406           is_ip_any = 0;
14407         }
14408       else
14409         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14410         {
14411           is_ipv6 = 1;
14412           is_ip_any = 0;
14413         }
14414       else
14415         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14416         {
14417           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14418             {
14419               clib_warning ("unsupported action: 'resolve'");
14420               return -99;
14421             }
14422         }
14423       else
14424         {
14425           clib_warning ("parse error '%U'", format_unformat_error, i);
14426           return -99;
14427         }
14428
14429     }
14430
14431   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14432
14433   mp->spd_id = ntohl (spd_id);
14434   mp->priority = ntohl (priority);
14435   mp->is_outbound = is_outbound;
14436
14437   mp->is_ipv6 = is_ipv6;
14438   if (is_ipv6 || is_ip_any)
14439     {
14440       clib_memcpy (mp->remote_address_start, &raddr6_start,
14441                    sizeof (ip6_address_t));
14442       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14443                    sizeof (ip6_address_t));
14444       clib_memcpy (mp->local_address_start, &laddr6_start,
14445                    sizeof (ip6_address_t));
14446       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14447                    sizeof (ip6_address_t));
14448     }
14449   else
14450     {
14451       clib_memcpy (mp->remote_address_start, &raddr4_start,
14452                    sizeof (ip4_address_t));
14453       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14454                    sizeof (ip4_address_t));
14455       clib_memcpy (mp->local_address_start, &laddr4_start,
14456                    sizeof (ip4_address_t));
14457       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14458                    sizeof (ip4_address_t));
14459     }
14460   mp->protocol = (u8) protocol;
14461   mp->local_port_start = ntohs ((u16) lport_start);
14462   mp->local_port_stop = ntohs ((u16) lport_stop);
14463   mp->remote_port_start = ntohs ((u16) rport_start);
14464   mp->remote_port_stop = ntohs ((u16) rport_stop);
14465   mp->policy = (u8) policy;
14466   mp->sa_id = ntohl (sa_id);
14467   mp->is_add = is_add;
14468   mp->is_ip_any = is_ip_any;
14469   S (mp);
14470   W (ret);
14471   return ret;
14472 }
14473
14474 static int
14475 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14476 {
14477   unformat_input_t *i = vam->input;
14478   vl_api_ipsec_sad_add_del_entry_t *mp;
14479   u32 sad_id = 0, spi = 0;
14480   u8 *ck = 0, *ik = 0;
14481   u8 is_add = 1;
14482
14483   u8 protocol = IPSEC_PROTOCOL_AH;
14484   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14485   u32 crypto_alg = 0, integ_alg = 0;
14486   ip4_address_t tun_src4;
14487   ip4_address_t tun_dst4;
14488   ip6_address_t tun_src6;
14489   ip6_address_t tun_dst6;
14490   int ret;
14491
14492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14493     {
14494       if (unformat (i, "del"))
14495         is_add = 0;
14496       else if (unformat (i, "sad_id %d", &sad_id))
14497         ;
14498       else if (unformat (i, "spi %d", &spi))
14499         ;
14500       else if (unformat (i, "esp"))
14501         protocol = IPSEC_PROTOCOL_ESP;
14502       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14503         {
14504           is_tunnel = 1;
14505           is_tunnel_ipv6 = 0;
14506         }
14507       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14508         {
14509           is_tunnel = 1;
14510           is_tunnel_ipv6 = 0;
14511         }
14512       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14513         {
14514           is_tunnel = 1;
14515           is_tunnel_ipv6 = 1;
14516         }
14517       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14518         {
14519           is_tunnel = 1;
14520           is_tunnel_ipv6 = 1;
14521         }
14522       else
14523         if (unformat
14524             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14525         {
14526           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14527               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14528             {
14529               clib_warning ("unsupported crypto-alg: '%U'",
14530                             format_ipsec_crypto_alg, crypto_alg);
14531               return -99;
14532             }
14533         }
14534       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14535         ;
14536       else
14537         if (unformat
14538             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14539         {
14540           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14541               integ_alg >= IPSEC_INTEG_N_ALG)
14542             {
14543               clib_warning ("unsupported integ-alg: '%U'",
14544                             format_ipsec_integ_alg, integ_alg);
14545               return -99;
14546             }
14547         }
14548       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14549         ;
14550       else
14551         {
14552           clib_warning ("parse error '%U'", format_unformat_error, i);
14553           return -99;
14554         }
14555
14556     }
14557
14558   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14559
14560   mp->sad_id = ntohl (sad_id);
14561   mp->is_add = is_add;
14562   mp->protocol = protocol;
14563   mp->spi = ntohl (spi);
14564   mp->is_tunnel = is_tunnel;
14565   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14566   mp->crypto_algorithm = crypto_alg;
14567   mp->integrity_algorithm = integ_alg;
14568   mp->crypto_key_length = vec_len (ck);
14569   mp->integrity_key_length = vec_len (ik);
14570
14571   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14572     mp->crypto_key_length = sizeof (mp->crypto_key);
14573
14574   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14575     mp->integrity_key_length = sizeof (mp->integrity_key);
14576
14577   if (ck)
14578     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14579   if (ik)
14580     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14581
14582   if (is_tunnel)
14583     {
14584       if (is_tunnel_ipv6)
14585         {
14586           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14587                        sizeof (ip6_address_t));
14588           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14589                        sizeof (ip6_address_t));
14590         }
14591       else
14592         {
14593           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14594                        sizeof (ip4_address_t));
14595           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14596                        sizeof (ip4_address_t));
14597         }
14598     }
14599
14600   S (mp);
14601   W (ret);
14602   return ret;
14603 }
14604
14605 static int
14606 api_ipsec_sa_set_key (vat_main_t * vam)
14607 {
14608   unformat_input_t *i = vam->input;
14609   vl_api_ipsec_sa_set_key_t *mp;
14610   u32 sa_id;
14611   u8 *ck = 0, *ik = 0;
14612   int ret;
14613
14614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14615     {
14616       if (unformat (i, "sa_id %d", &sa_id))
14617         ;
14618       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14619         ;
14620       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14621         ;
14622       else
14623         {
14624           clib_warning ("parse error '%U'", format_unformat_error, i);
14625           return -99;
14626         }
14627     }
14628
14629   M (IPSEC_SA_SET_KEY, mp);
14630
14631   mp->sa_id = ntohl (sa_id);
14632   mp->crypto_key_length = vec_len (ck);
14633   mp->integrity_key_length = vec_len (ik);
14634
14635   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14636     mp->crypto_key_length = sizeof (mp->crypto_key);
14637
14638   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14639     mp->integrity_key_length = sizeof (mp->integrity_key);
14640
14641   if (ck)
14642     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14643   if (ik)
14644     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14645
14646   S (mp);
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14653 {
14654   unformat_input_t *i = vam->input;
14655   vl_api_ipsec_tunnel_if_add_del_t *mp;
14656   u32 local_spi = 0, remote_spi = 0;
14657   u32 crypto_alg = 0, integ_alg = 0;
14658   u8 *lck = NULL, *rck = NULL;
14659   u8 *lik = NULL, *rik = NULL;
14660   ip4_address_t local_ip = { {0} };
14661   ip4_address_t remote_ip = { {0} };
14662   u8 is_add = 1;
14663   u8 esn = 0;
14664   u8 anti_replay = 0;
14665   int ret;
14666
14667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14668     {
14669       if (unformat (i, "del"))
14670         is_add = 0;
14671       else if (unformat (i, "esn"))
14672         esn = 1;
14673       else if (unformat (i, "anti_replay"))
14674         anti_replay = 1;
14675       else if (unformat (i, "local_spi %d", &local_spi))
14676         ;
14677       else if (unformat (i, "remote_spi %d", &remote_spi))
14678         ;
14679       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14680         ;
14681       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14682         ;
14683       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14684         ;
14685       else
14686         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14687         ;
14688       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14689         ;
14690       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14691         ;
14692       else
14693         if (unformat
14694             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14695         {
14696           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14697               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14698             {
14699               errmsg ("unsupported crypto-alg: '%U'\n",
14700                       format_ipsec_crypto_alg, crypto_alg);
14701               return -99;
14702             }
14703         }
14704       else
14705         if (unformat
14706             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14707         {
14708           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14709               integ_alg >= IPSEC_INTEG_N_ALG)
14710             {
14711               errmsg ("unsupported integ-alg: '%U'\n",
14712                       format_ipsec_integ_alg, integ_alg);
14713               return -99;
14714             }
14715         }
14716       else
14717         {
14718           errmsg ("parse error '%U'\n", format_unformat_error, i);
14719           return -99;
14720         }
14721     }
14722
14723   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14724
14725   mp->is_add = is_add;
14726   mp->esn = esn;
14727   mp->anti_replay = anti_replay;
14728
14729   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14730   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14731
14732   mp->local_spi = htonl (local_spi);
14733   mp->remote_spi = htonl (remote_spi);
14734   mp->crypto_alg = (u8) crypto_alg;
14735
14736   mp->local_crypto_key_len = 0;
14737   if (lck)
14738     {
14739       mp->local_crypto_key_len = vec_len (lck);
14740       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14741         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14742       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14743     }
14744
14745   mp->remote_crypto_key_len = 0;
14746   if (rck)
14747     {
14748       mp->remote_crypto_key_len = vec_len (rck);
14749       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14750         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14751       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14752     }
14753
14754   mp->integ_alg = (u8) integ_alg;
14755
14756   mp->local_integ_key_len = 0;
14757   if (lik)
14758     {
14759       mp->local_integ_key_len = vec_len (lik);
14760       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14761         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14762       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14763     }
14764
14765   mp->remote_integ_key_len = 0;
14766   if (rik)
14767     {
14768       mp->remote_integ_key_len = vec_len (rik);
14769       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14770         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14771       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14772     }
14773
14774   S (mp);
14775   W (ret);
14776   return ret;
14777 }
14778
14779 static void
14780 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14781 {
14782   vat_main_t *vam = &vat_main;
14783
14784   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14785          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14786          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14787          "tunnel_src_addr %U tunnel_dst_addr %U "
14788          "salt %u seq_outbound %lu last_seq_inbound %lu "
14789          "replay_window %lu total_data_size %lu\n",
14790          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14791          mp->protocol,
14792          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14793          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14794          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14795          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14796          mp->tunnel_src_addr,
14797          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14798          mp->tunnel_dst_addr,
14799          ntohl (mp->salt),
14800          clib_net_to_host_u64 (mp->seq_outbound),
14801          clib_net_to_host_u64 (mp->last_seq_inbound),
14802          clib_net_to_host_u64 (mp->replay_window),
14803          clib_net_to_host_u64 (mp->total_data_size));
14804 }
14805
14806 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14807 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14808
14809 static void vl_api_ipsec_sa_details_t_handler_json
14810   (vl_api_ipsec_sa_details_t * mp)
14811 {
14812   vat_main_t *vam = &vat_main;
14813   vat_json_node_t *node = NULL;
14814   struct in_addr src_ip4, dst_ip4;
14815   struct in6_addr src_ip6, dst_ip6;
14816
14817   if (VAT_JSON_ARRAY != vam->json_tree.type)
14818     {
14819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14820       vat_json_init_array (&vam->json_tree);
14821     }
14822   node = vat_json_array_add (&vam->json_tree);
14823
14824   vat_json_init_object (node);
14825   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14826   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14827   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14828   vat_json_object_add_uint (node, "proto", mp->protocol);
14829   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14830   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14831   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14832   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14833   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14834   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14835   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14836                              mp->crypto_key_len);
14837   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14838                              mp->integ_key_len);
14839   if (mp->is_tunnel_ip6)
14840     {
14841       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14842       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14843       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14844       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14845     }
14846   else
14847     {
14848       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14849       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14850       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14851       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14852     }
14853   vat_json_object_add_uint (node, "replay_window",
14854                             clib_net_to_host_u64 (mp->replay_window));
14855   vat_json_object_add_uint (node, "total_data_size",
14856                             clib_net_to_host_u64 (mp->total_data_size));
14857
14858 }
14859
14860 static int
14861 api_ipsec_sa_dump (vat_main_t * vam)
14862 {
14863   unformat_input_t *i = vam->input;
14864   vl_api_ipsec_sa_dump_t *mp;
14865   vl_api_control_ping_t *mp_ping;
14866   u32 sa_id = ~0;
14867   int ret;
14868
14869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14870     {
14871       if (unformat (i, "sa_id %d", &sa_id))
14872         ;
14873       else
14874         {
14875           clib_warning ("parse error '%U'", format_unformat_error, i);
14876           return -99;
14877         }
14878     }
14879
14880   M (IPSEC_SA_DUMP, mp);
14881
14882   mp->sa_id = ntohl (sa_id);
14883
14884   S (mp);
14885
14886   /* Use a control ping for synchronization */
14887   M (CONTROL_PING, mp_ping);
14888   S (mp_ping);
14889
14890   W (ret);
14891   return ret;
14892 }
14893
14894 static int
14895 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14896 {
14897   unformat_input_t *i = vam->input;
14898   vl_api_ipsec_tunnel_if_set_key_t *mp;
14899   u32 sw_if_index = ~0;
14900   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14901   u8 *key = 0;
14902   u32 alg = ~0;
14903   int ret;
14904
14905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14908         ;
14909       else
14910         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14911         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14912       else
14913         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14914         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14915       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14916         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14917       else
14918         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14919         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14920       else if (unformat (i, "%U", unformat_hex_string, &key))
14921         ;
14922       else
14923         {
14924           clib_warning ("parse error '%U'", format_unformat_error, i);
14925           return -99;
14926         }
14927     }
14928
14929   if (sw_if_index == ~0)
14930     {
14931       errmsg ("interface must be specified");
14932       return -99;
14933     }
14934
14935   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14936     {
14937       errmsg ("key type must be specified");
14938       return -99;
14939     }
14940
14941   if (alg == ~0)
14942     {
14943       errmsg ("algorithm must be specified");
14944       return -99;
14945     }
14946
14947   if (vec_len (key) == 0)
14948     {
14949       errmsg ("key must be specified");
14950       return -99;
14951     }
14952
14953   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14954
14955   mp->sw_if_index = htonl (sw_if_index);
14956   mp->alg = alg;
14957   mp->key_type = key_type;
14958   mp->key_len = vec_len (key);
14959   clib_memcpy (mp->key, key, vec_len (key));
14960
14961   S (mp);
14962   W (ret);
14963
14964   return ret;
14965 }
14966
14967 static int
14968 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14969 {
14970   unformat_input_t *i = vam->input;
14971   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14972   u32 sw_if_index = ~0;
14973   u32 sa_id = ~0;
14974   u8 is_outbound = (u8) ~ 0;
14975   int ret;
14976
14977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14980         ;
14981       else if (unformat (i, "sa_id %d", &sa_id))
14982         ;
14983       else if (unformat (i, "outbound"))
14984         is_outbound = 1;
14985       else if (unformat (i, "inbound"))
14986         is_outbound = 0;
14987       else
14988         {
14989           clib_warning ("parse error '%U'", format_unformat_error, i);
14990           return -99;
14991         }
14992     }
14993
14994   if (sw_if_index == ~0)
14995     {
14996       errmsg ("interface must be specified");
14997       return -99;
14998     }
14999
15000   if (sa_id == ~0)
15001     {
15002       errmsg ("SA ID must be specified");
15003       return -99;
15004     }
15005
15006   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15007
15008   mp->sw_if_index = htonl (sw_if_index);
15009   mp->sa_id = htonl (sa_id);
15010   mp->is_outbound = is_outbound;
15011
15012   S (mp);
15013   W (ret);
15014
15015   return ret;
15016 }
15017
15018 static int
15019 api_ikev2_profile_add_del (vat_main_t * vam)
15020 {
15021   unformat_input_t *i = vam->input;
15022   vl_api_ikev2_profile_add_del_t *mp;
15023   u8 is_add = 1;
15024   u8 *name = 0;
15025   int ret;
15026
15027   const char *valid_chars = "a-zA-Z0-9_";
15028
15029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15030     {
15031       if (unformat (i, "del"))
15032         is_add = 0;
15033       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15034         vec_add1 (name, 0);
15035       else
15036         {
15037           errmsg ("parse error '%U'", format_unformat_error, i);
15038           return -99;
15039         }
15040     }
15041
15042   if (!vec_len (name))
15043     {
15044       errmsg ("profile name must be specified");
15045       return -99;
15046     }
15047
15048   if (vec_len (name) > 64)
15049     {
15050       errmsg ("profile name too long");
15051       return -99;
15052     }
15053
15054   M (IKEV2_PROFILE_ADD_DEL, mp);
15055
15056   clib_memcpy (mp->name, name, vec_len (name));
15057   mp->is_add = is_add;
15058   vec_free (name);
15059
15060   S (mp);
15061   W (ret);
15062   return ret;
15063 }
15064
15065 static int
15066 api_ikev2_profile_set_auth (vat_main_t * vam)
15067 {
15068   unformat_input_t *i = vam->input;
15069   vl_api_ikev2_profile_set_auth_t *mp;
15070   u8 *name = 0;
15071   u8 *data = 0;
15072   u32 auth_method = 0;
15073   u8 is_hex = 0;
15074   int ret;
15075
15076   const char *valid_chars = "a-zA-Z0-9_";
15077
15078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15081         vec_add1 (name, 0);
15082       else if (unformat (i, "auth_method %U",
15083                          unformat_ikev2_auth_method, &auth_method))
15084         ;
15085       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15086         is_hex = 1;
15087       else if (unformat (i, "auth_data %v", &data))
15088         ;
15089       else
15090         {
15091           errmsg ("parse error '%U'", format_unformat_error, i);
15092           return -99;
15093         }
15094     }
15095
15096   if (!vec_len (name))
15097     {
15098       errmsg ("profile name must be specified");
15099       return -99;
15100     }
15101
15102   if (vec_len (name) > 64)
15103     {
15104       errmsg ("profile name too long");
15105       return -99;
15106     }
15107
15108   if (!vec_len (data))
15109     {
15110       errmsg ("auth_data must be specified");
15111       return -99;
15112     }
15113
15114   if (!auth_method)
15115     {
15116       errmsg ("auth_method must be specified");
15117       return -99;
15118     }
15119
15120   M (IKEV2_PROFILE_SET_AUTH, mp);
15121
15122   mp->is_hex = is_hex;
15123   mp->auth_method = (u8) auth_method;
15124   mp->data_len = vec_len (data);
15125   clib_memcpy (mp->name, name, vec_len (name));
15126   clib_memcpy (mp->data, data, vec_len (data));
15127   vec_free (name);
15128   vec_free (data);
15129
15130   S (mp);
15131   W (ret);
15132   return ret;
15133 }
15134
15135 static int
15136 api_ikev2_profile_set_id (vat_main_t * vam)
15137 {
15138   unformat_input_t *i = vam->input;
15139   vl_api_ikev2_profile_set_id_t *mp;
15140   u8 *name = 0;
15141   u8 *data = 0;
15142   u8 is_local = 0;
15143   u32 id_type = 0;
15144   ip4_address_t ip4;
15145   int ret;
15146
15147   const char *valid_chars = "a-zA-Z0-9_";
15148
15149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15150     {
15151       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15152         vec_add1 (name, 0);
15153       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15154         ;
15155       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15156         {
15157           data = vec_new (u8, 4);
15158           clib_memcpy (data, ip4.as_u8, 4);
15159         }
15160       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15161         ;
15162       else if (unformat (i, "id_data %v", &data))
15163         ;
15164       else if (unformat (i, "local"))
15165         is_local = 1;
15166       else if (unformat (i, "remote"))
15167         is_local = 0;
15168       else
15169         {
15170           errmsg ("parse error '%U'", format_unformat_error, i);
15171           return -99;
15172         }
15173     }
15174
15175   if (!vec_len (name))
15176     {
15177       errmsg ("profile name must be specified");
15178       return -99;
15179     }
15180
15181   if (vec_len (name) > 64)
15182     {
15183       errmsg ("profile name too long");
15184       return -99;
15185     }
15186
15187   if (!vec_len (data))
15188     {
15189       errmsg ("id_data must be specified");
15190       return -99;
15191     }
15192
15193   if (!id_type)
15194     {
15195       errmsg ("id_type must be specified");
15196       return -99;
15197     }
15198
15199   M (IKEV2_PROFILE_SET_ID, mp);
15200
15201   mp->is_local = is_local;
15202   mp->id_type = (u8) id_type;
15203   mp->data_len = vec_len (data);
15204   clib_memcpy (mp->name, name, vec_len (name));
15205   clib_memcpy (mp->data, data, vec_len (data));
15206   vec_free (name);
15207   vec_free (data);
15208
15209   S (mp);
15210   W (ret);
15211   return ret;
15212 }
15213
15214 static int
15215 api_ikev2_profile_set_ts (vat_main_t * vam)
15216 {
15217   unformat_input_t *i = vam->input;
15218   vl_api_ikev2_profile_set_ts_t *mp;
15219   u8 *name = 0;
15220   u8 is_local = 0;
15221   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15222   ip4_address_t start_addr, end_addr;
15223
15224   const char *valid_chars = "a-zA-Z0-9_";
15225   int ret;
15226
15227   start_addr.as_u32 = 0;
15228   end_addr.as_u32 = (u32) ~ 0;
15229
15230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15233         vec_add1 (name, 0);
15234       else if (unformat (i, "protocol %d", &proto))
15235         ;
15236       else if (unformat (i, "start_port %d", &start_port))
15237         ;
15238       else if (unformat (i, "end_port %d", &end_port))
15239         ;
15240       else
15241         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15242         ;
15243       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15244         ;
15245       else if (unformat (i, "local"))
15246         is_local = 1;
15247       else if (unformat (i, "remote"))
15248         is_local = 0;
15249       else
15250         {
15251           errmsg ("parse error '%U'", format_unformat_error, i);
15252           return -99;
15253         }
15254     }
15255
15256   if (!vec_len (name))
15257     {
15258       errmsg ("profile name must be specified");
15259       return -99;
15260     }
15261
15262   if (vec_len (name) > 64)
15263     {
15264       errmsg ("profile name too long");
15265       return -99;
15266     }
15267
15268   M (IKEV2_PROFILE_SET_TS, mp);
15269
15270   mp->is_local = is_local;
15271   mp->proto = (u8) proto;
15272   mp->start_port = (u16) start_port;
15273   mp->end_port = (u16) end_port;
15274   mp->start_addr = start_addr.as_u32;
15275   mp->end_addr = end_addr.as_u32;
15276   clib_memcpy (mp->name, name, vec_len (name));
15277   vec_free (name);
15278
15279   S (mp);
15280   W (ret);
15281   return ret;
15282 }
15283
15284 static int
15285 api_ikev2_set_local_key (vat_main_t * vam)
15286 {
15287   unformat_input_t *i = vam->input;
15288   vl_api_ikev2_set_local_key_t *mp;
15289   u8 *file = 0;
15290   int ret;
15291
15292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15293     {
15294       if (unformat (i, "file %v", &file))
15295         vec_add1 (file, 0);
15296       else
15297         {
15298           errmsg ("parse error '%U'", format_unformat_error, i);
15299           return -99;
15300         }
15301     }
15302
15303   if (!vec_len (file))
15304     {
15305       errmsg ("RSA key file must be specified");
15306       return -99;
15307     }
15308
15309   if (vec_len (file) > 256)
15310     {
15311       errmsg ("file name too long");
15312       return -99;
15313     }
15314
15315   M (IKEV2_SET_LOCAL_KEY, mp);
15316
15317   clib_memcpy (mp->key_file, file, vec_len (file));
15318   vec_free (file);
15319
15320   S (mp);
15321   W (ret);
15322   return ret;
15323 }
15324
15325 static int
15326 api_ikev2_set_responder (vat_main_t * vam)
15327 {
15328   unformat_input_t *i = vam->input;
15329   vl_api_ikev2_set_responder_t *mp;
15330   int ret;
15331   u8 *name = 0;
15332   u32 sw_if_index = ~0;
15333   ip4_address_t address;
15334
15335   const char *valid_chars = "a-zA-Z0-9_";
15336
15337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15338     {
15339       if (unformat
15340           (i, "%U interface %d address %U", unformat_token, valid_chars,
15341            &name, &sw_if_index, unformat_ip4_address, &address))
15342         vec_add1 (name, 0);
15343       else
15344         {
15345           errmsg ("parse error '%U'", format_unformat_error, i);
15346           return -99;
15347         }
15348     }
15349
15350   if (!vec_len (name))
15351     {
15352       errmsg ("profile name must be specified");
15353       return -99;
15354     }
15355
15356   if (vec_len (name) > 64)
15357     {
15358       errmsg ("profile name too long");
15359       return -99;
15360     }
15361
15362   M (IKEV2_SET_RESPONDER, mp);
15363
15364   clib_memcpy (mp->name, name, vec_len (name));
15365   vec_free (name);
15366
15367   mp->sw_if_index = sw_if_index;
15368   clib_memcpy (mp->address, &address, sizeof (address));
15369
15370   S (mp);
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static int
15376 api_ikev2_set_ike_transforms (vat_main_t * vam)
15377 {
15378   unformat_input_t *i = vam->input;
15379   vl_api_ikev2_set_ike_transforms_t *mp;
15380   int ret;
15381   u8 *name = 0;
15382   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15383
15384   const char *valid_chars = "a-zA-Z0-9_";
15385
15386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15387     {
15388       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15389                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15390         vec_add1 (name, 0);
15391       else
15392         {
15393           errmsg ("parse error '%U'", format_unformat_error, i);
15394           return -99;
15395         }
15396     }
15397
15398   if (!vec_len (name))
15399     {
15400       errmsg ("profile name must be specified");
15401       return -99;
15402     }
15403
15404   if (vec_len (name) > 64)
15405     {
15406       errmsg ("profile name too long");
15407       return -99;
15408     }
15409
15410   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15411
15412   clib_memcpy (mp->name, name, vec_len (name));
15413   vec_free (name);
15414   mp->crypto_alg = crypto_alg;
15415   mp->crypto_key_size = crypto_key_size;
15416   mp->integ_alg = integ_alg;
15417   mp->dh_group = dh_group;
15418
15419   S (mp);
15420   W (ret);
15421   return ret;
15422 }
15423
15424
15425 static int
15426 api_ikev2_set_esp_transforms (vat_main_t * vam)
15427 {
15428   unformat_input_t *i = vam->input;
15429   vl_api_ikev2_set_esp_transforms_t *mp;
15430   int ret;
15431   u8 *name = 0;
15432   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15433
15434   const char *valid_chars = "a-zA-Z0-9_";
15435
15436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15437     {
15438       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15439                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15440         vec_add1 (name, 0);
15441       else
15442         {
15443           errmsg ("parse error '%U'", format_unformat_error, i);
15444           return -99;
15445         }
15446     }
15447
15448   if (!vec_len (name))
15449     {
15450       errmsg ("profile name must be specified");
15451       return -99;
15452     }
15453
15454   if (vec_len (name) > 64)
15455     {
15456       errmsg ("profile name too long");
15457       return -99;
15458     }
15459
15460   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15461
15462   clib_memcpy (mp->name, name, vec_len (name));
15463   vec_free (name);
15464   mp->crypto_alg = crypto_alg;
15465   mp->crypto_key_size = crypto_key_size;
15466   mp->integ_alg = integ_alg;
15467   mp->dh_group = dh_group;
15468
15469   S (mp);
15470   W (ret);
15471   return ret;
15472 }
15473
15474 static int
15475 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15476 {
15477   unformat_input_t *i = vam->input;
15478   vl_api_ikev2_set_sa_lifetime_t *mp;
15479   int ret;
15480   u8 *name = 0;
15481   u64 lifetime, lifetime_maxdata;
15482   u32 lifetime_jitter, handover;
15483
15484   const char *valid_chars = "a-zA-Z0-9_";
15485
15486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15487     {
15488       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15489                     &lifetime, &lifetime_jitter, &handover,
15490                     &lifetime_maxdata))
15491         vec_add1 (name, 0);
15492       else
15493         {
15494           errmsg ("parse error '%U'", format_unformat_error, i);
15495           return -99;
15496         }
15497     }
15498
15499   if (!vec_len (name))
15500     {
15501       errmsg ("profile name must be specified");
15502       return -99;
15503     }
15504
15505   if (vec_len (name) > 64)
15506     {
15507       errmsg ("profile name too long");
15508       return -99;
15509     }
15510
15511   M (IKEV2_SET_SA_LIFETIME, mp);
15512
15513   clib_memcpy (mp->name, name, vec_len (name));
15514   vec_free (name);
15515   mp->lifetime = lifetime;
15516   mp->lifetime_jitter = lifetime_jitter;
15517   mp->handover = handover;
15518   mp->lifetime_maxdata = lifetime_maxdata;
15519
15520   S (mp);
15521   W (ret);
15522   return ret;
15523 }
15524
15525 static int
15526 api_ikev2_initiate_sa_init (vat_main_t * vam)
15527 {
15528   unformat_input_t *i = vam->input;
15529   vl_api_ikev2_initiate_sa_init_t *mp;
15530   int ret;
15531   u8 *name = 0;
15532
15533   const char *valid_chars = "a-zA-Z0-9_";
15534
15535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15536     {
15537       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15538         vec_add1 (name, 0);
15539       else
15540         {
15541           errmsg ("parse error '%U'", format_unformat_error, i);
15542           return -99;
15543         }
15544     }
15545
15546   if (!vec_len (name))
15547     {
15548       errmsg ("profile name must be specified");
15549       return -99;
15550     }
15551
15552   if (vec_len (name) > 64)
15553     {
15554       errmsg ("profile name too long");
15555       return -99;
15556     }
15557
15558   M (IKEV2_INITIATE_SA_INIT, mp);
15559
15560   clib_memcpy (mp->name, name, vec_len (name));
15561   vec_free (name);
15562
15563   S (mp);
15564   W (ret);
15565   return ret;
15566 }
15567
15568 static int
15569 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15570 {
15571   unformat_input_t *i = vam->input;
15572   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15573   int ret;
15574   u64 ispi;
15575
15576
15577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (i, "%lx", &ispi))
15580         ;
15581       else
15582         {
15583           errmsg ("parse error '%U'", format_unformat_error, i);
15584           return -99;
15585         }
15586     }
15587
15588   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15589
15590   mp->ispi = ispi;
15591
15592   S (mp);
15593   W (ret);
15594   return ret;
15595 }
15596
15597 static int
15598 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15599 {
15600   unformat_input_t *i = vam->input;
15601   vl_api_ikev2_initiate_del_child_sa_t *mp;
15602   int ret;
15603   u32 ispi;
15604
15605
15606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15607     {
15608       if (unformat (i, "%x", &ispi))
15609         ;
15610       else
15611         {
15612           errmsg ("parse error '%U'", format_unformat_error, i);
15613           return -99;
15614         }
15615     }
15616
15617   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15618
15619   mp->ispi = ispi;
15620
15621   S (mp);
15622   W (ret);
15623   return ret;
15624 }
15625
15626 static int
15627 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15628 {
15629   unformat_input_t *i = vam->input;
15630   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15631   int ret;
15632   u32 ispi;
15633
15634
15635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15636     {
15637       if (unformat (i, "%x", &ispi))
15638         ;
15639       else
15640         {
15641           errmsg ("parse error '%U'", format_unformat_error, i);
15642           return -99;
15643         }
15644     }
15645
15646   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15647
15648   mp->ispi = ispi;
15649
15650   S (mp);
15651   W (ret);
15652   return ret;
15653 }
15654
15655 /*
15656  * MAP
15657  */
15658 static int
15659 api_map_add_domain (vat_main_t * vam)
15660 {
15661   unformat_input_t *i = vam->input;
15662   vl_api_map_add_domain_t *mp;
15663
15664   ip4_address_t ip4_prefix;
15665   ip6_address_t ip6_prefix;
15666   ip6_address_t ip6_src;
15667   u32 num_m_args = 0;
15668   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15669     0, psid_length = 0;
15670   u8 is_translation = 0;
15671   u32 mtu = 0;
15672   u32 ip6_src_len = 128;
15673   int ret;
15674
15675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15678                     &ip4_prefix, &ip4_prefix_len))
15679         num_m_args++;
15680       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15681                          &ip6_prefix, &ip6_prefix_len))
15682         num_m_args++;
15683       else
15684         if (unformat
15685             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15686              &ip6_src_len))
15687         num_m_args++;
15688       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15689         num_m_args++;
15690       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15691         num_m_args++;
15692       else if (unformat (i, "psid-offset %d", &psid_offset))
15693         num_m_args++;
15694       else if (unformat (i, "psid-len %d", &psid_length))
15695         num_m_args++;
15696       else if (unformat (i, "mtu %d", &mtu))
15697         num_m_args++;
15698       else if (unformat (i, "map-t"))
15699         is_translation = 1;
15700       else
15701         {
15702           clib_warning ("parse error '%U'", format_unformat_error, i);
15703           return -99;
15704         }
15705     }
15706
15707   if (num_m_args < 3)
15708     {
15709       errmsg ("mandatory argument(s) missing");
15710       return -99;
15711     }
15712
15713   /* Construct the API message */
15714   M (MAP_ADD_DOMAIN, mp);
15715
15716   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15717   mp->ip4_prefix_len = ip4_prefix_len;
15718
15719   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15720   mp->ip6_prefix_len = ip6_prefix_len;
15721
15722   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15723   mp->ip6_src_prefix_len = ip6_src_len;
15724
15725   mp->ea_bits_len = ea_bits_len;
15726   mp->psid_offset = psid_offset;
15727   mp->psid_length = psid_length;
15728   mp->is_translation = is_translation;
15729   mp->mtu = htons (mtu);
15730
15731   /* send it... */
15732   S (mp);
15733
15734   /* Wait for a reply, return good/bad news  */
15735   W (ret);
15736   return ret;
15737 }
15738
15739 static int
15740 api_map_del_domain (vat_main_t * vam)
15741 {
15742   unformat_input_t *i = vam->input;
15743   vl_api_map_del_domain_t *mp;
15744
15745   u32 num_m_args = 0;
15746   u32 index;
15747   int ret;
15748
15749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15750     {
15751       if (unformat (i, "index %d", &index))
15752         num_m_args++;
15753       else
15754         {
15755           clib_warning ("parse error '%U'", format_unformat_error, i);
15756           return -99;
15757         }
15758     }
15759
15760   if (num_m_args != 1)
15761     {
15762       errmsg ("mandatory argument(s) missing");
15763       return -99;
15764     }
15765
15766   /* Construct the API message */
15767   M (MAP_DEL_DOMAIN, mp);
15768
15769   mp->index = ntohl (index);
15770
15771   /* send it... */
15772   S (mp);
15773
15774   /* Wait for a reply, return good/bad news  */
15775   W (ret);
15776   return ret;
15777 }
15778
15779 static int
15780 api_map_add_del_rule (vat_main_t * vam)
15781 {
15782   unformat_input_t *i = vam->input;
15783   vl_api_map_add_del_rule_t *mp;
15784   u8 is_add = 1;
15785   ip6_address_t ip6_dst;
15786   u32 num_m_args = 0, index, psid = 0;
15787   int ret;
15788
15789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15790     {
15791       if (unformat (i, "index %d", &index))
15792         num_m_args++;
15793       else if (unformat (i, "psid %d", &psid))
15794         num_m_args++;
15795       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15796         num_m_args++;
15797       else if (unformat (i, "del"))
15798         {
15799           is_add = 0;
15800         }
15801       else
15802         {
15803           clib_warning ("parse error '%U'", format_unformat_error, i);
15804           return -99;
15805         }
15806     }
15807
15808   /* Construct the API message */
15809   M (MAP_ADD_DEL_RULE, mp);
15810
15811   mp->index = ntohl (index);
15812   mp->is_add = is_add;
15813   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15814   mp->psid = ntohs (psid);
15815
15816   /* send it... */
15817   S (mp);
15818
15819   /* Wait for a reply, return good/bad news  */
15820   W (ret);
15821   return ret;
15822 }
15823
15824 static int
15825 api_map_domain_dump (vat_main_t * vam)
15826 {
15827   vl_api_map_domain_dump_t *mp;
15828   vl_api_control_ping_t *mp_ping;
15829   int ret;
15830
15831   /* Construct the API message */
15832   M (MAP_DOMAIN_DUMP, mp);
15833
15834   /* send it... */
15835   S (mp);
15836
15837   /* Use a control ping for synchronization */
15838   MPING (CONTROL_PING, mp_ping);
15839   S (mp_ping);
15840
15841   W (ret);
15842   return ret;
15843 }
15844
15845 static int
15846 api_map_rule_dump (vat_main_t * vam)
15847 {
15848   unformat_input_t *i = vam->input;
15849   vl_api_map_rule_dump_t *mp;
15850   vl_api_control_ping_t *mp_ping;
15851   u32 domain_index = ~0;
15852   int ret;
15853
15854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15855     {
15856       if (unformat (i, "index %u", &domain_index))
15857         ;
15858       else
15859         break;
15860     }
15861
15862   if (domain_index == ~0)
15863     {
15864       clib_warning ("parse error: domain index expected");
15865       return -99;
15866     }
15867
15868   /* Construct the API message */
15869   M (MAP_RULE_DUMP, mp);
15870
15871   mp->domain_index = htonl (domain_index);
15872
15873   /* send it... */
15874   S (mp);
15875
15876   /* Use a control ping for synchronization */
15877   MPING (CONTROL_PING, mp_ping);
15878   S (mp_ping);
15879
15880   W (ret);
15881   return ret;
15882 }
15883
15884 static void vl_api_map_add_domain_reply_t_handler
15885   (vl_api_map_add_domain_reply_t * mp)
15886 {
15887   vat_main_t *vam = &vat_main;
15888   i32 retval = ntohl (mp->retval);
15889
15890   if (vam->async_mode)
15891     {
15892       vam->async_errors += (retval < 0);
15893     }
15894   else
15895     {
15896       vam->retval = retval;
15897       vam->result_ready = 1;
15898     }
15899 }
15900
15901 static void vl_api_map_add_domain_reply_t_handler_json
15902   (vl_api_map_add_domain_reply_t * mp)
15903 {
15904   vat_main_t *vam = &vat_main;
15905   vat_json_node_t node;
15906
15907   vat_json_init_object (&node);
15908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15909   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15910
15911   vat_json_print (vam->ofp, &node);
15912   vat_json_free (&node);
15913
15914   vam->retval = ntohl (mp->retval);
15915   vam->result_ready = 1;
15916 }
15917
15918 static int
15919 api_get_first_msg_id (vat_main_t * vam)
15920 {
15921   vl_api_get_first_msg_id_t *mp;
15922   unformat_input_t *i = vam->input;
15923   u8 *name;
15924   u8 name_set = 0;
15925   int ret;
15926
15927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15928     {
15929       if (unformat (i, "client %s", &name))
15930         name_set = 1;
15931       else
15932         break;
15933     }
15934
15935   if (name_set == 0)
15936     {
15937       errmsg ("missing client name");
15938       return -99;
15939     }
15940   vec_add1 (name, 0);
15941
15942   if (vec_len (name) > 63)
15943     {
15944       errmsg ("client name too long");
15945       return -99;
15946     }
15947
15948   M (GET_FIRST_MSG_ID, mp);
15949   clib_memcpy (mp->name, name, vec_len (name));
15950   S (mp);
15951   W (ret);
15952   return ret;
15953 }
15954
15955 static int
15956 api_cop_interface_enable_disable (vat_main_t * vam)
15957 {
15958   unformat_input_t *line_input = vam->input;
15959   vl_api_cop_interface_enable_disable_t *mp;
15960   u32 sw_if_index = ~0;
15961   u8 enable_disable = 1;
15962   int ret;
15963
15964   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15965     {
15966       if (unformat (line_input, "disable"))
15967         enable_disable = 0;
15968       if (unformat (line_input, "enable"))
15969         enable_disable = 1;
15970       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15971                          vam, &sw_if_index))
15972         ;
15973       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15974         ;
15975       else
15976         break;
15977     }
15978
15979   if (sw_if_index == ~0)
15980     {
15981       errmsg ("missing interface name or sw_if_index");
15982       return -99;
15983     }
15984
15985   /* Construct the API message */
15986   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15987   mp->sw_if_index = ntohl (sw_if_index);
15988   mp->enable_disable = enable_disable;
15989
15990   /* send it... */
15991   S (mp);
15992   /* Wait for the reply */
15993   W (ret);
15994   return ret;
15995 }
15996
15997 static int
15998 api_cop_whitelist_enable_disable (vat_main_t * vam)
15999 {
16000   unformat_input_t *line_input = vam->input;
16001   vl_api_cop_whitelist_enable_disable_t *mp;
16002   u32 sw_if_index = ~0;
16003   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16004   u32 fib_id = 0;
16005   int ret;
16006
16007   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16008     {
16009       if (unformat (line_input, "ip4"))
16010         ip4 = 1;
16011       else if (unformat (line_input, "ip6"))
16012         ip6 = 1;
16013       else if (unformat (line_input, "default"))
16014         default_cop = 1;
16015       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16016                          vam, &sw_if_index))
16017         ;
16018       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16019         ;
16020       else if (unformat (line_input, "fib-id %d", &fib_id))
16021         ;
16022       else
16023         break;
16024     }
16025
16026   if (sw_if_index == ~0)
16027     {
16028       errmsg ("missing interface name or sw_if_index");
16029       return -99;
16030     }
16031
16032   /* Construct the API message */
16033   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16034   mp->sw_if_index = ntohl (sw_if_index);
16035   mp->fib_id = ntohl (fib_id);
16036   mp->ip4 = ip4;
16037   mp->ip6 = ip6;
16038   mp->default_cop = default_cop;
16039
16040   /* send it... */
16041   S (mp);
16042   /* Wait for the reply */
16043   W (ret);
16044   return ret;
16045 }
16046
16047 static int
16048 api_get_node_graph (vat_main_t * vam)
16049 {
16050   vl_api_get_node_graph_t *mp;
16051   int ret;
16052
16053   M (GET_NODE_GRAPH, mp);
16054
16055   /* send it... */
16056   S (mp);
16057   /* Wait for the reply */
16058   W (ret);
16059   return ret;
16060 }
16061
16062 /* *INDENT-OFF* */
16063 /** Used for parsing LISP eids */
16064 typedef CLIB_PACKED(struct{
16065   u8 addr[16];   /**< eid address */
16066   u32 len;       /**< prefix length if IP */
16067   u8 type;      /**< type of eid */
16068 }) lisp_eid_vat_t;
16069 /* *INDENT-ON* */
16070
16071 static uword
16072 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16073 {
16074   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16075
16076   memset (a, 0, sizeof (a[0]));
16077
16078   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16079     {
16080       a->type = 0;              /* ipv4 type */
16081     }
16082   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16083     {
16084       a->type = 1;              /* ipv6 type */
16085     }
16086   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16087     {
16088       a->type = 2;              /* mac type */
16089     }
16090   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16091     {
16092       a->type = 3;              /* NSH type */
16093       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16094       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16095     }
16096   else
16097     {
16098       return 0;
16099     }
16100
16101   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16102     {
16103       return 0;
16104     }
16105
16106   return 1;
16107 }
16108
16109 static int
16110 lisp_eid_size_vat (u8 type)
16111 {
16112   switch (type)
16113     {
16114     case 0:
16115       return 4;
16116     case 1:
16117       return 16;
16118     case 2:
16119       return 6;
16120     case 3:
16121       return 5;
16122     }
16123   return 0;
16124 }
16125
16126 static void
16127 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16128 {
16129   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16130 }
16131
16132 static int
16133 api_one_add_del_locator_set (vat_main_t * vam)
16134 {
16135   unformat_input_t *input = vam->input;
16136   vl_api_one_add_del_locator_set_t *mp;
16137   u8 is_add = 1;
16138   u8 *locator_set_name = NULL;
16139   u8 locator_set_name_set = 0;
16140   vl_api_local_locator_t locator, *locators = 0;
16141   u32 sw_if_index, priority, weight;
16142   u32 data_len = 0;
16143
16144   int ret;
16145   /* Parse args required to build the message */
16146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (input, "del"))
16149         {
16150           is_add = 0;
16151         }
16152       else if (unformat (input, "locator-set %s", &locator_set_name))
16153         {
16154           locator_set_name_set = 1;
16155         }
16156       else if (unformat (input, "sw_if_index %u p %u w %u",
16157                          &sw_if_index, &priority, &weight))
16158         {
16159           locator.sw_if_index = htonl (sw_if_index);
16160           locator.priority = priority;
16161           locator.weight = weight;
16162           vec_add1 (locators, locator);
16163         }
16164       else
16165         if (unformat
16166             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16167              &sw_if_index, &priority, &weight))
16168         {
16169           locator.sw_if_index = htonl (sw_if_index);
16170           locator.priority = priority;
16171           locator.weight = weight;
16172           vec_add1 (locators, locator);
16173         }
16174       else
16175         break;
16176     }
16177
16178   if (locator_set_name_set == 0)
16179     {
16180       errmsg ("missing locator-set name");
16181       vec_free (locators);
16182       return -99;
16183     }
16184
16185   if (vec_len (locator_set_name) > 64)
16186     {
16187       errmsg ("locator-set name too long");
16188       vec_free (locator_set_name);
16189       vec_free (locators);
16190       return -99;
16191     }
16192   vec_add1 (locator_set_name, 0);
16193
16194   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16195
16196   /* Construct the API message */
16197   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16198
16199   mp->is_add = is_add;
16200   clib_memcpy (mp->locator_set_name, locator_set_name,
16201                vec_len (locator_set_name));
16202   vec_free (locator_set_name);
16203
16204   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16205   if (locators)
16206     clib_memcpy (mp->locators, locators, data_len);
16207   vec_free (locators);
16208
16209   /* send it... */
16210   S (mp);
16211
16212   /* Wait for a reply... */
16213   W (ret);
16214   return ret;
16215 }
16216
16217 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16218
16219 static int
16220 api_one_add_del_locator (vat_main_t * vam)
16221 {
16222   unformat_input_t *input = vam->input;
16223   vl_api_one_add_del_locator_t *mp;
16224   u32 tmp_if_index = ~0;
16225   u32 sw_if_index = ~0;
16226   u8 sw_if_index_set = 0;
16227   u8 sw_if_index_if_name_set = 0;
16228   u32 priority = ~0;
16229   u8 priority_set = 0;
16230   u32 weight = ~0;
16231   u8 weight_set = 0;
16232   u8 is_add = 1;
16233   u8 *locator_set_name = NULL;
16234   u8 locator_set_name_set = 0;
16235   int ret;
16236
16237   /* Parse args required to build the message */
16238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16239     {
16240       if (unformat (input, "del"))
16241         {
16242           is_add = 0;
16243         }
16244       else if (unformat (input, "locator-set %s", &locator_set_name))
16245         {
16246           locator_set_name_set = 1;
16247         }
16248       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16249                          &tmp_if_index))
16250         {
16251           sw_if_index_if_name_set = 1;
16252           sw_if_index = tmp_if_index;
16253         }
16254       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16255         {
16256           sw_if_index_set = 1;
16257           sw_if_index = tmp_if_index;
16258         }
16259       else if (unformat (input, "p %d", &priority))
16260         {
16261           priority_set = 1;
16262         }
16263       else if (unformat (input, "w %d", &weight))
16264         {
16265           weight_set = 1;
16266         }
16267       else
16268         break;
16269     }
16270
16271   if (locator_set_name_set == 0)
16272     {
16273       errmsg ("missing locator-set name");
16274       return -99;
16275     }
16276
16277   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16278     {
16279       errmsg ("missing sw_if_index");
16280       vec_free (locator_set_name);
16281       return -99;
16282     }
16283
16284   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16285     {
16286       errmsg ("cannot use both params interface name and sw_if_index");
16287       vec_free (locator_set_name);
16288       return -99;
16289     }
16290
16291   if (priority_set == 0)
16292     {
16293       errmsg ("missing locator-set priority");
16294       vec_free (locator_set_name);
16295       return -99;
16296     }
16297
16298   if (weight_set == 0)
16299     {
16300       errmsg ("missing locator-set weight");
16301       vec_free (locator_set_name);
16302       return -99;
16303     }
16304
16305   if (vec_len (locator_set_name) > 64)
16306     {
16307       errmsg ("locator-set name too long");
16308       vec_free (locator_set_name);
16309       return -99;
16310     }
16311   vec_add1 (locator_set_name, 0);
16312
16313   /* Construct the API message */
16314   M (ONE_ADD_DEL_LOCATOR, mp);
16315
16316   mp->is_add = is_add;
16317   mp->sw_if_index = ntohl (sw_if_index);
16318   mp->priority = priority;
16319   mp->weight = weight;
16320   clib_memcpy (mp->locator_set_name, locator_set_name,
16321                vec_len (locator_set_name));
16322   vec_free (locator_set_name);
16323
16324   /* send it... */
16325   S (mp);
16326
16327   /* Wait for a reply... */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 #define api_lisp_add_del_locator api_one_add_del_locator
16333
16334 uword
16335 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16336 {
16337   u32 *key_id = va_arg (*args, u32 *);
16338   u8 *s = 0;
16339
16340   if (unformat (input, "%s", &s))
16341     {
16342       if (!strcmp ((char *) s, "sha1"))
16343         key_id[0] = HMAC_SHA_1_96;
16344       else if (!strcmp ((char *) s, "sha256"))
16345         key_id[0] = HMAC_SHA_256_128;
16346       else
16347         {
16348           clib_warning ("invalid key_id: '%s'", s);
16349           key_id[0] = HMAC_NO_KEY;
16350         }
16351     }
16352   else
16353     return 0;
16354
16355   vec_free (s);
16356   return 1;
16357 }
16358
16359 static int
16360 api_one_add_del_local_eid (vat_main_t * vam)
16361 {
16362   unformat_input_t *input = vam->input;
16363   vl_api_one_add_del_local_eid_t *mp;
16364   u8 is_add = 1;
16365   u8 eid_set = 0;
16366   lisp_eid_vat_t _eid, *eid = &_eid;
16367   u8 *locator_set_name = 0;
16368   u8 locator_set_name_set = 0;
16369   u32 vni = 0;
16370   u16 key_id = 0;
16371   u8 *key = 0;
16372   int ret;
16373
16374   /* Parse args required to build the message */
16375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16376     {
16377       if (unformat (input, "del"))
16378         {
16379           is_add = 0;
16380         }
16381       else if (unformat (input, "vni %d", &vni))
16382         {
16383           ;
16384         }
16385       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16386         {
16387           eid_set = 1;
16388         }
16389       else if (unformat (input, "locator-set %s", &locator_set_name))
16390         {
16391           locator_set_name_set = 1;
16392         }
16393       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16394         ;
16395       else if (unformat (input, "secret-key %_%v%_", &key))
16396         ;
16397       else
16398         break;
16399     }
16400
16401   if (locator_set_name_set == 0)
16402     {
16403       errmsg ("missing locator-set name");
16404       return -99;
16405     }
16406
16407   if (0 == eid_set)
16408     {
16409       errmsg ("EID address not set!");
16410       vec_free (locator_set_name);
16411       return -99;
16412     }
16413
16414   if (key && (0 == key_id))
16415     {
16416       errmsg ("invalid key_id!");
16417       return -99;
16418     }
16419
16420   if (vec_len (key) > 64)
16421     {
16422       errmsg ("key too long");
16423       vec_free (key);
16424       return -99;
16425     }
16426
16427   if (vec_len (locator_set_name) > 64)
16428     {
16429       errmsg ("locator-set name too long");
16430       vec_free (locator_set_name);
16431       return -99;
16432     }
16433   vec_add1 (locator_set_name, 0);
16434
16435   /* Construct the API message */
16436   M (ONE_ADD_DEL_LOCAL_EID, mp);
16437
16438   mp->is_add = is_add;
16439   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16440   mp->eid_type = eid->type;
16441   mp->prefix_len = eid->len;
16442   mp->vni = clib_host_to_net_u32 (vni);
16443   mp->key_id = clib_host_to_net_u16 (key_id);
16444   clib_memcpy (mp->locator_set_name, locator_set_name,
16445                vec_len (locator_set_name));
16446   clib_memcpy (mp->key, key, vec_len (key));
16447
16448   vec_free (locator_set_name);
16449   vec_free (key);
16450
16451   /* send it... */
16452   S (mp);
16453
16454   /* Wait for a reply... */
16455   W (ret);
16456   return ret;
16457 }
16458
16459 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16460
16461 static int
16462 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16463 {
16464   u32 dp_table = 0, vni = 0;;
16465   unformat_input_t *input = vam->input;
16466   vl_api_gpe_add_del_fwd_entry_t *mp;
16467   u8 is_add = 1;
16468   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16469   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16470   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16471   u32 action = ~0, w;
16472   ip4_address_t rmt_rloc4, lcl_rloc4;
16473   ip6_address_t rmt_rloc6, lcl_rloc6;
16474   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16475   int ret;
16476
16477   memset (&rloc, 0, sizeof (rloc));
16478
16479   /* Parse args required to build the message */
16480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16481     {
16482       if (unformat (input, "del"))
16483         is_add = 0;
16484       else if (unformat (input, "add"))
16485         is_add = 1;
16486       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16487         {
16488           rmt_eid_set = 1;
16489         }
16490       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16491         {
16492           lcl_eid_set = 1;
16493         }
16494       else if (unformat (input, "vrf %d", &dp_table))
16495         ;
16496       else if (unformat (input, "bd %d", &dp_table))
16497         ;
16498       else if (unformat (input, "vni %d", &vni))
16499         ;
16500       else if (unformat (input, "w %d", &w))
16501         {
16502           if (!curr_rloc)
16503             {
16504               errmsg ("No RLOC configured for setting priority/weight!");
16505               return -99;
16506             }
16507           curr_rloc->weight = w;
16508         }
16509       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16510                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16511         {
16512           rloc.is_ip4 = 1;
16513
16514           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16515           rloc.weight = 0;
16516           vec_add1 (lcl_locs, rloc);
16517
16518           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16519           vec_add1 (rmt_locs, rloc);
16520           /* weight saved in rmt loc */
16521           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16522         }
16523       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16524                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16525         {
16526           rloc.is_ip4 = 0;
16527           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16528           rloc.weight = 0;
16529           vec_add1 (lcl_locs, rloc);
16530
16531           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16532           vec_add1 (rmt_locs, rloc);
16533           /* weight saved in rmt loc */
16534           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16535         }
16536       else if (unformat (input, "action %d", &action))
16537         {
16538           ;
16539         }
16540       else
16541         {
16542           clib_warning ("parse error '%U'", format_unformat_error, input);
16543           return -99;
16544         }
16545     }
16546
16547   if (!rmt_eid_set)
16548     {
16549       errmsg ("remote eid addresses not set");
16550       return -99;
16551     }
16552
16553   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16554     {
16555       errmsg ("eid types don't match");
16556       return -99;
16557     }
16558
16559   if (0 == rmt_locs && (u32) ~ 0 == action)
16560     {
16561       errmsg ("action not set for negative mapping");
16562       return -99;
16563     }
16564
16565   /* Construct the API message */
16566   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16567       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16568
16569   mp->is_add = is_add;
16570   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16571   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16572   mp->eid_type = rmt_eid->type;
16573   mp->dp_table = clib_host_to_net_u32 (dp_table);
16574   mp->vni = clib_host_to_net_u32 (vni);
16575   mp->rmt_len = rmt_eid->len;
16576   mp->lcl_len = lcl_eid->len;
16577   mp->action = action;
16578
16579   if (0 != rmt_locs && 0 != lcl_locs)
16580     {
16581       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16582       clib_memcpy (mp->locs, lcl_locs,
16583                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16584
16585       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16586       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16587                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16588     }
16589   vec_free (lcl_locs);
16590   vec_free (rmt_locs);
16591
16592   /* send it... */
16593   S (mp);
16594
16595   /* Wait for a reply... */
16596   W (ret);
16597   return ret;
16598 }
16599
16600 static int
16601 api_one_add_del_map_server (vat_main_t * vam)
16602 {
16603   unformat_input_t *input = vam->input;
16604   vl_api_one_add_del_map_server_t *mp;
16605   u8 is_add = 1;
16606   u8 ipv4_set = 0;
16607   u8 ipv6_set = 0;
16608   ip4_address_t ipv4;
16609   ip6_address_t ipv6;
16610   int ret;
16611
16612   /* Parse args required to build the message */
16613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16614     {
16615       if (unformat (input, "del"))
16616         {
16617           is_add = 0;
16618         }
16619       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16620         {
16621           ipv4_set = 1;
16622         }
16623       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16624         {
16625           ipv6_set = 1;
16626         }
16627       else
16628         break;
16629     }
16630
16631   if (ipv4_set && ipv6_set)
16632     {
16633       errmsg ("both eid v4 and v6 addresses set");
16634       return -99;
16635     }
16636
16637   if (!ipv4_set && !ipv6_set)
16638     {
16639       errmsg ("eid addresses not set");
16640       return -99;
16641     }
16642
16643   /* Construct the API message */
16644   M (ONE_ADD_DEL_MAP_SERVER, mp);
16645
16646   mp->is_add = is_add;
16647   if (ipv6_set)
16648     {
16649       mp->is_ipv6 = 1;
16650       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16651     }
16652   else
16653     {
16654       mp->is_ipv6 = 0;
16655       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16656     }
16657
16658   /* send it... */
16659   S (mp);
16660
16661   /* Wait for a reply... */
16662   W (ret);
16663   return ret;
16664 }
16665
16666 #define api_lisp_add_del_map_server api_one_add_del_map_server
16667
16668 static int
16669 api_one_add_del_map_resolver (vat_main_t * vam)
16670 {
16671   unformat_input_t *input = vam->input;
16672   vl_api_one_add_del_map_resolver_t *mp;
16673   u8 is_add = 1;
16674   u8 ipv4_set = 0;
16675   u8 ipv6_set = 0;
16676   ip4_address_t ipv4;
16677   ip6_address_t ipv6;
16678   int ret;
16679
16680   /* Parse args required to build the message */
16681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16682     {
16683       if (unformat (input, "del"))
16684         {
16685           is_add = 0;
16686         }
16687       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16688         {
16689           ipv4_set = 1;
16690         }
16691       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16692         {
16693           ipv6_set = 1;
16694         }
16695       else
16696         break;
16697     }
16698
16699   if (ipv4_set && ipv6_set)
16700     {
16701       errmsg ("both eid v4 and v6 addresses set");
16702       return -99;
16703     }
16704
16705   if (!ipv4_set && !ipv6_set)
16706     {
16707       errmsg ("eid addresses not set");
16708       return -99;
16709     }
16710
16711   /* Construct the API message */
16712   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16713
16714   mp->is_add = is_add;
16715   if (ipv6_set)
16716     {
16717       mp->is_ipv6 = 1;
16718       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16719     }
16720   else
16721     {
16722       mp->is_ipv6 = 0;
16723       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16724     }
16725
16726   /* send it... */
16727   S (mp);
16728
16729   /* Wait for a reply... */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16735
16736 static int
16737 api_lisp_gpe_enable_disable (vat_main_t * vam)
16738 {
16739   unformat_input_t *input = vam->input;
16740   vl_api_gpe_enable_disable_t *mp;
16741   u8 is_set = 0;
16742   u8 is_en = 1;
16743   int ret;
16744
16745   /* Parse args required to build the message */
16746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16747     {
16748       if (unformat (input, "enable"))
16749         {
16750           is_set = 1;
16751           is_en = 1;
16752         }
16753       else if (unformat (input, "disable"))
16754         {
16755           is_set = 1;
16756           is_en = 0;
16757         }
16758       else
16759         break;
16760     }
16761
16762   if (is_set == 0)
16763     {
16764       errmsg ("Value not set");
16765       return -99;
16766     }
16767
16768   /* Construct the API message */
16769   M (GPE_ENABLE_DISABLE, mp);
16770
16771   mp->is_en = is_en;
16772
16773   /* send it... */
16774   S (mp);
16775
16776   /* Wait for a reply... */
16777   W (ret);
16778   return ret;
16779 }
16780
16781 static int
16782 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16783 {
16784   unformat_input_t *input = vam->input;
16785   vl_api_one_rloc_probe_enable_disable_t *mp;
16786   u8 is_set = 0;
16787   u8 is_en = 0;
16788   int ret;
16789
16790   /* Parse args required to build the message */
16791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16792     {
16793       if (unformat (input, "enable"))
16794         {
16795           is_set = 1;
16796           is_en = 1;
16797         }
16798       else if (unformat (input, "disable"))
16799         is_set = 1;
16800       else
16801         break;
16802     }
16803
16804   if (!is_set)
16805     {
16806       errmsg ("Value not set");
16807       return -99;
16808     }
16809
16810   /* Construct the API message */
16811   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16812
16813   mp->is_enabled = is_en;
16814
16815   /* send it... */
16816   S (mp);
16817
16818   /* Wait for a reply... */
16819   W (ret);
16820   return ret;
16821 }
16822
16823 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16824
16825 static int
16826 api_one_map_register_enable_disable (vat_main_t * vam)
16827 {
16828   unformat_input_t *input = vam->input;
16829   vl_api_one_map_register_enable_disable_t *mp;
16830   u8 is_set = 0;
16831   u8 is_en = 0;
16832   int ret;
16833
16834   /* Parse args required to build the message */
16835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16836     {
16837       if (unformat (input, "enable"))
16838         {
16839           is_set = 1;
16840           is_en = 1;
16841         }
16842       else if (unformat (input, "disable"))
16843         is_set = 1;
16844       else
16845         break;
16846     }
16847
16848   if (!is_set)
16849     {
16850       errmsg ("Value not set");
16851       return -99;
16852     }
16853
16854   /* Construct the API message */
16855   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16856
16857   mp->is_enabled = is_en;
16858
16859   /* send it... */
16860   S (mp);
16861
16862   /* Wait for a reply... */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16868
16869 static int
16870 api_one_enable_disable (vat_main_t * vam)
16871 {
16872   unformat_input_t *input = vam->input;
16873   vl_api_one_enable_disable_t *mp;
16874   u8 is_set = 0;
16875   u8 is_en = 0;
16876   int ret;
16877
16878   /* Parse args required to build the message */
16879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16880     {
16881       if (unformat (input, "enable"))
16882         {
16883           is_set = 1;
16884           is_en = 1;
16885         }
16886       else if (unformat (input, "disable"))
16887         {
16888           is_set = 1;
16889         }
16890       else
16891         break;
16892     }
16893
16894   if (!is_set)
16895     {
16896       errmsg ("Value not set");
16897       return -99;
16898     }
16899
16900   /* Construct the API message */
16901   M (ONE_ENABLE_DISABLE, mp);
16902
16903   mp->is_en = is_en;
16904
16905   /* send it... */
16906   S (mp);
16907
16908   /* Wait for a reply... */
16909   W (ret);
16910   return ret;
16911 }
16912
16913 #define api_lisp_enable_disable api_one_enable_disable
16914
16915 static int
16916 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16917 {
16918   unformat_input_t *input = vam->input;
16919   vl_api_one_enable_disable_xtr_mode_t *mp;
16920   u8 is_set = 0;
16921   u8 is_en = 0;
16922   int ret;
16923
16924   /* Parse args required to build the message */
16925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16926     {
16927       if (unformat (input, "enable"))
16928         {
16929           is_set = 1;
16930           is_en = 1;
16931         }
16932       else if (unformat (input, "disable"))
16933         {
16934           is_set = 1;
16935         }
16936       else
16937         break;
16938     }
16939
16940   if (!is_set)
16941     {
16942       errmsg ("Value not set");
16943       return -99;
16944     }
16945
16946   /* Construct the API message */
16947   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16948
16949   mp->is_en = is_en;
16950
16951   /* send it... */
16952   S (mp);
16953
16954   /* Wait for a reply... */
16955   W (ret);
16956   return ret;
16957 }
16958
16959 static int
16960 api_one_show_xtr_mode (vat_main_t * vam)
16961 {
16962   vl_api_one_show_xtr_mode_t *mp;
16963   int ret;
16964
16965   /* Construct the API message */
16966   M (ONE_SHOW_XTR_MODE, mp);
16967
16968   /* send it... */
16969   S (mp);
16970
16971   /* Wait for a reply... */
16972   W (ret);
16973   return ret;
16974 }
16975
16976 static int
16977 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16978 {
16979   unformat_input_t *input = vam->input;
16980   vl_api_one_enable_disable_pitr_mode_t *mp;
16981   u8 is_set = 0;
16982   u8 is_en = 0;
16983   int ret;
16984
16985   /* Parse args required to build the message */
16986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16987     {
16988       if (unformat (input, "enable"))
16989         {
16990           is_set = 1;
16991           is_en = 1;
16992         }
16993       else if (unformat (input, "disable"))
16994         {
16995           is_set = 1;
16996         }
16997       else
16998         break;
16999     }
17000
17001   if (!is_set)
17002     {
17003       errmsg ("Value not set");
17004       return -99;
17005     }
17006
17007   /* Construct the API message */
17008   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17009
17010   mp->is_en = is_en;
17011
17012   /* send it... */
17013   S (mp);
17014
17015   /* Wait for a reply... */
17016   W (ret);
17017   return ret;
17018 }
17019
17020 static int
17021 api_one_show_pitr_mode (vat_main_t * vam)
17022 {
17023   vl_api_one_show_pitr_mode_t *mp;
17024   int ret;
17025
17026   /* Construct the API message */
17027   M (ONE_SHOW_PITR_MODE, mp);
17028
17029   /* send it... */
17030   S (mp);
17031
17032   /* Wait for a reply... */
17033   W (ret);
17034   return ret;
17035 }
17036
17037 static int
17038 api_one_enable_disable_petr_mode (vat_main_t * vam)
17039 {
17040   unformat_input_t *input = vam->input;
17041   vl_api_one_enable_disable_petr_mode_t *mp;
17042   u8 is_set = 0;
17043   u8 is_en = 0;
17044   int ret;
17045
17046   /* Parse args required to build the message */
17047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17048     {
17049       if (unformat (input, "enable"))
17050         {
17051           is_set = 1;
17052           is_en = 1;
17053         }
17054       else if (unformat (input, "disable"))
17055         {
17056           is_set = 1;
17057         }
17058       else
17059         break;
17060     }
17061
17062   if (!is_set)
17063     {
17064       errmsg ("Value not set");
17065       return -99;
17066     }
17067
17068   /* Construct the API message */
17069   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17070
17071   mp->is_en = is_en;
17072
17073   /* send it... */
17074   S (mp);
17075
17076   /* Wait for a reply... */
17077   W (ret);
17078   return ret;
17079 }
17080
17081 static int
17082 api_one_show_petr_mode (vat_main_t * vam)
17083 {
17084   vl_api_one_show_petr_mode_t *mp;
17085   int ret;
17086
17087   /* Construct the API message */
17088   M (ONE_SHOW_PETR_MODE, mp);
17089
17090   /* send it... */
17091   S (mp);
17092
17093   /* Wait for a reply... */
17094   W (ret);
17095   return ret;
17096 }
17097
17098 static int
17099 api_show_one_map_register_state (vat_main_t * vam)
17100 {
17101   vl_api_show_one_map_register_state_t *mp;
17102   int ret;
17103
17104   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17105
17106   /* send */
17107   S (mp);
17108
17109   /* wait for reply */
17110   W (ret);
17111   return ret;
17112 }
17113
17114 #define api_show_lisp_map_register_state api_show_one_map_register_state
17115
17116 static int
17117 api_show_one_rloc_probe_state (vat_main_t * vam)
17118 {
17119   vl_api_show_one_rloc_probe_state_t *mp;
17120   int ret;
17121
17122   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17123
17124   /* send */
17125   S (mp);
17126
17127   /* wait for reply */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17133
17134 static int
17135 api_one_add_del_ndp_entry (vat_main_t * vam)
17136 {
17137   vl_api_one_add_del_ndp_entry_t *mp;
17138   unformat_input_t *input = vam->input;
17139   u8 is_add = 1;
17140   u8 mac_set = 0;
17141   u8 bd_set = 0;
17142   u8 ip_set = 0;
17143   u8 mac[6] = { 0, };
17144   u8 ip6[16] = { 0, };
17145   u32 bd = ~0;
17146   int ret;
17147
17148   /* Parse args required to build the message */
17149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (input, "del"))
17152         is_add = 0;
17153       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17154         mac_set = 1;
17155       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17156         ip_set = 1;
17157       else if (unformat (input, "bd %d", &bd))
17158         bd_set = 1;
17159       else
17160         {
17161           errmsg ("parse error '%U'", format_unformat_error, input);
17162           return -99;
17163         }
17164     }
17165
17166   if (!bd_set || !ip_set || (!mac_set && is_add))
17167     {
17168       errmsg ("Missing BD, IP or MAC!");
17169       return -99;
17170     }
17171
17172   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17173   mp->is_add = is_add;
17174   clib_memcpy (mp->mac, mac, 6);
17175   mp->bd = clib_host_to_net_u32 (bd);
17176   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17177
17178   /* send */
17179   S (mp);
17180
17181   /* wait for reply */
17182   W (ret);
17183   return ret;
17184 }
17185
17186 static int
17187 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17188 {
17189   vl_api_one_add_del_l2_arp_entry_t *mp;
17190   unformat_input_t *input = vam->input;
17191   u8 is_add = 1;
17192   u8 mac_set = 0;
17193   u8 bd_set = 0;
17194   u8 ip_set = 0;
17195   u8 mac[6] = { 0, };
17196   u32 ip4 = 0, bd = ~0;
17197   int ret;
17198
17199   /* Parse args required to build the message */
17200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17201     {
17202       if (unformat (input, "del"))
17203         is_add = 0;
17204       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17205         mac_set = 1;
17206       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17207         ip_set = 1;
17208       else if (unformat (input, "bd %d", &bd))
17209         bd_set = 1;
17210       else
17211         {
17212           errmsg ("parse error '%U'", format_unformat_error, input);
17213           return -99;
17214         }
17215     }
17216
17217   if (!bd_set || !ip_set || (!mac_set && is_add))
17218     {
17219       errmsg ("Missing BD, IP or MAC!");
17220       return -99;
17221     }
17222
17223   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17224   mp->is_add = is_add;
17225   clib_memcpy (mp->mac, mac, 6);
17226   mp->bd = clib_host_to_net_u32 (bd);
17227   mp->ip4 = ip4;
17228
17229   /* send */
17230   S (mp);
17231
17232   /* wait for reply */
17233   W (ret);
17234   return ret;
17235 }
17236
17237 static int
17238 api_one_ndp_bd_get (vat_main_t * vam)
17239 {
17240   vl_api_one_ndp_bd_get_t *mp;
17241   int ret;
17242
17243   M (ONE_NDP_BD_GET, mp);
17244
17245   /* send */
17246   S (mp);
17247
17248   /* wait for reply */
17249   W (ret);
17250   return ret;
17251 }
17252
17253 static int
17254 api_one_ndp_entries_get (vat_main_t * vam)
17255 {
17256   vl_api_one_ndp_entries_get_t *mp;
17257   unformat_input_t *input = vam->input;
17258   u8 bd_set = 0;
17259   u32 bd = ~0;
17260   int ret;
17261
17262   /* Parse args required to build the message */
17263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17264     {
17265       if (unformat (input, "bd %d", &bd))
17266         bd_set = 1;
17267       else
17268         {
17269           errmsg ("parse error '%U'", format_unformat_error, input);
17270           return -99;
17271         }
17272     }
17273
17274   if (!bd_set)
17275     {
17276       errmsg ("Expected bridge domain!");
17277       return -99;
17278     }
17279
17280   M (ONE_NDP_ENTRIES_GET, mp);
17281   mp->bd = clib_host_to_net_u32 (bd);
17282
17283   /* send */
17284   S (mp);
17285
17286   /* wait for reply */
17287   W (ret);
17288   return ret;
17289 }
17290
17291 static int
17292 api_one_l2_arp_bd_get (vat_main_t * vam)
17293 {
17294   vl_api_one_l2_arp_bd_get_t *mp;
17295   int ret;
17296
17297   M (ONE_L2_ARP_BD_GET, mp);
17298
17299   /* send */
17300   S (mp);
17301
17302   /* wait for reply */
17303   W (ret);
17304   return ret;
17305 }
17306
17307 static int
17308 api_one_l2_arp_entries_get (vat_main_t * vam)
17309 {
17310   vl_api_one_l2_arp_entries_get_t *mp;
17311   unformat_input_t *input = vam->input;
17312   u8 bd_set = 0;
17313   u32 bd = ~0;
17314   int ret;
17315
17316   /* Parse args required to build the message */
17317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17318     {
17319       if (unformat (input, "bd %d", &bd))
17320         bd_set = 1;
17321       else
17322         {
17323           errmsg ("parse error '%U'", format_unformat_error, input);
17324           return -99;
17325         }
17326     }
17327
17328   if (!bd_set)
17329     {
17330       errmsg ("Expected bridge domain!");
17331       return -99;
17332     }
17333
17334   M (ONE_L2_ARP_ENTRIES_GET, mp);
17335   mp->bd = clib_host_to_net_u32 (bd);
17336
17337   /* send */
17338   S (mp);
17339
17340   /* wait for reply */
17341   W (ret);
17342   return ret;
17343 }
17344
17345 static int
17346 api_one_stats_enable_disable (vat_main_t * vam)
17347 {
17348   vl_api_one_stats_enable_disable_t *mp;
17349   unformat_input_t *input = vam->input;
17350   u8 is_set = 0;
17351   u8 is_en = 0;
17352   int ret;
17353
17354   /* Parse args required to build the message */
17355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17356     {
17357       if (unformat (input, "enable"))
17358         {
17359           is_set = 1;
17360           is_en = 1;
17361         }
17362       else if (unformat (input, "disable"))
17363         {
17364           is_set = 1;
17365         }
17366       else
17367         break;
17368     }
17369
17370   if (!is_set)
17371     {
17372       errmsg ("Value not set");
17373       return -99;
17374     }
17375
17376   M (ONE_STATS_ENABLE_DISABLE, mp);
17377   mp->is_en = is_en;
17378
17379   /* send */
17380   S (mp);
17381
17382   /* wait for reply */
17383   W (ret);
17384   return ret;
17385 }
17386
17387 static int
17388 api_show_one_stats_enable_disable (vat_main_t * vam)
17389 {
17390   vl_api_show_one_stats_enable_disable_t *mp;
17391   int ret;
17392
17393   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17394
17395   /* send */
17396   S (mp);
17397
17398   /* wait for reply */
17399   W (ret);
17400   return ret;
17401 }
17402
17403 static int
17404 api_show_one_map_request_mode (vat_main_t * vam)
17405 {
17406   vl_api_show_one_map_request_mode_t *mp;
17407   int ret;
17408
17409   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17410
17411   /* send */
17412   S (mp);
17413
17414   /* wait for reply */
17415   W (ret);
17416   return ret;
17417 }
17418
17419 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17420
17421 static int
17422 api_one_map_request_mode (vat_main_t * vam)
17423 {
17424   unformat_input_t *input = vam->input;
17425   vl_api_one_map_request_mode_t *mp;
17426   u8 mode = 0;
17427   int ret;
17428
17429   /* Parse args required to build the message */
17430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17431     {
17432       if (unformat (input, "dst-only"))
17433         mode = 0;
17434       else if (unformat (input, "src-dst"))
17435         mode = 1;
17436       else
17437         {
17438           errmsg ("parse error '%U'", format_unformat_error, input);
17439           return -99;
17440         }
17441     }
17442
17443   M (ONE_MAP_REQUEST_MODE, mp);
17444
17445   mp->mode = mode;
17446
17447   /* send */
17448   S (mp);
17449
17450   /* wait for reply */
17451   W (ret);
17452   return ret;
17453 }
17454
17455 #define api_lisp_map_request_mode api_one_map_request_mode
17456
17457 /**
17458  * Enable/disable ONE proxy ITR.
17459  *
17460  * @param vam vpp API test context
17461  * @return return code
17462  */
17463 static int
17464 api_one_pitr_set_locator_set (vat_main_t * vam)
17465 {
17466   u8 ls_name_set = 0;
17467   unformat_input_t *input = vam->input;
17468   vl_api_one_pitr_set_locator_set_t *mp;
17469   u8 is_add = 1;
17470   u8 *ls_name = 0;
17471   int ret;
17472
17473   /* Parse args required to build the message */
17474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17475     {
17476       if (unformat (input, "del"))
17477         is_add = 0;
17478       else if (unformat (input, "locator-set %s", &ls_name))
17479         ls_name_set = 1;
17480       else
17481         {
17482           errmsg ("parse error '%U'", format_unformat_error, input);
17483           return -99;
17484         }
17485     }
17486
17487   if (!ls_name_set)
17488     {
17489       errmsg ("locator-set name not set!");
17490       return -99;
17491     }
17492
17493   M (ONE_PITR_SET_LOCATOR_SET, mp);
17494
17495   mp->is_add = is_add;
17496   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17497   vec_free (ls_name);
17498
17499   /* send */
17500   S (mp);
17501
17502   /* wait for reply */
17503   W (ret);
17504   return ret;
17505 }
17506
17507 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17508
17509 static int
17510 api_one_nsh_set_locator_set (vat_main_t * vam)
17511 {
17512   u8 ls_name_set = 0;
17513   unformat_input_t *input = vam->input;
17514   vl_api_one_nsh_set_locator_set_t *mp;
17515   u8 is_add = 1;
17516   u8 *ls_name = 0;
17517   int ret;
17518
17519   /* Parse args required to build the message */
17520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17521     {
17522       if (unformat (input, "del"))
17523         is_add = 0;
17524       else if (unformat (input, "ls %s", &ls_name))
17525         ls_name_set = 1;
17526       else
17527         {
17528           errmsg ("parse error '%U'", format_unformat_error, input);
17529           return -99;
17530         }
17531     }
17532
17533   if (!ls_name_set && is_add)
17534     {
17535       errmsg ("locator-set name not set!");
17536       return -99;
17537     }
17538
17539   M (ONE_NSH_SET_LOCATOR_SET, mp);
17540
17541   mp->is_add = is_add;
17542   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17543   vec_free (ls_name);
17544
17545   /* send */
17546   S (mp);
17547
17548   /* wait for reply */
17549   W (ret);
17550   return ret;
17551 }
17552
17553 static int
17554 api_show_one_pitr (vat_main_t * vam)
17555 {
17556   vl_api_show_one_pitr_t *mp;
17557   int ret;
17558
17559   if (!vam->json_output)
17560     {
17561       print (vam->ofp, "%=20s", "lisp status:");
17562     }
17563
17564   M (SHOW_ONE_PITR, mp);
17565   /* send it... */
17566   S (mp);
17567
17568   /* Wait for a reply... */
17569   W (ret);
17570   return ret;
17571 }
17572
17573 #define api_show_lisp_pitr api_show_one_pitr
17574
17575 static int
17576 api_one_use_petr (vat_main_t * vam)
17577 {
17578   unformat_input_t *input = vam->input;
17579   vl_api_one_use_petr_t *mp;
17580   u8 is_add = 0;
17581   ip_address_t ip;
17582   int ret;
17583
17584   memset (&ip, 0, sizeof (ip));
17585
17586   /* Parse args required to build the message */
17587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17588     {
17589       if (unformat (input, "disable"))
17590         is_add = 0;
17591       else
17592         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17593         {
17594           is_add = 1;
17595           ip_addr_version (&ip) = IP4;
17596         }
17597       else
17598         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17599         {
17600           is_add = 1;
17601           ip_addr_version (&ip) = IP6;
17602         }
17603       else
17604         {
17605           errmsg ("parse error '%U'", format_unformat_error, input);
17606           return -99;
17607         }
17608     }
17609
17610   M (ONE_USE_PETR, mp);
17611
17612   mp->is_add = is_add;
17613   if (is_add)
17614     {
17615       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17616       if (mp->is_ip4)
17617         clib_memcpy (mp->address, &ip, 4);
17618       else
17619         clib_memcpy (mp->address, &ip, 16);
17620     }
17621
17622   /* send */
17623   S (mp);
17624
17625   /* wait for reply */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 #define api_lisp_use_petr api_one_use_petr
17631
17632 static int
17633 api_show_one_nsh_mapping (vat_main_t * vam)
17634 {
17635   vl_api_show_one_use_petr_t *mp;
17636   int ret;
17637
17638   if (!vam->json_output)
17639     {
17640       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17641     }
17642
17643   M (SHOW_ONE_NSH_MAPPING, mp);
17644   /* send it... */
17645   S (mp);
17646
17647   /* Wait for a reply... */
17648   W (ret);
17649   return ret;
17650 }
17651
17652 static int
17653 api_show_one_use_petr (vat_main_t * vam)
17654 {
17655   vl_api_show_one_use_petr_t *mp;
17656   int ret;
17657
17658   if (!vam->json_output)
17659     {
17660       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17661     }
17662
17663   M (SHOW_ONE_USE_PETR, mp);
17664   /* send it... */
17665   S (mp);
17666
17667   /* Wait for a reply... */
17668   W (ret);
17669   return ret;
17670 }
17671
17672 #define api_show_lisp_use_petr api_show_one_use_petr
17673
17674 /**
17675  * Add/delete mapping between vni and vrf
17676  */
17677 static int
17678 api_one_eid_table_add_del_map (vat_main_t * vam)
17679 {
17680   unformat_input_t *input = vam->input;
17681   vl_api_one_eid_table_add_del_map_t *mp;
17682   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17683   u32 vni, vrf, bd_index;
17684   int ret;
17685
17686   /* Parse args required to build the message */
17687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17688     {
17689       if (unformat (input, "del"))
17690         is_add = 0;
17691       else if (unformat (input, "vrf %d", &vrf))
17692         vrf_set = 1;
17693       else if (unformat (input, "bd_index %d", &bd_index))
17694         bd_index_set = 1;
17695       else if (unformat (input, "vni %d", &vni))
17696         vni_set = 1;
17697       else
17698         break;
17699     }
17700
17701   if (!vni_set || (!vrf_set && !bd_index_set))
17702     {
17703       errmsg ("missing arguments!");
17704       return -99;
17705     }
17706
17707   if (vrf_set && bd_index_set)
17708     {
17709       errmsg ("error: both vrf and bd entered!");
17710       return -99;
17711     }
17712
17713   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17714
17715   mp->is_add = is_add;
17716   mp->vni = htonl (vni);
17717   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17718   mp->is_l2 = bd_index_set;
17719
17720   /* send */
17721   S (mp);
17722
17723   /* wait for reply */
17724   W (ret);
17725   return ret;
17726 }
17727
17728 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17729
17730 uword
17731 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17732 {
17733   u32 *action = va_arg (*args, u32 *);
17734   u8 *s = 0;
17735
17736   if (unformat (input, "%s", &s))
17737     {
17738       if (!strcmp ((char *) s, "no-action"))
17739         action[0] = 0;
17740       else if (!strcmp ((char *) s, "natively-forward"))
17741         action[0] = 1;
17742       else if (!strcmp ((char *) s, "send-map-request"))
17743         action[0] = 2;
17744       else if (!strcmp ((char *) s, "drop"))
17745         action[0] = 3;
17746       else
17747         {
17748           clib_warning ("invalid action: '%s'", s);
17749           action[0] = 3;
17750         }
17751     }
17752   else
17753     return 0;
17754
17755   vec_free (s);
17756   return 1;
17757 }
17758
17759 /**
17760  * Add/del remote mapping to/from ONE control plane
17761  *
17762  * @param vam vpp API test context
17763  * @return return code
17764  */
17765 static int
17766 api_one_add_del_remote_mapping (vat_main_t * vam)
17767 {
17768   unformat_input_t *input = vam->input;
17769   vl_api_one_add_del_remote_mapping_t *mp;
17770   u32 vni = 0;
17771   lisp_eid_vat_t _eid, *eid = &_eid;
17772   lisp_eid_vat_t _seid, *seid = &_seid;
17773   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17774   u32 action = ~0, p, w, data_len;
17775   ip4_address_t rloc4;
17776   ip6_address_t rloc6;
17777   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17778   int ret;
17779
17780   memset (&rloc, 0, sizeof (rloc));
17781
17782   /* Parse args required to build the message */
17783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17784     {
17785       if (unformat (input, "del-all"))
17786         {
17787           del_all = 1;
17788         }
17789       else if (unformat (input, "del"))
17790         {
17791           is_add = 0;
17792         }
17793       else if (unformat (input, "add"))
17794         {
17795           is_add = 1;
17796         }
17797       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17798         {
17799           eid_set = 1;
17800         }
17801       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17802         {
17803           seid_set = 1;
17804         }
17805       else if (unformat (input, "vni %d", &vni))
17806         {
17807           ;
17808         }
17809       else if (unformat (input, "p %d w %d", &p, &w))
17810         {
17811           if (!curr_rloc)
17812             {
17813               errmsg ("No RLOC configured for setting priority/weight!");
17814               return -99;
17815             }
17816           curr_rloc->priority = p;
17817           curr_rloc->weight = w;
17818         }
17819       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17820         {
17821           rloc.is_ip4 = 1;
17822           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17823           vec_add1 (rlocs, rloc);
17824           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17825         }
17826       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17827         {
17828           rloc.is_ip4 = 0;
17829           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17830           vec_add1 (rlocs, rloc);
17831           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17832         }
17833       else if (unformat (input, "action %U",
17834                          unformat_negative_mapping_action, &action))
17835         {
17836           ;
17837         }
17838       else
17839         {
17840           clib_warning ("parse error '%U'", format_unformat_error, input);
17841           return -99;
17842         }
17843     }
17844
17845   if (0 == eid_set)
17846     {
17847       errmsg ("missing params!");
17848       return -99;
17849     }
17850
17851   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17852     {
17853       errmsg ("no action set for negative map-reply!");
17854       return -99;
17855     }
17856
17857   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17858
17859   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17860   mp->is_add = is_add;
17861   mp->vni = htonl (vni);
17862   mp->action = (u8) action;
17863   mp->is_src_dst = seid_set;
17864   mp->eid_len = eid->len;
17865   mp->seid_len = seid->len;
17866   mp->del_all = del_all;
17867   mp->eid_type = eid->type;
17868   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17869   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17870
17871   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17872   clib_memcpy (mp->rlocs, rlocs, data_len);
17873   vec_free (rlocs);
17874
17875   /* send it... */
17876   S (mp);
17877
17878   /* Wait for a reply... */
17879   W (ret);
17880   return ret;
17881 }
17882
17883 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17884
17885 /**
17886  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17887  * forwarding entries in data-plane accordingly.
17888  *
17889  * @param vam vpp API test context
17890  * @return return code
17891  */
17892 static int
17893 api_one_add_del_adjacency (vat_main_t * vam)
17894 {
17895   unformat_input_t *input = vam->input;
17896   vl_api_one_add_del_adjacency_t *mp;
17897   u32 vni = 0;
17898   ip4_address_t leid4, reid4;
17899   ip6_address_t leid6, reid6;
17900   u8 reid_mac[6] = { 0 };
17901   u8 leid_mac[6] = { 0 };
17902   u8 reid_type, leid_type;
17903   u32 leid_len = 0, reid_len = 0, len;
17904   u8 is_add = 1;
17905   int ret;
17906
17907   leid_type = reid_type = (u8) ~ 0;
17908
17909   /* Parse args required to build the message */
17910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17911     {
17912       if (unformat (input, "del"))
17913         {
17914           is_add = 0;
17915         }
17916       else if (unformat (input, "add"))
17917         {
17918           is_add = 1;
17919         }
17920       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17921                          &reid4, &len))
17922         {
17923           reid_type = 0;        /* ipv4 */
17924           reid_len = len;
17925         }
17926       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17927                          &reid6, &len))
17928         {
17929           reid_type = 1;        /* ipv6 */
17930           reid_len = len;
17931         }
17932       else if (unformat (input, "reid %U", unformat_ethernet_address,
17933                          reid_mac))
17934         {
17935           reid_type = 2;        /* mac */
17936         }
17937       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17938                          &leid4, &len))
17939         {
17940           leid_type = 0;        /* ipv4 */
17941           leid_len = len;
17942         }
17943       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17944                          &leid6, &len))
17945         {
17946           leid_type = 1;        /* ipv6 */
17947           leid_len = len;
17948         }
17949       else if (unformat (input, "leid %U", unformat_ethernet_address,
17950                          leid_mac))
17951         {
17952           leid_type = 2;        /* mac */
17953         }
17954       else if (unformat (input, "vni %d", &vni))
17955         {
17956           ;
17957         }
17958       else
17959         {
17960           errmsg ("parse error '%U'", format_unformat_error, input);
17961           return -99;
17962         }
17963     }
17964
17965   if ((u8) ~ 0 == reid_type)
17966     {
17967       errmsg ("missing params!");
17968       return -99;
17969     }
17970
17971   if (leid_type != reid_type)
17972     {
17973       errmsg ("remote and local EIDs are of different types!");
17974       return -99;
17975     }
17976
17977   M (ONE_ADD_DEL_ADJACENCY, mp);
17978   mp->is_add = is_add;
17979   mp->vni = htonl (vni);
17980   mp->leid_len = leid_len;
17981   mp->reid_len = reid_len;
17982   mp->eid_type = reid_type;
17983
17984   switch (mp->eid_type)
17985     {
17986     case 0:
17987       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17988       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17989       break;
17990     case 1:
17991       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17992       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17993       break;
17994     case 2:
17995       clib_memcpy (mp->leid, leid_mac, 6);
17996       clib_memcpy (mp->reid, reid_mac, 6);
17997       break;
17998     default:
17999       errmsg ("unknown EID type %d!", mp->eid_type);
18000       return 0;
18001     }
18002
18003   /* send it... */
18004   S (mp);
18005
18006   /* Wait for a reply... */
18007   W (ret);
18008   return ret;
18009 }
18010
18011 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18012
18013 uword
18014 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18015 {
18016   u32 *mode = va_arg (*args, u32 *);
18017
18018   if (unformat (input, "lisp"))
18019     *mode = 0;
18020   else if (unformat (input, "vxlan"))
18021     *mode = 1;
18022   else
18023     return 0;
18024
18025   return 1;
18026 }
18027
18028 static int
18029 api_gpe_get_encap_mode (vat_main_t * vam)
18030 {
18031   vl_api_gpe_get_encap_mode_t *mp;
18032   int ret;
18033
18034   /* Construct the API message */
18035   M (GPE_GET_ENCAP_MODE, mp);
18036
18037   /* send it... */
18038   S (mp);
18039
18040   /* Wait for a reply... */
18041   W (ret);
18042   return ret;
18043 }
18044
18045 static int
18046 api_gpe_set_encap_mode (vat_main_t * vam)
18047 {
18048   unformat_input_t *input = vam->input;
18049   vl_api_gpe_set_encap_mode_t *mp;
18050   int ret;
18051   u32 mode = 0;
18052
18053   /* Parse args required to build the message */
18054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18055     {
18056       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18057         ;
18058       else
18059         break;
18060     }
18061
18062   /* Construct the API message */
18063   M (GPE_SET_ENCAP_MODE, mp);
18064
18065   mp->mode = mode;
18066
18067   /* send it... */
18068   S (mp);
18069
18070   /* Wait for a reply... */
18071   W (ret);
18072   return ret;
18073 }
18074
18075 static int
18076 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18077 {
18078   unformat_input_t *input = vam->input;
18079   vl_api_gpe_add_del_iface_t *mp;
18080   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18081   u32 dp_table = 0, vni = 0;
18082   int ret;
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "up"))
18088         {
18089           action_set = 1;
18090           is_add = 1;
18091         }
18092       else if (unformat (input, "down"))
18093         {
18094           action_set = 1;
18095           is_add = 0;
18096         }
18097       else if (unformat (input, "table_id %d", &dp_table))
18098         {
18099           dp_table_set = 1;
18100         }
18101       else if (unformat (input, "bd_id %d", &dp_table))
18102         {
18103           dp_table_set = 1;
18104           is_l2 = 1;
18105         }
18106       else if (unformat (input, "vni %d", &vni))
18107         {
18108           vni_set = 1;
18109         }
18110       else
18111         break;
18112     }
18113
18114   if (action_set == 0)
18115     {
18116       errmsg ("Action not set");
18117       return -99;
18118     }
18119   if (dp_table_set == 0 || vni_set == 0)
18120     {
18121       errmsg ("vni and dp_table must be set");
18122       return -99;
18123     }
18124
18125   /* Construct the API message */
18126   M (GPE_ADD_DEL_IFACE, mp);
18127
18128   mp->is_add = is_add;
18129   mp->dp_table = clib_host_to_net_u32 (dp_table);
18130   mp->is_l2 = is_l2;
18131   mp->vni = clib_host_to_net_u32 (vni);
18132
18133   /* send it... */
18134   S (mp);
18135
18136   /* Wait for a reply... */
18137   W (ret);
18138   return ret;
18139 }
18140
18141 static int
18142 api_one_map_register_fallback_threshold (vat_main_t * vam)
18143 {
18144   unformat_input_t *input = vam->input;
18145   vl_api_one_map_register_fallback_threshold_t *mp;
18146   u32 value = 0;
18147   u8 is_set = 0;
18148   int ret;
18149
18150   /* Parse args required to build the message */
18151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18152     {
18153       if (unformat (input, "%u", &value))
18154         is_set = 1;
18155       else
18156         {
18157           clib_warning ("parse error '%U'", format_unformat_error, input);
18158           return -99;
18159         }
18160     }
18161
18162   if (!is_set)
18163     {
18164       errmsg ("fallback threshold value is missing!");
18165       return -99;
18166     }
18167
18168   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18169   mp->value = clib_host_to_net_u32 (value);
18170
18171   /* send it... */
18172   S (mp);
18173
18174   /* Wait for a reply... */
18175   W (ret);
18176   return ret;
18177 }
18178
18179 static int
18180 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18181 {
18182   vl_api_show_one_map_register_fallback_threshold_t *mp;
18183   int ret;
18184
18185   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18186
18187   /* send it... */
18188   S (mp);
18189
18190   /* Wait for a reply... */
18191   W (ret);
18192   return ret;
18193 }
18194
18195 uword
18196 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18197 {
18198   u32 *proto = va_arg (*args, u32 *);
18199
18200   if (unformat (input, "udp"))
18201     *proto = 1;
18202   else if (unformat (input, "api"))
18203     *proto = 2;
18204   else
18205     return 0;
18206
18207   return 1;
18208 }
18209
18210 static int
18211 api_one_set_transport_protocol (vat_main_t * vam)
18212 {
18213   unformat_input_t *input = vam->input;
18214   vl_api_one_set_transport_protocol_t *mp;
18215   u8 is_set = 0;
18216   u32 protocol = 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, "%U", unformat_lisp_transport_protocol, &protocol))
18223         is_set = 1;
18224       else
18225         {
18226           clib_warning ("parse error '%U'", format_unformat_error, input);
18227           return -99;
18228         }
18229     }
18230
18231   if (!is_set)
18232     {
18233       errmsg ("Transport protocol missing!");
18234       return -99;
18235     }
18236
18237   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18238   mp->protocol = (u8) protocol;
18239
18240   /* send it... */
18241   S (mp);
18242
18243   /* Wait for a reply... */
18244   W (ret);
18245   return ret;
18246 }
18247
18248 static int
18249 api_one_get_transport_protocol (vat_main_t * vam)
18250 {
18251   vl_api_one_get_transport_protocol_t *mp;
18252   int ret;
18253
18254   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18255
18256   /* send it... */
18257   S (mp);
18258
18259   /* Wait for a reply... */
18260   W (ret);
18261   return ret;
18262 }
18263
18264 static int
18265 api_one_map_register_set_ttl (vat_main_t * vam)
18266 {
18267   unformat_input_t *input = vam->input;
18268   vl_api_one_map_register_set_ttl_t *mp;
18269   u32 ttl = 0;
18270   u8 is_set = 0;
18271   int ret;
18272
18273   /* Parse args required to build the message */
18274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18275     {
18276       if (unformat (input, "%u", &ttl))
18277         is_set = 1;
18278       else
18279         {
18280           clib_warning ("parse error '%U'", format_unformat_error, input);
18281           return -99;
18282         }
18283     }
18284
18285   if (!is_set)
18286     {
18287       errmsg ("TTL value missing!");
18288       return -99;
18289     }
18290
18291   M (ONE_MAP_REGISTER_SET_TTL, mp);
18292   mp->ttl = clib_host_to_net_u32 (ttl);
18293
18294   /* send it... */
18295   S (mp);
18296
18297   /* Wait for a reply... */
18298   W (ret);
18299   return ret;
18300 }
18301
18302 static int
18303 api_show_one_map_register_ttl (vat_main_t * vam)
18304 {
18305   vl_api_show_one_map_register_ttl_t *mp;
18306   int ret;
18307
18308   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18309
18310   /* send it... */
18311   S (mp);
18312
18313   /* Wait for a reply... */
18314   W (ret);
18315   return ret;
18316 }
18317
18318 /**
18319  * Add/del map request itr rlocs from ONE control plane and updates
18320  *
18321  * @param vam vpp API test context
18322  * @return return code
18323  */
18324 static int
18325 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18326 {
18327   unformat_input_t *input = vam->input;
18328   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18329   u8 *locator_set_name = 0;
18330   u8 locator_set_name_set = 0;
18331   u8 is_add = 1;
18332   int ret;
18333
18334   /* Parse args required to build the message */
18335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18336     {
18337       if (unformat (input, "del"))
18338         {
18339           is_add = 0;
18340         }
18341       else if (unformat (input, "%_%v%_", &locator_set_name))
18342         {
18343           locator_set_name_set = 1;
18344         }
18345       else
18346         {
18347           clib_warning ("parse error '%U'", format_unformat_error, input);
18348           return -99;
18349         }
18350     }
18351
18352   if (is_add && !locator_set_name_set)
18353     {
18354       errmsg ("itr-rloc is not set!");
18355       return -99;
18356     }
18357
18358   if (is_add && vec_len (locator_set_name) > 64)
18359     {
18360       errmsg ("itr-rloc locator-set name too long");
18361       vec_free (locator_set_name);
18362       return -99;
18363     }
18364
18365   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18366   mp->is_add = is_add;
18367   if (is_add)
18368     {
18369       clib_memcpy (mp->locator_set_name, locator_set_name,
18370                    vec_len (locator_set_name));
18371     }
18372   else
18373     {
18374       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18375     }
18376   vec_free (locator_set_name);
18377
18378   /* send it... */
18379   S (mp);
18380
18381   /* Wait for a reply... */
18382   W (ret);
18383   return ret;
18384 }
18385
18386 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18387
18388 static int
18389 api_one_locator_dump (vat_main_t * vam)
18390 {
18391   unformat_input_t *input = vam->input;
18392   vl_api_one_locator_dump_t *mp;
18393   vl_api_control_ping_t *mp_ping;
18394   u8 is_index_set = 0, is_name_set = 0;
18395   u8 *ls_name = 0;
18396   u32 ls_index = ~0;
18397   int ret;
18398
18399   /* Parse args required to build the message */
18400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18401     {
18402       if (unformat (input, "ls_name %_%v%_", &ls_name))
18403         {
18404           is_name_set = 1;
18405         }
18406       else if (unformat (input, "ls_index %d", &ls_index))
18407         {
18408           is_index_set = 1;
18409         }
18410       else
18411         {
18412           errmsg ("parse error '%U'", format_unformat_error, input);
18413           return -99;
18414         }
18415     }
18416
18417   if (!is_index_set && !is_name_set)
18418     {
18419       errmsg ("error: expected one of index or name!");
18420       return -99;
18421     }
18422
18423   if (is_index_set && is_name_set)
18424     {
18425       errmsg ("error: only one param expected!");
18426       return -99;
18427     }
18428
18429   if (vec_len (ls_name) > 62)
18430     {
18431       errmsg ("error: locator set name too long!");
18432       return -99;
18433     }
18434
18435   if (!vam->json_output)
18436     {
18437       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18438     }
18439
18440   M (ONE_LOCATOR_DUMP, mp);
18441   mp->is_index_set = is_index_set;
18442
18443   if (is_index_set)
18444     mp->ls_index = clib_host_to_net_u32 (ls_index);
18445   else
18446     {
18447       vec_add1 (ls_name, 0);
18448       strncpy ((char *) mp->ls_name, (char *) ls_name,
18449                sizeof (mp->ls_name) - 1);
18450     }
18451
18452   /* send it... */
18453   S (mp);
18454
18455   /* Use a control ping for synchronization */
18456   MPING (CONTROL_PING, mp_ping);
18457   S (mp_ping);
18458
18459   /* Wait for a reply... */
18460   W (ret);
18461   return ret;
18462 }
18463
18464 #define api_lisp_locator_dump api_one_locator_dump
18465
18466 static int
18467 api_one_locator_set_dump (vat_main_t * vam)
18468 {
18469   vl_api_one_locator_set_dump_t *mp;
18470   vl_api_control_ping_t *mp_ping;
18471   unformat_input_t *input = vam->input;
18472   u8 filter = 0;
18473   int ret;
18474
18475   /* Parse args required to build the message */
18476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18477     {
18478       if (unformat (input, "local"))
18479         {
18480           filter = 1;
18481         }
18482       else if (unformat (input, "remote"))
18483         {
18484           filter = 2;
18485         }
18486       else
18487         {
18488           errmsg ("parse error '%U'", format_unformat_error, input);
18489           return -99;
18490         }
18491     }
18492
18493   if (!vam->json_output)
18494     {
18495       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18496     }
18497
18498   M (ONE_LOCATOR_SET_DUMP, mp);
18499
18500   mp->filter = filter;
18501
18502   /* send it... */
18503   S (mp);
18504
18505   /* Use a control ping for synchronization */
18506   MPING (CONTROL_PING, mp_ping);
18507   S (mp_ping);
18508
18509   /* Wait for a reply... */
18510   W (ret);
18511   return ret;
18512 }
18513
18514 #define api_lisp_locator_set_dump api_one_locator_set_dump
18515
18516 static int
18517 api_one_eid_table_map_dump (vat_main_t * vam)
18518 {
18519   u8 is_l2 = 0;
18520   u8 mode_set = 0;
18521   unformat_input_t *input = vam->input;
18522   vl_api_one_eid_table_map_dump_t *mp;
18523   vl_api_control_ping_t *mp_ping;
18524   int ret;
18525
18526   /* Parse args required to build the message */
18527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18528     {
18529       if (unformat (input, "l2"))
18530         {
18531           is_l2 = 1;
18532           mode_set = 1;
18533         }
18534       else if (unformat (input, "l3"))
18535         {
18536           is_l2 = 0;
18537           mode_set = 1;
18538         }
18539       else
18540         {
18541           errmsg ("parse error '%U'", format_unformat_error, input);
18542           return -99;
18543         }
18544     }
18545
18546   if (!mode_set)
18547     {
18548       errmsg ("expected one of 'l2' or 'l3' parameter!");
18549       return -99;
18550     }
18551
18552   if (!vam->json_output)
18553     {
18554       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18555     }
18556
18557   M (ONE_EID_TABLE_MAP_DUMP, mp);
18558   mp->is_l2 = is_l2;
18559
18560   /* send it... */
18561   S (mp);
18562
18563   /* Use a control ping for synchronization */
18564   MPING (CONTROL_PING, mp_ping);
18565   S (mp_ping);
18566
18567   /* Wait for a reply... */
18568   W (ret);
18569   return ret;
18570 }
18571
18572 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18573
18574 static int
18575 api_one_eid_table_vni_dump (vat_main_t * vam)
18576 {
18577   vl_api_one_eid_table_vni_dump_t *mp;
18578   vl_api_control_ping_t *mp_ping;
18579   int ret;
18580
18581   if (!vam->json_output)
18582     {
18583       print (vam->ofp, "VNI");
18584     }
18585
18586   M (ONE_EID_TABLE_VNI_DUMP, mp);
18587
18588   /* send it... */
18589   S (mp);
18590
18591   /* Use a control ping for synchronization */
18592   MPING (CONTROL_PING, mp_ping);
18593   S (mp_ping);
18594
18595   /* Wait for a reply... */
18596   W (ret);
18597   return ret;
18598 }
18599
18600 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18601
18602 static int
18603 api_one_eid_table_dump (vat_main_t * vam)
18604 {
18605   unformat_input_t *i = vam->input;
18606   vl_api_one_eid_table_dump_t *mp;
18607   vl_api_control_ping_t *mp_ping;
18608   struct in_addr ip4;
18609   struct in6_addr ip6;
18610   u8 mac[6];
18611   u8 eid_type = ~0, eid_set = 0;
18612   u32 prefix_length = ~0, t, vni = 0;
18613   u8 filter = 0;
18614   int ret;
18615   lisp_nsh_api_t nsh;
18616
18617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18618     {
18619       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18620         {
18621           eid_set = 1;
18622           eid_type = 0;
18623           prefix_length = t;
18624         }
18625       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18626         {
18627           eid_set = 1;
18628           eid_type = 1;
18629           prefix_length = t;
18630         }
18631       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18632         {
18633           eid_set = 1;
18634           eid_type = 2;
18635         }
18636       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18637         {
18638           eid_set = 1;
18639           eid_type = 3;
18640         }
18641       else if (unformat (i, "vni %d", &t))
18642         {
18643           vni = t;
18644         }
18645       else if (unformat (i, "local"))
18646         {
18647           filter = 1;
18648         }
18649       else if (unformat (i, "remote"))
18650         {
18651           filter = 2;
18652         }
18653       else
18654         {
18655           errmsg ("parse error '%U'", format_unformat_error, i);
18656           return -99;
18657         }
18658     }
18659
18660   if (!vam->json_output)
18661     {
18662       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18663              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18664     }
18665
18666   M (ONE_EID_TABLE_DUMP, mp);
18667
18668   mp->filter = filter;
18669   if (eid_set)
18670     {
18671       mp->eid_set = 1;
18672       mp->vni = htonl (vni);
18673       mp->eid_type = eid_type;
18674       switch (eid_type)
18675         {
18676         case 0:
18677           mp->prefix_length = prefix_length;
18678           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18679           break;
18680         case 1:
18681           mp->prefix_length = prefix_length;
18682           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18683           break;
18684         case 2:
18685           clib_memcpy (mp->eid, mac, sizeof (mac));
18686           break;
18687         case 3:
18688           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18689           break;
18690         default:
18691           errmsg ("unknown EID type %d!", eid_type);
18692           return -99;
18693         }
18694     }
18695
18696   /* send it... */
18697   S (mp);
18698
18699   /* Use a control ping for synchronization */
18700   MPING (CONTROL_PING, mp_ping);
18701   S (mp_ping);
18702
18703   /* Wait for a reply... */
18704   W (ret);
18705   return ret;
18706 }
18707
18708 #define api_lisp_eid_table_dump api_one_eid_table_dump
18709
18710 static int
18711 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18712 {
18713   unformat_input_t *i = vam->input;
18714   vl_api_gpe_fwd_entries_get_t *mp;
18715   u8 vni_set = 0;
18716   u32 vni = ~0;
18717   int ret;
18718
18719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18720     {
18721       if (unformat (i, "vni %d", &vni))
18722         {
18723           vni_set = 1;
18724         }
18725       else
18726         {
18727           errmsg ("parse error '%U'", format_unformat_error, i);
18728           return -99;
18729         }
18730     }
18731
18732   if (!vni_set)
18733     {
18734       errmsg ("vni not set!");
18735       return -99;
18736     }
18737
18738   if (!vam->json_output)
18739     {
18740       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18741              "leid", "reid");
18742     }
18743
18744   M (GPE_FWD_ENTRIES_GET, mp);
18745   mp->vni = clib_host_to_net_u32 (vni);
18746
18747   /* send it... */
18748   S (mp);
18749
18750   /* Wait for a reply... */
18751   W (ret);
18752   return ret;
18753 }
18754
18755 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18756 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18757 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18758 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18759 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18760 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18761 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18762 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18763
18764 static int
18765 api_one_adjacencies_get (vat_main_t * vam)
18766 {
18767   unformat_input_t *i = vam->input;
18768   vl_api_one_adjacencies_get_t *mp;
18769   u8 vni_set = 0;
18770   u32 vni = ~0;
18771   int ret;
18772
18773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18774     {
18775       if (unformat (i, "vni %d", &vni))
18776         {
18777           vni_set = 1;
18778         }
18779       else
18780         {
18781           errmsg ("parse error '%U'", format_unformat_error, i);
18782           return -99;
18783         }
18784     }
18785
18786   if (!vni_set)
18787     {
18788       errmsg ("vni not set!");
18789       return -99;
18790     }
18791
18792   if (!vam->json_output)
18793     {
18794       print (vam->ofp, "%s %40s", "leid", "reid");
18795     }
18796
18797   M (ONE_ADJACENCIES_GET, mp);
18798   mp->vni = clib_host_to_net_u32 (vni);
18799
18800   /* send it... */
18801   S (mp);
18802
18803   /* Wait for a reply... */
18804   W (ret);
18805   return ret;
18806 }
18807
18808 #define api_lisp_adjacencies_get api_one_adjacencies_get
18809
18810 static int
18811 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18812 {
18813   unformat_input_t *i = vam->input;
18814   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18815   int ret;
18816   u8 ip_family_set = 0, is_ip4 = 1;
18817
18818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18819     {
18820       if (unformat (i, "ip4"))
18821         {
18822           ip_family_set = 1;
18823           is_ip4 = 1;
18824         }
18825       else if (unformat (i, "ip6"))
18826         {
18827           ip_family_set = 1;
18828           is_ip4 = 0;
18829         }
18830       else
18831         {
18832           errmsg ("parse error '%U'", format_unformat_error, i);
18833           return -99;
18834         }
18835     }
18836
18837   if (!ip_family_set)
18838     {
18839       errmsg ("ip family not set!");
18840       return -99;
18841     }
18842
18843   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18844   mp->is_ip4 = is_ip4;
18845
18846   /* send it... */
18847   S (mp);
18848
18849   /* Wait for a reply... */
18850   W (ret);
18851   return ret;
18852 }
18853
18854 static int
18855 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18856 {
18857   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18858   int ret;
18859
18860   if (!vam->json_output)
18861     {
18862       print (vam->ofp, "VNIs");
18863     }
18864
18865   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18866
18867   /* send it... */
18868   S (mp);
18869
18870   /* Wait for a reply... */
18871   W (ret);
18872   return ret;
18873 }
18874
18875 static int
18876 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18877 {
18878   unformat_input_t *i = vam->input;
18879   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18880   int ret = 0;
18881   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18882   struct in_addr ip4;
18883   struct in6_addr ip6;
18884   u32 table_id = 0, nh_sw_if_index = ~0;
18885
18886   memset (&ip4, 0, sizeof (ip4));
18887   memset (&ip6, 0, sizeof (ip6));
18888
18889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18890     {
18891       if (unformat (i, "del"))
18892         is_add = 0;
18893       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18894                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18895         {
18896           ip_set = 1;
18897           is_ip4 = 1;
18898         }
18899       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18900                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18901         {
18902           ip_set = 1;
18903           is_ip4 = 0;
18904         }
18905       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18906         {
18907           ip_set = 1;
18908           is_ip4 = 1;
18909           nh_sw_if_index = ~0;
18910         }
18911       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18912         {
18913           ip_set = 1;
18914           is_ip4 = 0;
18915           nh_sw_if_index = ~0;
18916         }
18917       else if (unformat (i, "table %d", &table_id))
18918         ;
18919       else
18920         {
18921           errmsg ("parse error '%U'", format_unformat_error, i);
18922           return -99;
18923         }
18924     }
18925
18926   if (!ip_set)
18927     {
18928       errmsg ("nh addr not set!");
18929       return -99;
18930     }
18931
18932   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18933   mp->is_add = is_add;
18934   mp->table_id = clib_host_to_net_u32 (table_id);
18935   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18936   mp->is_ip4 = is_ip4;
18937   if (is_ip4)
18938     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18939   else
18940     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18941
18942   /* send it... */
18943   S (mp);
18944
18945   /* Wait for a reply... */
18946   W (ret);
18947   return ret;
18948 }
18949
18950 static int
18951 api_one_map_server_dump (vat_main_t * vam)
18952 {
18953   vl_api_one_map_server_dump_t *mp;
18954   vl_api_control_ping_t *mp_ping;
18955   int ret;
18956
18957   if (!vam->json_output)
18958     {
18959       print (vam->ofp, "%=20s", "Map server");
18960     }
18961
18962   M (ONE_MAP_SERVER_DUMP, mp);
18963   /* send it... */
18964   S (mp);
18965
18966   /* Use a control ping for synchronization */
18967   MPING (CONTROL_PING, mp_ping);
18968   S (mp_ping);
18969
18970   /* Wait for a reply... */
18971   W (ret);
18972   return ret;
18973 }
18974
18975 #define api_lisp_map_server_dump api_one_map_server_dump
18976
18977 static int
18978 api_one_map_resolver_dump (vat_main_t * vam)
18979 {
18980   vl_api_one_map_resolver_dump_t *mp;
18981   vl_api_control_ping_t *mp_ping;
18982   int ret;
18983
18984   if (!vam->json_output)
18985     {
18986       print (vam->ofp, "%=20s", "Map resolver");
18987     }
18988
18989   M (ONE_MAP_RESOLVER_DUMP, mp);
18990   /* send it... */
18991   S (mp);
18992
18993   /* Use a control ping for synchronization */
18994   MPING (CONTROL_PING, mp_ping);
18995   S (mp_ping);
18996
18997   /* Wait for a reply... */
18998   W (ret);
18999   return ret;
19000 }
19001
19002 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19003
19004 static int
19005 api_one_stats_flush (vat_main_t * vam)
19006 {
19007   vl_api_one_stats_flush_t *mp;
19008   int ret = 0;
19009
19010   M (ONE_STATS_FLUSH, mp);
19011   S (mp);
19012   W (ret);
19013   return ret;
19014 }
19015
19016 static int
19017 api_one_stats_dump (vat_main_t * vam)
19018 {
19019   vl_api_one_stats_dump_t *mp;
19020   vl_api_control_ping_t *mp_ping;
19021   int ret;
19022
19023   M (ONE_STATS_DUMP, mp);
19024   /* send it... */
19025   S (mp);
19026
19027   /* Use a control ping for synchronization */
19028   MPING (CONTROL_PING, mp_ping);
19029   S (mp_ping);
19030
19031   /* Wait for a reply... */
19032   W (ret);
19033   return ret;
19034 }
19035
19036 static int
19037 api_show_one_status (vat_main_t * vam)
19038 {
19039   vl_api_show_one_status_t *mp;
19040   int ret;
19041
19042   if (!vam->json_output)
19043     {
19044       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19045     }
19046
19047   M (SHOW_ONE_STATUS, mp);
19048   /* send it... */
19049   S (mp);
19050   /* Wait for a reply... */
19051   W (ret);
19052   return ret;
19053 }
19054
19055 #define api_show_lisp_status api_show_one_status
19056
19057 static int
19058 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19059 {
19060   vl_api_gpe_fwd_entry_path_dump_t *mp;
19061   vl_api_control_ping_t *mp_ping;
19062   unformat_input_t *i = vam->input;
19063   u32 fwd_entry_index = ~0;
19064   int ret;
19065
19066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19067     {
19068       if (unformat (i, "index %d", &fwd_entry_index))
19069         ;
19070       else
19071         break;
19072     }
19073
19074   if (~0 == fwd_entry_index)
19075     {
19076       errmsg ("no index specified!");
19077       return -99;
19078     }
19079
19080   if (!vam->json_output)
19081     {
19082       print (vam->ofp, "first line");
19083     }
19084
19085   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19086
19087   /* send it... */
19088   S (mp);
19089   /* Use a control ping for synchronization */
19090   MPING (CONTROL_PING, mp_ping);
19091   S (mp_ping);
19092
19093   /* Wait for a reply... */
19094   W (ret);
19095   return ret;
19096 }
19097
19098 static int
19099 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19100 {
19101   vl_api_one_get_map_request_itr_rlocs_t *mp;
19102   int ret;
19103
19104   if (!vam->json_output)
19105     {
19106       print (vam->ofp, "%=20s", "itr-rlocs:");
19107     }
19108
19109   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19110   /* send it... */
19111   S (mp);
19112   /* Wait for a reply... */
19113   W (ret);
19114   return ret;
19115 }
19116
19117 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19118
19119 static int
19120 api_af_packet_create (vat_main_t * vam)
19121 {
19122   unformat_input_t *i = vam->input;
19123   vl_api_af_packet_create_t *mp;
19124   u8 *host_if_name = 0;
19125   u8 hw_addr[6];
19126   u8 random_hw_addr = 1;
19127   int ret;
19128
19129   memset (hw_addr, 0, sizeof (hw_addr));
19130
19131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19132     {
19133       if (unformat (i, "name %s", &host_if_name))
19134         vec_add1 (host_if_name, 0);
19135       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19136         random_hw_addr = 0;
19137       else
19138         break;
19139     }
19140
19141   if (!vec_len (host_if_name))
19142     {
19143       errmsg ("host-interface name must be specified");
19144       return -99;
19145     }
19146
19147   if (vec_len (host_if_name) > 64)
19148     {
19149       errmsg ("host-interface name too long");
19150       return -99;
19151     }
19152
19153   M (AF_PACKET_CREATE, mp);
19154
19155   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19156   clib_memcpy (mp->hw_addr, hw_addr, 6);
19157   mp->use_random_hw_addr = random_hw_addr;
19158   vec_free (host_if_name);
19159
19160   S (mp);
19161
19162   /* *INDENT-OFF* */
19163   W2 (ret,
19164       ({
19165         if (ret == 0)
19166           fprintf (vam->ofp ? vam->ofp : stderr,
19167                    " new sw_if_index = %d\n", vam->sw_if_index);
19168       }));
19169   /* *INDENT-ON* */
19170   return ret;
19171 }
19172
19173 static int
19174 api_af_packet_delete (vat_main_t * vam)
19175 {
19176   unformat_input_t *i = vam->input;
19177   vl_api_af_packet_delete_t *mp;
19178   u8 *host_if_name = 0;
19179   int ret;
19180
19181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19182     {
19183       if (unformat (i, "name %s", &host_if_name))
19184         vec_add1 (host_if_name, 0);
19185       else
19186         break;
19187     }
19188
19189   if (!vec_len (host_if_name))
19190     {
19191       errmsg ("host-interface name must be specified");
19192       return -99;
19193     }
19194
19195   if (vec_len (host_if_name) > 64)
19196     {
19197       errmsg ("host-interface name too long");
19198       return -99;
19199     }
19200
19201   M (AF_PACKET_DELETE, mp);
19202
19203   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19204   vec_free (host_if_name);
19205
19206   S (mp);
19207   W (ret);
19208   return ret;
19209 }
19210
19211 static int
19212 api_policer_add_del (vat_main_t * vam)
19213 {
19214   unformat_input_t *i = vam->input;
19215   vl_api_policer_add_del_t *mp;
19216   u8 is_add = 1;
19217   u8 *name = 0;
19218   u32 cir = 0;
19219   u32 eir = 0;
19220   u64 cb = 0;
19221   u64 eb = 0;
19222   u8 rate_type = 0;
19223   u8 round_type = 0;
19224   u8 type = 0;
19225   u8 color_aware = 0;
19226   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19227   int ret;
19228
19229   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19230   conform_action.dscp = 0;
19231   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19232   exceed_action.dscp = 0;
19233   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19234   violate_action.dscp = 0;
19235
19236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19237     {
19238       if (unformat (i, "del"))
19239         is_add = 0;
19240       else if (unformat (i, "name %s", &name))
19241         vec_add1 (name, 0);
19242       else if (unformat (i, "cir %u", &cir))
19243         ;
19244       else if (unformat (i, "eir %u", &eir))
19245         ;
19246       else if (unformat (i, "cb %u", &cb))
19247         ;
19248       else if (unformat (i, "eb %u", &eb))
19249         ;
19250       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19251                          &rate_type))
19252         ;
19253       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19254                          &round_type))
19255         ;
19256       else if (unformat (i, "type %U", unformat_policer_type, &type))
19257         ;
19258       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19259                          &conform_action))
19260         ;
19261       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19262                          &exceed_action))
19263         ;
19264       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19265                          &violate_action))
19266         ;
19267       else if (unformat (i, "color-aware"))
19268         color_aware = 1;
19269       else
19270         break;
19271     }
19272
19273   if (!vec_len (name))
19274     {
19275       errmsg ("policer name must be specified");
19276       return -99;
19277     }
19278
19279   if (vec_len (name) > 64)
19280     {
19281       errmsg ("policer name too long");
19282       return -99;
19283     }
19284
19285   M (POLICER_ADD_DEL, mp);
19286
19287   clib_memcpy (mp->name, name, vec_len (name));
19288   vec_free (name);
19289   mp->is_add = is_add;
19290   mp->cir = ntohl (cir);
19291   mp->eir = ntohl (eir);
19292   mp->cb = clib_net_to_host_u64 (cb);
19293   mp->eb = clib_net_to_host_u64 (eb);
19294   mp->rate_type = rate_type;
19295   mp->round_type = round_type;
19296   mp->type = type;
19297   mp->conform_action_type = conform_action.action_type;
19298   mp->conform_dscp = conform_action.dscp;
19299   mp->exceed_action_type = exceed_action.action_type;
19300   mp->exceed_dscp = exceed_action.dscp;
19301   mp->violate_action_type = violate_action.action_type;
19302   mp->violate_dscp = violate_action.dscp;
19303   mp->color_aware = color_aware;
19304
19305   S (mp);
19306   W (ret);
19307   return ret;
19308 }
19309
19310 static int
19311 api_policer_dump (vat_main_t * vam)
19312 {
19313   unformat_input_t *i = vam->input;
19314   vl_api_policer_dump_t *mp;
19315   vl_api_control_ping_t *mp_ping;
19316   u8 *match_name = 0;
19317   u8 match_name_valid = 0;
19318   int ret;
19319
19320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19321     {
19322       if (unformat (i, "name %s", &match_name))
19323         {
19324           vec_add1 (match_name, 0);
19325           match_name_valid = 1;
19326         }
19327       else
19328         break;
19329     }
19330
19331   M (POLICER_DUMP, mp);
19332   mp->match_name_valid = match_name_valid;
19333   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19334   vec_free (match_name);
19335   /* send it... */
19336   S (mp);
19337
19338   /* Use a control ping for synchronization */
19339   MPING (CONTROL_PING, mp_ping);
19340   S (mp_ping);
19341
19342   /* Wait for a reply... */
19343   W (ret);
19344   return ret;
19345 }
19346
19347 static int
19348 api_policer_classify_set_interface (vat_main_t * vam)
19349 {
19350   unformat_input_t *i = vam->input;
19351   vl_api_policer_classify_set_interface_t *mp;
19352   u32 sw_if_index;
19353   int sw_if_index_set;
19354   u32 ip4_table_index = ~0;
19355   u32 ip6_table_index = ~0;
19356   u32 l2_table_index = ~0;
19357   u8 is_add = 1;
19358   int ret;
19359
19360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19361     {
19362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19363         sw_if_index_set = 1;
19364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19365         sw_if_index_set = 1;
19366       else if (unformat (i, "del"))
19367         is_add = 0;
19368       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19369         ;
19370       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19371         ;
19372       else if (unformat (i, "l2-table %d", &l2_table_index))
19373         ;
19374       else
19375         {
19376           clib_warning ("parse error '%U'", format_unformat_error, i);
19377           return -99;
19378         }
19379     }
19380
19381   if (sw_if_index_set == 0)
19382     {
19383       errmsg ("missing interface name or sw_if_index");
19384       return -99;
19385     }
19386
19387   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19388
19389   mp->sw_if_index = ntohl (sw_if_index);
19390   mp->ip4_table_index = ntohl (ip4_table_index);
19391   mp->ip6_table_index = ntohl (ip6_table_index);
19392   mp->l2_table_index = ntohl (l2_table_index);
19393   mp->is_add = is_add;
19394
19395   S (mp);
19396   W (ret);
19397   return ret;
19398 }
19399
19400 static int
19401 api_policer_classify_dump (vat_main_t * vam)
19402 {
19403   unformat_input_t *i = vam->input;
19404   vl_api_policer_classify_dump_t *mp;
19405   vl_api_control_ping_t *mp_ping;
19406   u8 type = POLICER_CLASSIFY_N_TABLES;
19407   int ret;
19408
19409   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19410     ;
19411   else
19412     {
19413       errmsg ("classify table type must be specified");
19414       return -99;
19415     }
19416
19417   if (!vam->json_output)
19418     {
19419       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19420     }
19421
19422   M (POLICER_CLASSIFY_DUMP, mp);
19423   mp->type = type;
19424   /* send it... */
19425   S (mp);
19426
19427   /* Use a control ping for synchronization */
19428   MPING (CONTROL_PING, mp_ping);
19429   S (mp_ping);
19430
19431   /* Wait for a reply... */
19432   W (ret);
19433   return ret;
19434 }
19435
19436 static int
19437 api_netmap_create (vat_main_t * vam)
19438 {
19439   unformat_input_t *i = vam->input;
19440   vl_api_netmap_create_t *mp;
19441   u8 *if_name = 0;
19442   u8 hw_addr[6];
19443   u8 random_hw_addr = 1;
19444   u8 is_pipe = 0;
19445   u8 is_master = 0;
19446   int ret;
19447
19448   memset (hw_addr, 0, sizeof (hw_addr));
19449
19450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19451     {
19452       if (unformat (i, "name %s", &if_name))
19453         vec_add1 (if_name, 0);
19454       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19455         random_hw_addr = 0;
19456       else if (unformat (i, "pipe"))
19457         is_pipe = 1;
19458       else if (unformat (i, "master"))
19459         is_master = 1;
19460       else if (unformat (i, "slave"))
19461         is_master = 0;
19462       else
19463         break;
19464     }
19465
19466   if (!vec_len (if_name))
19467     {
19468       errmsg ("interface name must be specified");
19469       return -99;
19470     }
19471
19472   if (vec_len (if_name) > 64)
19473     {
19474       errmsg ("interface name too long");
19475       return -99;
19476     }
19477
19478   M (NETMAP_CREATE, mp);
19479
19480   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19481   clib_memcpy (mp->hw_addr, hw_addr, 6);
19482   mp->use_random_hw_addr = random_hw_addr;
19483   mp->is_pipe = is_pipe;
19484   mp->is_master = is_master;
19485   vec_free (if_name);
19486
19487   S (mp);
19488   W (ret);
19489   return ret;
19490 }
19491
19492 static int
19493 api_netmap_delete (vat_main_t * vam)
19494 {
19495   unformat_input_t *i = vam->input;
19496   vl_api_netmap_delete_t *mp;
19497   u8 *if_name = 0;
19498   int ret;
19499
19500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19501     {
19502       if (unformat (i, "name %s", &if_name))
19503         vec_add1 (if_name, 0);
19504       else
19505         break;
19506     }
19507
19508   if (!vec_len (if_name))
19509     {
19510       errmsg ("interface name must be specified");
19511       return -99;
19512     }
19513
19514   if (vec_len (if_name) > 64)
19515     {
19516       errmsg ("interface name too long");
19517       return -99;
19518     }
19519
19520   M (NETMAP_DELETE, mp);
19521
19522   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19523   vec_free (if_name);
19524
19525   S (mp);
19526   W (ret);
19527   return ret;
19528 }
19529
19530 static void
19531 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19532 {
19533   if (fp->afi == IP46_TYPE_IP6)
19534     print (vam->ofp,
19535            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19536            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19537            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19538            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19539            format_ip6_address, fp->next_hop);
19540   else if (fp->afi == IP46_TYPE_IP4)
19541     print (vam->ofp,
19542            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19543            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19544            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19545            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19546            format_ip4_address, fp->next_hop);
19547 }
19548
19549 static void
19550 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19551                                  vl_api_fib_path2_t * fp)
19552 {
19553   struct in_addr ip4;
19554   struct in6_addr ip6;
19555
19556   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19557   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19558   vat_json_object_add_uint (node, "is_local", fp->is_local);
19559   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19560   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19561   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19562   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19563   if (fp->afi == IP46_TYPE_IP4)
19564     {
19565       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19566       vat_json_object_add_ip4 (node, "next_hop", ip4);
19567     }
19568   else if (fp->afi == IP46_TYPE_IP6)
19569     {
19570       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19571       vat_json_object_add_ip6 (node, "next_hop", ip6);
19572     }
19573 }
19574
19575 static void
19576 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19577 {
19578   vat_main_t *vam = &vat_main;
19579   int count = ntohl (mp->mt_count);
19580   vl_api_fib_path2_t *fp;
19581   i32 i;
19582
19583   print (vam->ofp, "[%d]: sw_if_index %d via:",
19584          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19585   fp = mp->mt_paths;
19586   for (i = 0; i < count; i++)
19587     {
19588       vl_api_mpls_fib_path_print (vam, fp);
19589       fp++;
19590     }
19591
19592   print (vam->ofp, "");
19593 }
19594
19595 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19596 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19597
19598 static void
19599 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19600 {
19601   vat_main_t *vam = &vat_main;
19602   vat_json_node_t *node = NULL;
19603   int count = ntohl (mp->mt_count);
19604   vl_api_fib_path2_t *fp;
19605   i32 i;
19606
19607   if (VAT_JSON_ARRAY != vam->json_tree.type)
19608     {
19609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19610       vat_json_init_array (&vam->json_tree);
19611     }
19612   node = vat_json_array_add (&vam->json_tree);
19613
19614   vat_json_init_object (node);
19615   vat_json_object_add_uint (node, "tunnel_index",
19616                             ntohl (mp->mt_tunnel_index));
19617   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19618
19619   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19620
19621   fp = mp->mt_paths;
19622   for (i = 0; i < count; i++)
19623     {
19624       vl_api_mpls_fib_path_json_print (node, fp);
19625       fp++;
19626     }
19627 }
19628
19629 static int
19630 api_mpls_tunnel_dump (vat_main_t * vam)
19631 {
19632   vl_api_mpls_tunnel_dump_t *mp;
19633   vl_api_control_ping_t *mp_ping;
19634   i32 index = -1;
19635   int ret;
19636
19637   /* Parse args required to build the message */
19638   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19639     {
19640       if (!unformat (vam->input, "tunnel_index %d", &index))
19641         {
19642           index = -1;
19643           break;
19644         }
19645     }
19646
19647   print (vam->ofp, "  tunnel_index %d", index);
19648
19649   M (MPLS_TUNNEL_DUMP, mp);
19650   mp->tunnel_index = htonl (index);
19651   S (mp);
19652
19653   /* Use a control ping for synchronization */
19654   MPING (CONTROL_PING, mp_ping);
19655   S (mp_ping);
19656
19657   W (ret);
19658   return ret;
19659 }
19660
19661 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19662 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19663
19664
19665 static void
19666 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19667 {
19668   vat_main_t *vam = &vat_main;
19669   int count = ntohl (mp->count);
19670   vl_api_fib_path2_t *fp;
19671   int i;
19672
19673   print (vam->ofp,
19674          "table-id %d, label %u, ess_bit %u",
19675          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19676   fp = mp->path;
19677   for (i = 0; i < count; i++)
19678     {
19679       vl_api_mpls_fib_path_print (vam, fp);
19680       fp++;
19681     }
19682 }
19683
19684 static void vl_api_mpls_fib_details_t_handler_json
19685   (vl_api_mpls_fib_details_t * mp)
19686 {
19687   vat_main_t *vam = &vat_main;
19688   int count = ntohl (mp->count);
19689   vat_json_node_t *node = NULL;
19690   vl_api_fib_path2_t *fp;
19691   int i;
19692
19693   if (VAT_JSON_ARRAY != vam->json_tree.type)
19694     {
19695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19696       vat_json_init_array (&vam->json_tree);
19697     }
19698   node = vat_json_array_add (&vam->json_tree);
19699
19700   vat_json_init_object (node);
19701   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19702   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19703   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19704   vat_json_object_add_uint (node, "path_count", count);
19705   fp = mp->path;
19706   for (i = 0; i < count; i++)
19707     {
19708       vl_api_mpls_fib_path_json_print (node, fp);
19709       fp++;
19710     }
19711 }
19712
19713 static int
19714 api_mpls_fib_dump (vat_main_t * vam)
19715 {
19716   vl_api_mpls_fib_dump_t *mp;
19717   vl_api_control_ping_t *mp_ping;
19718   int ret;
19719
19720   M (MPLS_FIB_DUMP, mp);
19721   S (mp);
19722
19723   /* Use a control ping for synchronization */
19724   MPING (CONTROL_PING, mp_ping);
19725   S (mp_ping);
19726
19727   W (ret);
19728   return ret;
19729 }
19730
19731 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19732 #define vl_api_ip_fib_details_t_print vl_noop_handler
19733
19734 static void
19735 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19736 {
19737   vat_main_t *vam = &vat_main;
19738   int count = ntohl (mp->count);
19739   vl_api_fib_path_t *fp;
19740   int i;
19741
19742   print (vam->ofp,
19743          "table-id %d, prefix %U/%d",
19744          ntohl (mp->table_id), format_ip4_address, mp->address,
19745          mp->address_length);
19746   fp = mp->path;
19747   for (i = 0; i < count; i++)
19748     {
19749       if (fp->afi == IP46_TYPE_IP6)
19750         print (vam->ofp,
19751                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19752                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19753                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19754                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19755                format_ip6_address, fp->next_hop);
19756       else if (fp->afi == IP46_TYPE_IP4)
19757         print (vam->ofp,
19758                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19759                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19760                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19761                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19762                format_ip4_address, fp->next_hop);
19763       fp++;
19764     }
19765 }
19766
19767 static void vl_api_ip_fib_details_t_handler_json
19768   (vl_api_ip_fib_details_t * mp)
19769 {
19770   vat_main_t *vam = &vat_main;
19771   int count = ntohl (mp->count);
19772   vat_json_node_t *node = NULL;
19773   struct in_addr ip4;
19774   struct in6_addr ip6;
19775   vl_api_fib_path_t *fp;
19776   int i;
19777
19778   if (VAT_JSON_ARRAY != vam->json_tree.type)
19779     {
19780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19781       vat_json_init_array (&vam->json_tree);
19782     }
19783   node = vat_json_array_add (&vam->json_tree);
19784
19785   vat_json_init_object (node);
19786   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19787   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19788   vat_json_object_add_ip4 (node, "prefix", ip4);
19789   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19790   vat_json_object_add_uint (node, "path_count", count);
19791   fp = mp->path;
19792   for (i = 0; i < count; i++)
19793     {
19794       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19795       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19796       vat_json_object_add_uint (node, "is_local", fp->is_local);
19797       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19798       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19799       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19800       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19801       if (fp->afi == IP46_TYPE_IP4)
19802         {
19803           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19804           vat_json_object_add_ip4 (node, "next_hop", ip4);
19805         }
19806       else if (fp->afi == IP46_TYPE_IP6)
19807         {
19808           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19809           vat_json_object_add_ip6 (node, "next_hop", ip6);
19810         }
19811     }
19812 }
19813
19814 static int
19815 api_ip_fib_dump (vat_main_t * vam)
19816 {
19817   vl_api_ip_fib_dump_t *mp;
19818   vl_api_control_ping_t *mp_ping;
19819   int ret;
19820
19821   M (IP_FIB_DUMP, mp);
19822   S (mp);
19823
19824   /* Use a control ping for synchronization */
19825   MPING (CONTROL_PING, mp_ping);
19826   S (mp_ping);
19827
19828   W (ret);
19829   return ret;
19830 }
19831
19832 static int
19833 api_ip_mfib_dump (vat_main_t * vam)
19834 {
19835   vl_api_ip_mfib_dump_t *mp;
19836   vl_api_control_ping_t *mp_ping;
19837   int ret;
19838
19839   M (IP_MFIB_DUMP, mp);
19840   S (mp);
19841
19842   /* Use a control ping for synchronization */
19843   MPING (CONTROL_PING, mp_ping);
19844   S (mp_ping);
19845
19846   W (ret);
19847   return ret;
19848 }
19849
19850 static void vl_api_ip_neighbor_details_t_handler
19851   (vl_api_ip_neighbor_details_t * mp)
19852 {
19853   vat_main_t *vam = &vat_main;
19854
19855   print (vam->ofp, "%c %U %U",
19856          (mp->is_static) ? 'S' : 'D',
19857          format_ethernet_address, &mp->mac_address,
19858          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19859          &mp->ip_address);
19860 }
19861
19862 static void vl_api_ip_neighbor_details_t_handler_json
19863   (vl_api_ip_neighbor_details_t * mp)
19864 {
19865
19866   vat_main_t *vam = &vat_main;
19867   vat_json_node_t *node;
19868   struct in_addr ip4;
19869   struct in6_addr ip6;
19870
19871   if (VAT_JSON_ARRAY != vam->json_tree.type)
19872     {
19873       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19874       vat_json_init_array (&vam->json_tree);
19875     }
19876   node = vat_json_array_add (&vam->json_tree);
19877
19878   vat_json_init_object (node);
19879   vat_json_object_add_string_copy (node, "flag",
19880                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19881                                    "dynamic");
19882
19883   vat_json_object_add_string_copy (node, "link_layer",
19884                                    format (0, "%U", format_ethernet_address,
19885                                            &mp->mac_address));
19886
19887   if (mp->is_ipv6)
19888     {
19889       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19890       vat_json_object_add_ip6 (node, "ip_address", ip6);
19891     }
19892   else
19893     {
19894       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19895       vat_json_object_add_ip4 (node, "ip_address", ip4);
19896     }
19897 }
19898
19899 static int
19900 api_ip_neighbor_dump (vat_main_t * vam)
19901 {
19902   unformat_input_t *i = vam->input;
19903   vl_api_ip_neighbor_dump_t *mp;
19904   vl_api_control_ping_t *mp_ping;
19905   u8 is_ipv6 = 0;
19906   u32 sw_if_index = ~0;
19907   int ret;
19908
19909   /* Parse args required to build the message */
19910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19911     {
19912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19913         ;
19914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19915         ;
19916       else if (unformat (i, "ip6"))
19917         is_ipv6 = 1;
19918       else
19919         break;
19920     }
19921
19922   if (sw_if_index == ~0)
19923     {
19924       errmsg ("missing interface name or sw_if_index");
19925       return -99;
19926     }
19927
19928   M (IP_NEIGHBOR_DUMP, mp);
19929   mp->is_ipv6 = (u8) is_ipv6;
19930   mp->sw_if_index = ntohl (sw_if_index);
19931   S (mp);
19932
19933   /* Use a control ping for synchronization */
19934   MPING (CONTROL_PING, mp_ping);
19935   S (mp_ping);
19936
19937   W (ret);
19938   return ret;
19939 }
19940
19941 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19942 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19943
19944 static void
19945 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19946 {
19947   vat_main_t *vam = &vat_main;
19948   int count = ntohl (mp->count);
19949   vl_api_fib_path_t *fp;
19950   int i;
19951
19952   print (vam->ofp,
19953          "table-id %d, prefix %U/%d",
19954          ntohl (mp->table_id), format_ip6_address, mp->address,
19955          mp->address_length);
19956   fp = mp->path;
19957   for (i = 0; i < count; i++)
19958     {
19959       if (fp->afi == IP46_TYPE_IP6)
19960         print (vam->ofp,
19961                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19962                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19963                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19964                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19965                format_ip6_address, fp->next_hop);
19966       else if (fp->afi == IP46_TYPE_IP4)
19967         print (vam->ofp,
19968                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19969                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19970                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19971                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19972                format_ip4_address, fp->next_hop);
19973       fp++;
19974     }
19975 }
19976
19977 static void vl_api_ip6_fib_details_t_handler_json
19978   (vl_api_ip6_fib_details_t * mp)
19979 {
19980   vat_main_t *vam = &vat_main;
19981   int count = ntohl (mp->count);
19982   vat_json_node_t *node = NULL;
19983   struct in_addr ip4;
19984   struct in6_addr ip6;
19985   vl_api_fib_path_t *fp;
19986   int i;
19987
19988   if (VAT_JSON_ARRAY != vam->json_tree.type)
19989     {
19990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19991       vat_json_init_array (&vam->json_tree);
19992     }
19993   node = vat_json_array_add (&vam->json_tree);
19994
19995   vat_json_init_object (node);
19996   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19997   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19998   vat_json_object_add_ip6 (node, "prefix", ip6);
19999   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20000   vat_json_object_add_uint (node, "path_count", count);
20001   fp = mp->path;
20002   for (i = 0; i < count; i++)
20003     {
20004       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20005       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20006       vat_json_object_add_uint (node, "is_local", fp->is_local);
20007       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20008       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20009       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20010       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20011       if (fp->afi == IP46_TYPE_IP4)
20012         {
20013           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20014           vat_json_object_add_ip4 (node, "next_hop", ip4);
20015         }
20016       else if (fp->afi == IP46_TYPE_IP6)
20017         {
20018           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20019           vat_json_object_add_ip6 (node, "next_hop", ip6);
20020         }
20021     }
20022 }
20023
20024 static int
20025 api_ip6_fib_dump (vat_main_t * vam)
20026 {
20027   vl_api_ip6_fib_dump_t *mp;
20028   vl_api_control_ping_t *mp_ping;
20029   int ret;
20030
20031   M (IP6_FIB_DUMP, mp);
20032   S (mp);
20033
20034   /* Use a control ping for synchronization */
20035   MPING (CONTROL_PING, mp_ping);
20036   S (mp_ping);
20037
20038   W (ret);
20039   return ret;
20040 }
20041
20042 static int
20043 api_ip6_mfib_dump (vat_main_t * vam)
20044 {
20045   vl_api_ip6_mfib_dump_t *mp;
20046   vl_api_control_ping_t *mp_ping;
20047   int ret;
20048
20049   M (IP6_MFIB_DUMP, mp);
20050   S (mp);
20051
20052   /* Use a control ping for synchronization */
20053   MPING (CONTROL_PING, mp_ping);
20054   S (mp_ping);
20055
20056   W (ret);
20057   return ret;
20058 }
20059
20060 int
20061 api_classify_table_ids (vat_main_t * vam)
20062 {
20063   vl_api_classify_table_ids_t *mp;
20064   int ret;
20065
20066   /* Construct the API message */
20067   M (CLASSIFY_TABLE_IDS, mp);
20068   mp->context = 0;
20069
20070   S (mp);
20071   W (ret);
20072   return ret;
20073 }
20074
20075 int
20076 api_classify_table_by_interface (vat_main_t * vam)
20077 {
20078   unformat_input_t *input = vam->input;
20079   vl_api_classify_table_by_interface_t *mp;
20080
20081   u32 sw_if_index = ~0;
20082   int ret;
20083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20086         ;
20087       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20088         ;
20089       else
20090         break;
20091     }
20092   if (sw_if_index == ~0)
20093     {
20094       errmsg ("missing interface name or sw_if_index");
20095       return -99;
20096     }
20097
20098   /* Construct the API message */
20099   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20100   mp->context = 0;
20101   mp->sw_if_index = ntohl (sw_if_index);
20102
20103   S (mp);
20104   W (ret);
20105   return ret;
20106 }
20107
20108 int
20109 api_classify_table_info (vat_main_t * vam)
20110 {
20111   unformat_input_t *input = vam->input;
20112   vl_api_classify_table_info_t *mp;
20113
20114   u32 table_id = ~0;
20115   int ret;
20116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20117     {
20118       if (unformat (input, "table_id %d", &table_id))
20119         ;
20120       else
20121         break;
20122     }
20123   if (table_id == ~0)
20124     {
20125       errmsg ("missing table id");
20126       return -99;
20127     }
20128
20129   /* Construct the API message */
20130   M (CLASSIFY_TABLE_INFO, mp);
20131   mp->context = 0;
20132   mp->table_id = ntohl (table_id);
20133
20134   S (mp);
20135   W (ret);
20136   return ret;
20137 }
20138
20139 int
20140 api_classify_session_dump (vat_main_t * vam)
20141 {
20142   unformat_input_t *input = vam->input;
20143   vl_api_classify_session_dump_t *mp;
20144   vl_api_control_ping_t *mp_ping;
20145
20146   u32 table_id = ~0;
20147   int ret;
20148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20149     {
20150       if (unformat (input, "table_id %d", &table_id))
20151         ;
20152       else
20153         break;
20154     }
20155   if (table_id == ~0)
20156     {
20157       errmsg ("missing table id");
20158       return -99;
20159     }
20160
20161   /* Construct the API message */
20162   M (CLASSIFY_SESSION_DUMP, mp);
20163   mp->context = 0;
20164   mp->table_id = ntohl (table_id);
20165   S (mp);
20166
20167   /* Use a control ping for synchronization */
20168   MPING (CONTROL_PING, mp_ping);
20169   S (mp_ping);
20170
20171   W (ret);
20172   return ret;
20173 }
20174
20175 static void
20176 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20177 {
20178   vat_main_t *vam = &vat_main;
20179
20180   print (vam->ofp, "collector_address %U, collector_port %d, "
20181          "src_address %U, vrf_id %d, path_mtu %u, "
20182          "template_interval %u, udp_checksum %d",
20183          format_ip4_address, mp->collector_address,
20184          ntohs (mp->collector_port),
20185          format_ip4_address, mp->src_address,
20186          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20187          ntohl (mp->template_interval), mp->udp_checksum);
20188
20189   vam->retval = 0;
20190   vam->result_ready = 1;
20191 }
20192
20193 static void
20194   vl_api_ipfix_exporter_details_t_handler_json
20195   (vl_api_ipfix_exporter_details_t * mp)
20196 {
20197   vat_main_t *vam = &vat_main;
20198   vat_json_node_t node;
20199   struct in_addr collector_address;
20200   struct in_addr src_address;
20201
20202   vat_json_init_object (&node);
20203   clib_memcpy (&collector_address, &mp->collector_address,
20204                sizeof (collector_address));
20205   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20206   vat_json_object_add_uint (&node, "collector_port",
20207                             ntohs (mp->collector_port));
20208   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20209   vat_json_object_add_ip4 (&node, "src_address", src_address);
20210   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20211   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20212   vat_json_object_add_uint (&node, "template_interval",
20213                             ntohl (mp->template_interval));
20214   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20215
20216   vat_json_print (vam->ofp, &node);
20217   vat_json_free (&node);
20218   vam->retval = 0;
20219   vam->result_ready = 1;
20220 }
20221
20222 int
20223 api_ipfix_exporter_dump (vat_main_t * vam)
20224 {
20225   vl_api_ipfix_exporter_dump_t *mp;
20226   int ret;
20227
20228   /* Construct the API message */
20229   M (IPFIX_EXPORTER_DUMP, mp);
20230   mp->context = 0;
20231
20232   S (mp);
20233   W (ret);
20234   return ret;
20235 }
20236
20237 static int
20238 api_ipfix_classify_stream_dump (vat_main_t * vam)
20239 {
20240   vl_api_ipfix_classify_stream_dump_t *mp;
20241   int ret;
20242
20243   /* Construct the API message */
20244   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20245   mp->context = 0;
20246
20247   S (mp);
20248   W (ret);
20249   return ret;
20250   /* NOTREACHED */
20251   return 0;
20252 }
20253
20254 static void
20255   vl_api_ipfix_classify_stream_details_t_handler
20256   (vl_api_ipfix_classify_stream_details_t * mp)
20257 {
20258   vat_main_t *vam = &vat_main;
20259   print (vam->ofp, "domain_id %d, src_port %d",
20260          ntohl (mp->domain_id), ntohs (mp->src_port));
20261   vam->retval = 0;
20262   vam->result_ready = 1;
20263 }
20264
20265 static void
20266   vl_api_ipfix_classify_stream_details_t_handler_json
20267   (vl_api_ipfix_classify_stream_details_t * mp)
20268 {
20269   vat_main_t *vam = &vat_main;
20270   vat_json_node_t node;
20271
20272   vat_json_init_object (&node);
20273   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20274   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20275
20276   vat_json_print (vam->ofp, &node);
20277   vat_json_free (&node);
20278   vam->retval = 0;
20279   vam->result_ready = 1;
20280 }
20281
20282 static int
20283 api_ipfix_classify_table_dump (vat_main_t * vam)
20284 {
20285   vl_api_ipfix_classify_table_dump_t *mp;
20286   vl_api_control_ping_t *mp_ping;
20287   int ret;
20288
20289   if (!vam->json_output)
20290     {
20291       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20292              "transport_protocol");
20293     }
20294
20295   /* Construct the API message */
20296   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20297
20298   /* send it... */
20299   S (mp);
20300
20301   /* Use a control ping for synchronization */
20302   MPING (CONTROL_PING, mp_ping);
20303   S (mp_ping);
20304
20305   W (ret);
20306   return ret;
20307 }
20308
20309 static void
20310   vl_api_ipfix_classify_table_details_t_handler
20311   (vl_api_ipfix_classify_table_details_t * mp)
20312 {
20313   vat_main_t *vam = &vat_main;
20314   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20315          mp->transport_protocol);
20316 }
20317
20318 static void
20319   vl_api_ipfix_classify_table_details_t_handler_json
20320   (vl_api_ipfix_classify_table_details_t * mp)
20321 {
20322   vat_json_node_t *node = NULL;
20323   vat_main_t *vam = &vat_main;
20324
20325   if (VAT_JSON_ARRAY != vam->json_tree.type)
20326     {
20327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20328       vat_json_init_array (&vam->json_tree);
20329     }
20330
20331   node = vat_json_array_add (&vam->json_tree);
20332   vat_json_init_object (node);
20333
20334   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20335   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20336   vat_json_object_add_uint (node, "transport_protocol",
20337                             mp->transport_protocol);
20338 }
20339
20340 static int
20341 api_sw_interface_span_enable_disable (vat_main_t * vam)
20342 {
20343   unformat_input_t *i = vam->input;
20344   vl_api_sw_interface_span_enable_disable_t *mp;
20345   u32 src_sw_if_index = ~0;
20346   u32 dst_sw_if_index = ~0;
20347   u8 state = 3;
20348   int ret;
20349   u8 is_l2 = 0;
20350
20351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20352     {
20353       if (unformat
20354           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20355         ;
20356       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20357         ;
20358       else
20359         if (unformat
20360             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20361         ;
20362       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20363         ;
20364       else if (unformat (i, "disable"))
20365         state = 0;
20366       else if (unformat (i, "rx"))
20367         state = 1;
20368       else if (unformat (i, "tx"))
20369         state = 2;
20370       else if (unformat (i, "both"))
20371         state = 3;
20372       else if (unformat (i, "l2"))
20373         is_l2 = 1;
20374       else
20375         break;
20376     }
20377
20378   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20379
20380   mp->sw_if_index_from = htonl (src_sw_if_index);
20381   mp->sw_if_index_to = htonl (dst_sw_if_index);
20382   mp->state = state;
20383   mp->is_l2 = is_l2;
20384
20385   S (mp);
20386   W (ret);
20387   return ret;
20388 }
20389
20390 static void
20391 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20392                                             * mp)
20393 {
20394   vat_main_t *vam = &vat_main;
20395   u8 *sw_if_from_name = 0;
20396   u8 *sw_if_to_name = 0;
20397   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20398   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20399   char *states[] = { "none", "rx", "tx", "both" };
20400   hash_pair_t *p;
20401
20402   /* *INDENT-OFF* */
20403   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20404   ({
20405     if ((u32) p->value[0] == sw_if_index_from)
20406       {
20407         sw_if_from_name = (u8 *)(p->key);
20408         if (sw_if_to_name)
20409           break;
20410       }
20411     if ((u32) p->value[0] == sw_if_index_to)
20412       {
20413         sw_if_to_name = (u8 *)(p->key);
20414         if (sw_if_from_name)
20415           break;
20416       }
20417   }));
20418   /* *INDENT-ON* */
20419   print (vam->ofp, "%20s => %20s (%s)",
20420          sw_if_from_name, sw_if_to_name, states[mp->state]);
20421 }
20422
20423 static void
20424   vl_api_sw_interface_span_details_t_handler_json
20425   (vl_api_sw_interface_span_details_t * mp)
20426 {
20427   vat_main_t *vam = &vat_main;
20428   vat_json_node_t *node = NULL;
20429   u8 *sw_if_from_name = 0;
20430   u8 *sw_if_to_name = 0;
20431   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20432   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20433   hash_pair_t *p;
20434
20435   /* *INDENT-OFF* */
20436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20437   ({
20438     if ((u32) p->value[0] == sw_if_index_from)
20439       {
20440         sw_if_from_name = (u8 *)(p->key);
20441         if (sw_if_to_name)
20442           break;
20443       }
20444     if ((u32) p->value[0] == sw_if_index_to)
20445       {
20446         sw_if_to_name = (u8 *)(p->key);
20447         if (sw_if_from_name)
20448           break;
20449       }
20450   }));
20451   /* *INDENT-ON* */
20452
20453   if (VAT_JSON_ARRAY != vam->json_tree.type)
20454     {
20455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20456       vat_json_init_array (&vam->json_tree);
20457     }
20458   node = vat_json_array_add (&vam->json_tree);
20459
20460   vat_json_init_object (node);
20461   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20462   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20463   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20464   if (0 != sw_if_to_name)
20465     {
20466       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20467     }
20468   vat_json_object_add_uint (node, "state", mp->state);
20469 }
20470
20471 static int
20472 api_sw_interface_span_dump (vat_main_t * vam)
20473 {
20474   unformat_input_t *input = vam->input;
20475   vl_api_sw_interface_span_dump_t *mp;
20476   vl_api_control_ping_t *mp_ping;
20477   u8 is_l2 = 0;
20478   int ret;
20479
20480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20481     {
20482       if (unformat (input, "l2"))
20483         is_l2 = 1;
20484       else
20485         break;
20486     }
20487
20488   M (SW_INTERFACE_SPAN_DUMP, mp);
20489   mp->is_l2 = is_l2;
20490   S (mp);
20491
20492   /* Use a control ping for synchronization */
20493   MPING (CONTROL_PING, mp_ping);
20494   S (mp_ping);
20495
20496   W (ret);
20497   return ret;
20498 }
20499
20500 int
20501 api_pg_create_interface (vat_main_t * vam)
20502 {
20503   unformat_input_t *input = vam->input;
20504   vl_api_pg_create_interface_t *mp;
20505
20506   u32 if_id = ~0;
20507   int ret;
20508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20509     {
20510       if (unformat (input, "if_id %d", &if_id))
20511         ;
20512       else
20513         break;
20514     }
20515   if (if_id == ~0)
20516     {
20517       errmsg ("missing pg interface index");
20518       return -99;
20519     }
20520
20521   /* Construct the API message */
20522   M (PG_CREATE_INTERFACE, mp);
20523   mp->context = 0;
20524   mp->interface_id = ntohl (if_id);
20525
20526   S (mp);
20527   W (ret);
20528   return ret;
20529 }
20530
20531 int
20532 api_pg_capture (vat_main_t * vam)
20533 {
20534   unformat_input_t *input = vam->input;
20535   vl_api_pg_capture_t *mp;
20536
20537   u32 if_id = ~0;
20538   u8 enable = 1;
20539   u32 count = 1;
20540   u8 pcap_file_set = 0;
20541   u8 *pcap_file = 0;
20542   int ret;
20543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (input, "if_id %d", &if_id))
20546         ;
20547       else if (unformat (input, "pcap %s", &pcap_file))
20548         pcap_file_set = 1;
20549       else if (unformat (input, "count %d", &count))
20550         ;
20551       else if (unformat (input, "disable"))
20552         enable = 0;
20553       else
20554         break;
20555     }
20556   if (if_id == ~0)
20557     {
20558       errmsg ("missing pg interface index");
20559       return -99;
20560     }
20561   if (pcap_file_set > 0)
20562     {
20563       if (vec_len (pcap_file) > 255)
20564         {
20565           errmsg ("pcap file name is too long");
20566           return -99;
20567         }
20568     }
20569
20570   u32 name_len = vec_len (pcap_file);
20571   /* Construct the API message */
20572   M (PG_CAPTURE, mp);
20573   mp->context = 0;
20574   mp->interface_id = ntohl (if_id);
20575   mp->is_enabled = enable;
20576   mp->count = ntohl (count);
20577   mp->pcap_name_length = ntohl (name_len);
20578   if (pcap_file_set != 0)
20579     {
20580       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20581     }
20582   vec_free (pcap_file);
20583
20584   S (mp);
20585   W (ret);
20586   return ret;
20587 }
20588
20589 int
20590 api_pg_enable_disable (vat_main_t * vam)
20591 {
20592   unformat_input_t *input = vam->input;
20593   vl_api_pg_enable_disable_t *mp;
20594
20595   u8 enable = 1;
20596   u8 stream_name_set = 0;
20597   u8 *stream_name = 0;
20598   int ret;
20599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20600     {
20601       if (unformat (input, "stream %s", &stream_name))
20602         stream_name_set = 1;
20603       else if (unformat (input, "disable"))
20604         enable = 0;
20605       else
20606         break;
20607     }
20608
20609   if (stream_name_set > 0)
20610     {
20611       if (vec_len (stream_name) > 255)
20612         {
20613           errmsg ("stream name too long");
20614           return -99;
20615         }
20616     }
20617
20618   u32 name_len = vec_len (stream_name);
20619   /* Construct the API message */
20620   M (PG_ENABLE_DISABLE, mp);
20621   mp->context = 0;
20622   mp->is_enabled = enable;
20623   if (stream_name_set != 0)
20624     {
20625       mp->stream_name_length = ntohl (name_len);
20626       clib_memcpy (mp->stream_name, stream_name, name_len);
20627     }
20628   vec_free (stream_name);
20629
20630   S (mp);
20631   W (ret);
20632   return ret;
20633 }
20634
20635 int
20636 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20637 {
20638   unformat_input_t *input = vam->input;
20639   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20640
20641   u16 *low_ports = 0;
20642   u16 *high_ports = 0;
20643   u16 this_low;
20644   u16 this_hi;
20645   ip4_address_t ip4_addr;
20646   ip6_address_t ip6_addr;
20647   u32 length;
20648   u32 tmp, tmp2;
20649   u8 prefix_set = 0;
20650   u32 vrf_id = ~0;
20651   u8 is_add = 1;
20652   u8 is_ipv6 = 0;
20653   int ret;
20654
20655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20656     {
20657       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20658         {
20659           prefix_set = 1;
20660         }
20661       else
20662         if (unformat
20663             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20664         {
20665           prefix_set = 1;
20666           is_ipv6 = 1;
20667         }
20668       else if (unformat (input, "vrf %d", &vrf_id))
20669         ;
20670       else if (unformat (input, "del"))
20671         is_add = 0;
20672       else if (unformat (input, "port %d", &tmp))
20673         {
20674           if (tmp == 0 || tmp > 65535)
20675             {
20676               errmsg ("port %d out of range", tmp);
20677               return -99;
20678             }
20679           this_low = tmp;
20680           this_hi = this_low + 1;
20681           vec_add1 (low_ports, this_low);
20682           vec_add1 (high_ports, this_hi);
20683         }
20684       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20685         {
20686           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20687             {
20688               errmsg ("incorrect range parameters");
20689               return -99;
20690             }
20691           this_low = tmp;
20692           /* Note: in debug CLI +1 is added to high before
20693              passing to real fn that does "the work"
20694              (ip_source_and_port_range_check_add_del).
20695              This fn is a wrapper around the binary API fn a
20696              control plane will call, which expects this increment
20697              to have occurred. Hence letting the binary API control
20698              plane fn do the increment for consistency between VAT
20699              and other control planes.
20700            */
20701           this_hi = tmp2;
20702           vec_add1 (low_ports, this_low);
20703           vec_add1 (high_ports, this_hi);
20704         }
20705       else
20706         break;
20707     }
20708
20709   if (prefix_set == 0)
20710     {
20711       errmsg ("<address>/<mask> not specified");
20712       return -99;
20713     }
20714
20715   if (vrf_id == ~0)
20716     {
20717       errmsg ("VRF ID required, not specified");
20718       return -99;
20719     }
20720
20721   if (vrf_id == 0)
20722     {
20723       errmsg
20724         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20725       return -99;
20726     }
20727
20728   if (vec_len (low_ports) == 0)
20729     {
20730       errmsg ("At least one port or port range required");
20731       return -99;
20732     }
20733
20734   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20735
20736   mp->is_add = is_add;
20737
20738   if (is_ipv6)
20739     {
20740       mp->is_ipv6 = 1;
20741       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20742     }
20743   else
20744     {
20745       mp->is_ipv6 = 0;
20746       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20747     }
20748
20749   mp->mask_length = length;
20750   mp->number_of_ranges = vec_len (low_ports);
20751
20752   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20753   vec_free (low_ports);
20754
20755   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20756   vec_free (high_ports);
20757
20758   mp->vrf_id = ntohl (vrf_id);
20759
20760   S (mp);
20761   W (ret);
20762   return ret;
20763 }
20764
20765 int
20766 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20767 {
20768   unformat_input_t *input = vam->input;
20769   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20770   u32 sw_if_index = ~0;
20771   int vrf_set = 0;
20772   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20773   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20774   u8 is_add = 1;
20775   int ret;
20776
20777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20778     {
20779       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20780         ;
20781       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20782         ;
20783       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20784         vrf_set = 1;
20785       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20786         vrf_set = 1;
20787       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20788         vrf_set = 1;
20789       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20790         vrf_set = 1;
20791       else if (unformat (input, "del"))
20792         is_add = 0;
20793       else
20794         break;
20795     }
20796
20797   if (sw_if_index == ~0)
20798     {
20799       errmsg ("Interface required but not specified");
20800       return -99;
20801     }
20802
20803   if (vrf_set == 0)
20804     {
20805       errmsg ("VRF ID required but not specified");
20806       return -99;
20807     }
20808
20809   if (tcp_out_vrf_id == 0
20810       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20811     {
20812       errmsg
20813         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20814       return -99;
20815     }
20816
20817   /* Construct the API message */
20818   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20819
20820   mp->sw_if_index = ntohl (sw_if_index);
20821   mp->is_add = is_add;
20822   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20823   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20824   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20825   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20826
20827   /* send it... */
20828   S (mp);
20829
20830   /* Wait for a reply... */
20831   W (ret);
20832   return ret;
20833 }
20834
20835 static int
20836 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20837 {
20838   unformat_input_t *i = vam->input;
20839   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20840   u32 local_sa_id = 0;
20841   u32 remote_sa_id = 0;
20842   ip4_address_t src_address;
20843   ip4_address_t dst_address;
20844   u8 is_add = 1;
20845   int ret;
20846
20847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20848     {
20849       if (unformat (i, "local_sa %d", &local_sa_id))
20850         ;
20851       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20852         ;
20853       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20854         ;
20855       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20856         ;
20857       else if (unformat (i, "del"))
20858         is_add = 0;
20859       else
20860         {
20861           clib_warning ("parse error '%U'", format_unformat_error, i);
20862           return -99;
20863         }
20864     }
20865
20866   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20867
20868   mp->local_sa_id = ntohl (local_sa_id);
20869   mp->remote_sa_id = ntohl (remote_sa_id);
20870   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20871   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20872   mp->is_add = is_add;
20873
20874   S (mp);
20875   W (ret);
20876   return ret;
20877 }
20878
20879 static int
20880 api_punt (vat_main_t * vam)
20881 {
20882   unformat_input_t *i = vam->input;
20883   vl_api_punt_t *mp;
20884   u32 ipv = ~0;
20885   u32 protocol = ~0;
20886   u32 port = ~0;
20887   int is_add = 1;
20888   int ret;
20889
20890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20891     {
20892       if (unformat (i, "ip %d", &ipv))
20893         ;
20894       else if (unformat (i, "protocol %d", &protocol))
20895         ;
20896       else if (unformat (i, "port %d", &port))
20897         ;
20898       else if (unformat (i, "del"))
20899         is_add = 0;
20900       else
20901         {
20902           clib_warning ("parse error '%U'", format_unformat_error, i);
20903           return -99;
20904         }
20905     }
20906
20907   M (PUNT, mp);
20908
20909   mp->is_add = (u8) is_add;
20910   mp->ipv = (u8) ipv;
20911   mp->l4_protocol = (u8) protocol;
20912   mp->l4_port = htons ((u16) port);
20913
20914   S (mp);
20915   W (ret);
20916   return ret;
20917 }
20918
20919 static void vl_api_ipsec_gre_tunnel_details_t_handler
20920   (vl_api_ipsec_gre_tunnel_details_t * mp)
20921 {
20922   vat_main_t *vam = &vat_main;
20923
20924   print (vam->ofp, "%11d%15U%15U%14d%14d",
20925          ntohl (mp->sw_if_index),
20926          format_ip4_address, &mp->src_address,
20927          format_ip4_address, &mp->dst_address,
20928          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20929 }
20930
20931 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20932   (vl_api_ipsec_gre_tunnel_details_t * mp)
20933 {
20934   vat_main_t *vam = &vat_main;
20935   vat_json_node_t *node = NULL;
20936   struct in_addr ip4;
20937
20938   if (VAT_JSON_ARRAY != vam->json_tree.type)
20939     {
20940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20941       vat_json_init_array (&vam->json_tree);
20942     }
20943   node = vat_json_array_add (&vam->json_tree);
20944
20945   vat_json_init_object (node);
20946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20947   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20948   vat_json_object_add_ip4 (node, "src_address", ip4);
20949   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20950   vat_json_object_add_ip4 (node, "dst_address", ip4);
20951   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20952   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20953 }
20954
20955 static int
20956 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20957 {
20958   unformat_input_t *i = vam->input;
20959   vl_api_ipsec_gre_tunnel_dump_t *mp;
20960   vl_api_control_ping_t *mp_ping;
20961   u32 sw_if_index;
20962   u8 sw_if_index_set = 0;
20963   int ret;
20964
20965   /* Parse args required to build the message */
20966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20967     {
20968       if (unformat (i, "sw_if_index %d", &sw_if_index))
20969         sw_if_index_set = 1;
20970       else
20971         break;
20972     }
20973
20974   if (sw_if_index_set == 0)
20975     {
20976       sw_if_index = ~0;
20977     }
20978
20979   if (!vam->json_output)
20980     {
20981       print (vam->ofp, "%11s%15s%15s%14s%14s",
20982              "sw_if_index", "src_address", "dst_address",
20983              "local_sa_id", "remote_sa_id");
20984     }
20985
20986   /* Get list of gre-tunnel interfaces */
20987   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20988
20989   mp->sw_if_index = htonl (sw_if_index);
20990
20991   S (mp);
20992
20993   /* Use a control ping for synchronization */
20994   MPING (CONTROL_PING, mp_ping);
20995   S (mp_ping);
20996
20997   W (ret);
20998   return ret;
20999 }
21000
21001 static int
21002 api_delete_subif (vat_main_t * vam)
21003 {
21004   unformat_input_t *i = vam->input;
21005   vl_api_delete_subif_t *mp;
21006   u32 sw_if_index = ~0;
21007   int ret;
21008
21009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21010     {
21011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21012         ;
21013       if (unformat (i, "sw_if_index %d", &sw_if_index))
21014         ;
21015       else
21016         break;
21017     }
21018
21019   if (sw_if_index == ~0)
21020     {
21021       errmsg ("missing sw_if_index");
21022       return -99;
21023     }
21024
21025   /* Construct the API message */
21026   M (DELETE_SUBIF, mp);
21027   mp->sw_if_index = ntohl (sw_if_index);
21028
21029   S (mp);
21030   W (ret);
21031   return ret;
21032 }
21033
21034 #define foreach_pbb_vtr_op      \
21035 _("disable",  L2_VTR_DISABLED)  \
21036 _("pop",  L2_VTR_POP_2)         \
21037 _("push",  L2_VTR_PUSH_2)
21038
21039 static int
21040 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21041 {
21042   unformat_input_t *i = vam->input;
21043   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21044   u32 sw_if_index = ~0, vtr_op = ~0;
21045   u16 outer_tag = ~0;
21046   u8 dmac[6], smac[6];
21047   u8 dmac_set = 0, smac_set = 0;
21048   u16 vlanid = 0;
21049   u32 sid = ~0;
21050   u32 tmp;
21051   int ret;
21052
21053   /* Shut up coverity */
21054   memset (dmac, 0, sizeof (dmac));
21055   memset (smac, 0, sizeof (smac));
21056
21057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21058     {
21059       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21060         ;
21061       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21062         ;
21063       else if (unformat (i, "vtr_op %d", &vtr_op))
21064         ;
21065 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21066       foreach_pbb_vtr_op
21067 #undef _
21068         else if (unformat (i, "translate_pbb_stag"))
21069         {
21070           if (unformat (i, "%d", &tmp))
21071             {
21072               vtr_op = L2_VTR_TRANSLATE_2_1;
21073               outer_tag = tmp;
21074             }
21075           else
21076             {
21077               errmsg
21078                 ("translate_pbb_stag operation requires outer tag definition");
21079               return -99;
21080             }
21081         }
21082       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21083         dmac_set++;
21084       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21085         smac_set++;
21086       else if (unformat (i, "sid %d", &sid))
21087         ;
21088       else if (unformat (i, "vlanid %d", &tmp))
21089         vlanid = tmp;
21090       else
21091         {
21092           clib_warning ("parse error '%U'", format_unformat_error, i);
21093           return -99;
21094         }
21095     }
21096
21097   if ((sw_if_index == ~0) || (vtr_op == ~0))
21098     {
21099       errmsg ("missing sw_if_index or vtr operation");
21100       return -99;
21101     }
21102   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21103       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21104     {
21105       errmsg
21106         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21107       return -99;
21108     }
21109
21110   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21111   mp->sw_if_index = ntohl (sw_if_index);
21112   mp->vtr_op = ntohl (vtr_op);
21113   mp->outer_tag = ntohs (outer_tag);
21114   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21115   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21116   mp->b_vlanid = ntohs (vlanid);
21117   mp->i_sid = ntohl (sid);
21118
21119   S (mp);
21120   W (ret);
21121   return ret;
21122 }
21123
21124 static int
21125 api_flow_classify_set_interface (vat_main_t * vam)
21126 {
21127   unformat_input_t *i = vam->input;
21128   vl_api_flow_classify_set_interface_t *mp;
21129   u32 sw_if_index;
21130   int sw_if_index_set;
21131   u32 ip4_table_index = ~0;
21132   u32 ip6_table_index = ~0;
21133   u8 is_add = 1;
21134   int ret;
21135
21136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21137     {
21138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21139         sw_if_index_set = 1;
21140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21141         sw_if_index_set = 1;
21142       else if (unformat (i, "del"))
21143         is_add = 0;
21144       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21145         ;
21146       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21147         ;
21148       else
21149         {
21150           clib_warning ("parse error '%U'", format_unformat_error, i);
21151           return -99;
21152         }
21153     }
21154
21155   if (sw_if_index_set == 0)
21156     {
21157       errmsg ("missing interface name or sw_if_index");
21158       return -99;
21159     }
21160
21161   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21162
21163   mp->sw_if_index = ntohl (sw_if_index);
21164   mp->ip4_table_index = ntohl (ip4_table_index);
21165   mp->ip6_table_index = ntohl (ip6_table_index);
21166   mp->is_add = is_add;
21167
21168   S (mp);
21169   W (ret);
21170   return ret;
21171 }
21172
21173 static int
21174 api_flow_classify_dump (vat_main_t * vam)
21175 {
21176   unformat_input_t *i = vam->input;
21177   vl_api_flow_classify_dump_t *mp;
21178   vl_api_control_ping_t *mp_ping;
21179   u8 type = FLOW_CLASSIFY_N_TABLES;
21180   int ret;
21181
21182   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21183     ;
21184   else
21185     {
21186       errmsg ("classify table type must be specified");
21187       return -99;
21188     }
21189
21190   if (!vam->json_output)
21191     {
21192       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21193     }
21194
21195   M (FLOW_CLASSIFY_DUMP, mp);
21196   mp->type = type;
21197   /* send it... */
21198   S (mp);
21199
21200   /* Use a control ping for synchronization */
21201   MPING (CONTROL_PING, mp_ping);
21202   S (mp_ping);
21203
21204   /* Wait for a reply... */
21205   W (ret);
21206   return ret;
21207 }
21208
21209 static int
21210 api_feature_enable_disable (vat_main_t * vam)
21211 {
21212   unformat_input_t *i = vam->input;
21213   vl_api_feature_enable_disable_t *mp;
21214   u8 *arc_name = 0;
21215   u8 *feature_name = 0;
21216   u32 sw_if_index = ~0;
21217   u8 enable = 1;
21218   int ret;
21219
21220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21221     {
21222       if (unformat (i, "arc_name %s", &arc_name))
21223         ;
21224       else if (unformat (i, "feature_name %s", &feature_name))
21225         ;
21226       else
21227         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21228         ;
21229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21230         ;
21231       else if (unformat (i, "disable"))
21232         enable = 0;
21233       else
21234         break;
21235     }
21236
21237   if (arc_name == 0)
21238     {
21239       errmsg ("missing arc name");
21240       return -99;
21241     }
21242   if (vec_len (arc_name) > 63)
21243     {
21244       errmsg ("arc name too long");
21245     }
21246
21247   if (feature_name == 0)
21248     {
21249       errmsg ("missing feature name");
21250       return -99;
21251     }
21252   if (vec_len (feature_name) > 63)
21253     {
21254       errmsg ("feature name too long");
21255     }
21256
21257   if (sw_if_index == ~0)
21258     {
21259       errmsg ("missing interface name or sw_if_index");
21260       return -99;
21261     }
21262
21263   /* Construct the API message */
21264   M (FEATURE_ENABLE_DISABLE, mp);
21265   mp->sw_if_index = ntohl (sw_if_index);
21266   mp->enable = enable;
21267   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21268   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21269   vec_free (arc_name);
21270   vec_free (feature_name);
21271
21272   S (mp);
21273   W (ret);
21274   return ret;
21275 }
21276
21277 static int
21278 api_sw_interface_tag_add_del (vat_main_t * vam)
21279 {
21280   unformat_input_t *i = vam->input;
21281   vl_api_sw_interface_tag_add_del_t *mp;
21282   u32 sw_if_index = ~0;
21283   u8 *tag = 0;
21284   u8 enable = 1;
21285   int ret;
21286
21287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21288     {
21289       if (unformat (i, "tag %s", &tag))
21290         ;
21291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21292         ;
21293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21294         ;
21295       else if (unformat (i, "del"))
21296         enable = 0;
21297       else
21298         break;
21299     }
21300
21301   if (sw_if_index == ~0)
21302     {
21303       errmsg ("missing interface name or sw_if_index");
21304       return -99;
21305     }
21306
21307   if (enable && (tag == 0))
21308     {
21309       errmsg ("no tag specified");
21310       return -99;
21311     }
21312
21313   /* Construct the API message */
21314   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21315   mp->sw_if_index = ntohl (sw_if_index);
21316   mp->is_add = enable;
21317   if (enable)
21318     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21319   vec_free (tag);
21320
21321   S (mp);
21322   W (ret);
21323   return ret;
21324 }
21325
21326 static void vl_api_l2_xconnect_details_t_handler
21327   (vl_api_l2_xconnect_details_t * mp)
21328 {
21329   vat_main_t *vam = &vat_main;
21330
21331   print (vam->ofp, "%15d%15d",
21332          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21333 }
21334
21335 static void vl_api_l2_xconnect_details_t_handler_json
21336   (vl_api_l2_xconnect_details_t * mp)
21337 {
21338   vat_main_t *vam = &vat_main;
21339   vat_json_node_t *node = NULL;
21340
21341   if (VAT_JSON_ARRAY != vam->json_tree.type)
21342     {
21343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21344       vat_json_init_array (&vam->json_tree);
21345     }
21346   node = vat_json_array_add (&vam->json_tree);
21347
21348   vat_json_init_object (node);
21349   vat_json_object_add_uint (node, "rx_sw_if_index",
21350                             ntohl (mp->rx_sw_if_index));
21351   vat_json_object_add_uint (node, "tx_sw_if_index",
21352                             ntohl (mp->tx_sw_if_index));
21353 }
21354
21355 static int
21356 api_l2_xconnect_dump (vat_main_t * vam)
21357 {
21358   vl_api_l2_xconnect_dump_t *mp;
21359   vl_api_control_ping_t *mp_ping;
21360   int ret;
21361
21362   if (!vam->json_output)
21363     {
21364       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21365     }
21366
21367   M (L2_XCONNECT_DUMP, mp);
21368
21369   S (mp);
21370
21371   /* Use a control ping for synchronization */
21372   MPING (CONTROL_PING, mp_ping);
21373   S (mp_ping);
21374
21375   W (ret);
21376   return ret;
21377 }
21378
21379 static int
21380 api_sw_interface_set_mtu (vat_main_t * vam)
21381 {
21382   unformat_input_t *i = vam->input;
21383   vl_api_sw_interface_set_mtu_t *mp;
21384   u32 sw_if_index = ~0;
21385   u32 mtu = 0;
21386   int ret;
21387
21388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21389     {
21390       if (unformat (i, "mtu %d", &mtu))
21391         ;
21392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21393         ;
21394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21395         ;
21396       else
21397         break;
21398     }
21399
21400   if (sw_if_index == ~0)
21401     {
21402       errmsg ("missing interface name or sw_if_index");
21403       return -99;
21404     }
21405
21406   if (mtu == 0)
21407     {
21408       errmsg ("no mtu specified");
21409       return -99;
21410     }
21411
21412   /* Construct the API message */
21413   M (SW_INTERFACE_SET_MTU, mp);
21414   mp->sw_if_index = ntohl (sw_if_index);
21415   mp->mtu = ntohs ((u16) mtu);
21416
21417   S (mp);
21418   W (ret);
21419   return ret;
21420 }
21421
21422 static int
21423 api_p2p_ethernet_add (vat_main_t * vam)
21424 {
21425   unformat_input_t *i = vam->input;
21426   vl_api_p2p_ethernet_add_t *mp;
21427   u32 parent_if_index = ~0;
21428   u32 sub_id = ~0;
21429   u8 remote_mac[6];
21430   u8 mac_set = 0;
21431   int ret;
21432
21433   memset (remote_mac, 0, sizeof (remote_mac));
21434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21435     {
21436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21437         ;
21438       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21439         ;
21440       else
21441         if (unformat
21442             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21443         mac_set++;
21444       else if (unformat (i, "sub_id %d", &sub_id))
21445         ;
21446       else
21447         {
21448           clib_warning ("parse error '%U'", format_unformat_error, i);
21449           return -99;
21450         }
21451     }
21452
21453   if (parent_if_index == ~0)
21454     {
21455       errmsg ("missing interface name or sw_if_index");
21456       return -99;
21457     }
21458   if (mac_set == 0)
21459     {
21460       errmsg ("missing remote mac address");
21461       return -99;
21462     }
21463   if (sub_id == ~0)
21464     {
21465       errmsg ("missing sub-interface id");
21466       return -99;
21467     }
21468
21469   M (P2P_ETHERNET_ADD, mp);
21470   mp->parent_if_index = ntohl (parent_if_index);
21471   mp->subif_id = ntohl (sub_id);
21472   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21473
21474   S (mp);
21475   W (ret);
21476   return ret;
21477 }
21478
21479 static int
21480 api_p2p_ethernet_del (vat_main_t * vam)
21481 {
21482   unformat_input_t *i = vam->input;
21483   vl_api_p2p_ethernet_del_t *mp;
21484   u32 parent_if_index = ~0;
21485   u8 remote_mac[6];
21486   u8 mac_set = 0;
21487   int ret;
21488
21489   memset (remote_mac, 0, sizeof (remote_mac));
21490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21491     {
21492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21493         ;
21494       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21495         ;
21496       else
21497         if (unformat
21498             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21499         mac_set++;
21500       else
21501         {
21502           clib_warning ("parse error '%U'", format_unformat_error, i);
21503           return -99;
21504         }
21505     }
21506
21507   if (parent_if_index == ~0)
21508     {
21509       errmsg ("missing interface name or sw_if_index");
21510       return -99;
21511     }
21512   if (mac_set == 0)
21513     {
21514       errmsg ("missing remote mac address");
21515       return -99;
21516     }
21517
21518   M (P2P_ETHERNET_DEL, mp);
21519   mp->parent_if_index = ntohl (parent_if_index);
21520   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21521
21522   S (mp);
21523   W (ret);
21524   return ret;
21525 }
21526
21527 static int
21528 api_lldp_config (vat_main_t * vam)
21529 {
21530   unformat_input_t *i = vam->input;
21531   vl_api_lldp_config_t *mp;
21532   int tx_hold = 0;
21533   int tx_interval = 0;
21534   u8 *sys_name = NULL;
21535   int ret;
21536
21537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21538     {
21539       if (unformat (i, "system-name %s", &sys_name))
21540         ;
21541       else if (unformat (i, "tx-hold %d", &tx_hold))
21542         ;
21543       else if (unformat (i, "tx-interval %d", &tx_interval))
21544         ;
21545       else
21546         {
21547           clib_warning ("parse error '%U'", format_unformat_error, i);
21548           return -99;
21549         }
21550     }
21551
21552   vec_add1 (sys_name, 0);
21553
21554   M (LLDP_CONFIG, mp);
21555   mp->tx_hold = htonl (tx_hold);
21556   mp->tx_interval = htonl (tx_interval);
21557   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21558   vec_free (sys_name);
21559
21560   S (mp);
21561   W (ret);
21562   return ret;
21563 }
21564
21565 static int
21566 api_sw_interface_set_lldp (vat_main_t * vam)
21567 {
21568   unformat_input_t *i = vam->input;
21569   vl_api_sw_interface_set_lldp_t *mp;
21570   u32 sw_if_index = ~0;
21571   u32 enable = 1;
21572   u8 *port_desc = NULL, *mgmt_oid = NULL;
21573   ip4_address_t ip4_addr;
21574   ip6_address_t ip6_addr;
21575   int ret;
21576
21577   memset (&ip4_addr, 0, sizeof (ip4_addr));
21578   memset (&ip6_addr, 0, sizeof (ip6_addr));
21579
21580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21581     {
21582       if (unformat (i, "disable"))
21583         enable = 0;
21584       else
21585         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21586         ;
21587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21588         ;
21589       else if (unformat (i, "port-desc %s", &port_desc))
21590         ;
21591       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21592         ;
21593       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21594         ;
21595       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21596         ;
21597       else
21598         break;
21599     }
21600
21601   if (sw_if_index == ~0)
21602     {
21603       errmsg ("missing interface name or sw_if_index");
21604       return -99;
21605     }
21606
21607   /* Construct the API message */
21608   vec_add1 (port_desc, 0);
21609   vec_add1 (mgmt_oid, 0);
21610   M (SW_INTERFACE_SET_LLDP, mp);
21611   mp->sw_if_index = ntohl (sw_if_index);
21612   mp->enable = enable;
21613   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21614   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21615   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21616   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21617   vec_free (port_desc);
21618   vec_free (mgmt_oid);
21619
21620   S (mp);
21621   W (ret);
21622   return ret;
21623 }
21624
21625 static int
21626 api_tcp_configure_src_addresses (vat_main_t * vam)
21627 {
21628   vl_api_tcp_configure_src_addresses_t *mp;
21629   unformat_input_t *i = vam->input;
21630   ip4_address_t v4first, v4last;
21631   ip6_address_t v6first, v6last;
21632   u8 range_set = 0;
21633   u32 vrf_id = 0;
21634   int ret;
21635
21636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21637     {
21638       if (unformat (i, "%U - %U",
21639                     unformat_ip4_address, &v4first,
21640                     unformat_ip4_address, &v4last))
21641         {
21642           if (range_set)
21643             {
21644               errmsg ("one range per message (range already set)");
21645               return -99;
21646             }
21647           range_set = 1;
21648         }
21649       else if (unformat (i, "%U - %U",
21650                          unformat_ip6_address, &v6first,
21651                          unformat_ip6_address, &v6last))
21652         {
21653           if (range_set)
21654             {
21655               errmsg ("one range per message (range already set)");
21656               return -99;
21657             }
21658           range_set = 2;
21659         }
21660       else if (unformat (i, "vrf %d", &vrf_id))
21661         ;
21662       else
21663         break;
21664     }
21665
21666   if (range_set == 0)
21667     {
21668       errmsg ("address range not set");
21669       return -99;
21670     }
21671
21672   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21673   mp->vrf_id = ntohl (vrf_id);
21674   /* ipv6? */
21675   if (range_set == 2)
21676     {
21677       mp->is_ipv6 = 1;
21678       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21679       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21680     }
21681   else
21682     {
21683       mp->is_ipv6 = 0;
21684       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21685       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21686     }
21687   S (mp);
21688   W (ret);
21689   return ret;
21690 }
21691
21692 static void vl_api_app_namespace_add_del_reply_t_handler
21693   (vl_api_app_namespace_add_del_reply_t * mp)
21694 {
21695   vat_main_t *vam = &vat_main;
21696   i32 retval = ntohl (mp->retval);
21697   if (vam->async_mode)
21698     {
21699       vam->async_errors += (retval < 0);
21700     }
21701   else
21702     {
21703       vam->retval = retval;
21704       if (retval == 0)
21705         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21706       vam->result_ready = 1;
21707     }
21708 }
21709
21710 static void vl_api_app_namespace_add_del_reply_t_handler_json
21711   (vl_api_app_namespace_add_del_reply_t * mp)
21712 {
21713   vat_main_t *vam = &vat_main;
21714   vat_json_node_t node;
21715
21716   vat_json_init_object (&node);
21717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21718   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21719
21720   vat_json_print (vam->ofp, &node);
21721   vat_json_free (&node);
21722
21723   vam->retval = ntohl (mp->retval);
21724   vam->result_ready = 1;
21725 }
21726
21727 static int
21728 api_app_namespace_add_del (vat_main_t * vam)
21729 {
21730   vl_api_app_namespace_add_del_t *mp;
21731   unformat_input_t *i = vam->input;
21732   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21733   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21734   u64 secret;
21735   int ret;
21736
21737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21738     {
21739       if (unformat (i, "id %_%v%_", &ns_id))
21740         ;
21741       else if (unformat (i, "secret %lu", &secret))
21742         secret_set = 1;
21743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21744         sw_if_index_set = 1;
21745       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21746         ;
21747       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21748         ;
21749       else
21750         break;
21751     }
21752   if (!ns_id || !secret_set || !sw_if_index_set)
21753     {
21754       errmsg ("namespace id, secret and sw_if_index must be set");
21755       return -99;
21756     }
21757   if (vec_len (ns_id) > 64)
21758     {
21759       errmsg ("namespace id too long");
21760       return -99;
21761     }
21762   M (APP_NAMESPACE_ADD_DEL, mp);
21763
21764   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21765   mp->namespace_id_len = vec_len (ns_id);
21766   mp->secret = clib_host_to_net_u64 (secret);
21767   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21768   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21769   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21770   vec_free (ns_id);
21771   S (mp);
21772   W (ret);
21773   return ret;
21774 }
21775
21776 static int
21777 api_memfd_segment_create (vat_main_t * vam)
21778 {
21779 #if VPP_API_TEST_BUILTIN == 0
21780   unformat_input_t *i = vam->input;
21781   vl_api_memfd_segment_create_t *mp;
21782   u64 size = 64 << 20;
21783   int ret;
21784
21785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21786     {
21787       if (unformat (i, "size %U", unformat_memory_size, &size))
21788         ;
21789       else
21790         break;
21791     }
21792
21793   M (MEMFD_SEGMENT_CREATE, mp);
21794   mp->requested_size = size;
21795   S (mp);
21796   W (ret);
21797   return ret;
21798
21799 #else
21800   errmsg ("memfd_segment_create (builtin) not supported");
21801   return -99;
21802 #endif
21803 }
21804
21805 static int
21806 api_dns_enable_disable (vat_main_t * vam)
21807 {
21808   unformat_input_t *line_input = vam->input;
21809   vl_api_dns_enable_disable_t *mp;
21810   u8 enable_disable = 1;
21811   int ret;
21812
21813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21814     {
21815       if (unformat (line_input, "disable"))
21816         enable_disable = 0;
21817       if (unformat (line_input, "enable"))
21818         enable_disable = 1;
21819       else
21820         break;
21821     }
21822
21823   /* Construct the API message */
21824   M (DNS_ENABLE_DISABLE, mp);
21825   mp->enable = enable_disable;
21826
21827   /* send it... */
21828   S (mp);
21829   /* Wait for the reply */
21830   W (ret);
21831   return ret;
21832 }
21833
21834 static int
21835 api_dns_resolve_name (vat_main_t * vam)
21836 {
21837   unformat_input_t *line_input = vam->input;
21838   vl_api_dns_resolve_name_t *mp;
21839   u8 *name = 0;
21840   int ret;
21841
21842   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21843     {
21844       if (unformat (line_input, "%s", &name))
21845         ;
21846       else
21847         break;
21848     }
21849
21850   if (vec_len (name) > 127)
21851     {
21852       errmsg ("name too long");
21853       return -99;
21854     }
21855
21856   /* Construct the API message */
21857   M (DNS_RESOLVE_NAME, mp);
21858   memcpy (mp->name, name, vec_len (name));
21859   vec_free (name);
21860
21861   /* send it... */
21862   S (mp);
21863   /* Wait for the reply */
21864   W (ret);
21865   return ret;
21866 }
21867
21868 static int
21869 api_dns_resolve_ip (vat_main_t * vam)
21870 {
21871   unformat_input_t *line_input = vam->input;
21872   vl_api_dns_resolve_ip_t *mp;
21873   int is_ip6 = -1;
21874   ip4_address_t addr4;
21875   ip6_address_t addr6;
21876   int ret;
21877
21878   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21879     {
21880       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21881         is_ip6 = 1;
21882       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21883         is_ip6 = 0;
21884       else
21885         break;
21886     }
21887
21888   if (is_ip6 == -1)
21889     {
21890       errmsg ("missing address");
21891       return -99;
21892     }
21893
21894   /* Construct the API message */
21895   M (DNS_RESOLVE_IP, mp);
21896   mp->is_ip6 = is_ip6;
21897   if (is_ip6)
21898     memcpy (mp->address, &addr6, sizeof (addr6));
21899   else
21900     memcpy (mp->address, &addr4, sizeof (addr4));
21901
21902   /* send it... */
21903   S (mp);
21904   /* Wait for the reply */
21905   W (ret);
21906   return ret;
21907 }
21908
21909 static int
21910 api_dns_name_server_add_del (vat_main_t * vam)
21911 {
21912   unformat_input_t *i = vam->input;
21913   vl_api_dns_name_server_add_del_t *mp;
21914   u8 is_add = 1;
21915   ip6_address_t ip6_server;
21916   ip4_address_t ip4_server;
21917   int ip6_set = 0;
21918   int ip4_set = 0;
21919   int ret = 0;
21920
21921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21922     {
21923       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21924         ip6_set = 1;
21925       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21926         ip4_set = 1;
21927       else if (unformat (i, "del"))
21928         is_add = 0;
21929       else
21930         {
21931           clib_warning ("parse error '%U'", format_unformat_error, i);
21932           return -99;
21933         }
21934     }
21935
21936   if (ip4_set && ip6_set)
21937     {
21938       errmsg ("Only one server address allowed per message");
21939       return -99;
21940     }
21941   if ((ip4_set + ip6_set) == 0)
21942     {
21943       errmsg ("Server address required");
21944       return -99;
21945     }
21946
21947   /* Construct the API message */
21948   M (DNS_NAME_SERVER_ADD_DEL, mp);
21949
21950   if (ip6_set)
21951     {
21952       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21953       mp->is_ip6 = 1;
21954     }
21955   else
21956     {
21957       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21958       mp->is_ip6 = 0;
21959     }
21960
21961   mp->is_add = is_add;
21962
21963   /* send it... */
21964   S (mp);
21965
21966   /* Wait for a reply, return good/bad news  */
21967   W (ret);
21968   return ret;
21969 }
21970
21971 static void
21972 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21973 {
21974   vat_main_t *vam = &vat_main;
21975
21976   if (mp->is_ip4)
21977     {
21978       print (vam->ofp,
21979              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21980              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21981              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21982              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21983              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21984              clib_net_to_host_u32 (mp->action_index), mp->tag);
21985     }
21986   else
21987     {
21988       print (vam->ofp,
21989              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21990              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21991              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21992              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21993              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21994              clib_net_to_host_u32 (mp->action_index), mp->tag);
21995     }
21996 }
21997
21998 static void
21999 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22000                                              mp)
22001 {
22002   vat_main_t *vam = &vat_main;
22003   vat_json_node_t *node = NULL;
22004   struct in6_addr ip6;
22005   struct in_addr ip4;
22006
22007   if (VAT_JSON_ARRAY != vam->json_tree.type)
22008     {
22009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22010       vat_json_init_array (&vam->json_tree);
22011     }
22012   node = vat_json_array_add (&vam->json_tree);
22013   vat_json_init_object (node);
22014
22015   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22016   vat_json_object_add_uint (node, "appns_index",
22017                             clib_net_to_host_u32 (mp->appns_index));
22018   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22019   vat_json_object_add_uint (node, "scope", mp->scope);
22020   vat_json_object_add_uint (node, "action_index",
22021                             clib_net_to_host_u32 (mp->action_index));
22022   vat_json_object_add_uint (node, "lcl_port",
22023                             clib_net_to_host_u16 (mp->lcl_port));
22024   vat_json_object_add_uint (node, "rmt_port",
22025                             clib_net_to_host_u16 (mp->rmt_port));
22026   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22027   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22028   vat_json_object_add_string_copy (node, "tag", mp->tag);
22029   if (mp->is_ip4)
22030     {
22031       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22032       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22033       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22034       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22035     }
22036   else
22037     {
22038       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22039       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22040       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22041       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22042     }
22043 }
22044
22045 static int
22046 api_session_rule_add_del (vat_main_t * vam)
22047 {
22048   vl_api_session_rule_add_del_t *mp;
22049   unformat_input_t *i = vam->input;
22050   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22051   u32 appns_index = 0, scope = 0;
22052   ip4_address_t lcl_ip4, rmt_ip4;
22053   ip6_address_t lcl_ip6, rmt_ip6;
22054   u8 is_ip4 = 1, conn_set = 0;
22055   u8 is_add = 1, *tag = 0;
22056   int ret;
22057
22058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22059     {
22060       if (unformat (i, "del"))
22061         is_add = 0;
22062       else if (unformat (i, "add"))
22063         ;
22064       else if (unformat (i, "proto tcp"))
22065         proto = 0;
22066       else if (unformat (i, "proto udp"))
22067         proto = 1;
22068       else if (unformat (i, "appns %d", &appns_index))
22069         ;
22070       else if (unformat (i, "scope %d", &scope))
22071         ;
22072       else if (unformat (i, "tag %_%v%_", &tag))
22073         ;
22074       else
22075         if (unformat
22076             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22077              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22078              &rmt_port))
22079         {
22080           is_ip4 = 1;
22081           conn_set = 1;
22082         }
22083       else
22084         if (unformat
22085             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22086              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22087              &rmt_port))
22088         {
22089           is_ip4 = 0;
22090           conn_set = 1;
22091         }
22092       else if (unformat (i, "action %d", &action))
22093         ;
22094       else
22095         break;
22096     }
22097   if (proto == ~0 || !conn_set || action == ~0)
22098     {
22099       errmsg ("transport proto, connection and action must be set");
22100       return -99;
22101     }
22102
22103   if (scope > 3)
22104     {
22105       errmsg ("scope should be 0-3");
22106       return -99;
22107     }
22108
22109   M (SESSION_RULE_ADD_DEL, mp);
22110
22111   mp->is_ip4 = is_ip4;
22112   mp->transport_proto = proto;
22113   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22114   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22115   mp->lcl_plen = lcl_plen;
22116   mp->rmt_plen = rmt_plen;
22117   mp->action_index = clib_host_to_net_u32 (action);
22118   mp->appns_index = clib_host_to_net_u32 (appns_index);
22119   mp->scope = scope;
22120   mp->is_add = is_add;
22121   if (is_ip4)
22122     {
22123       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22124       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22125     }
22126   else
22127     {
22128       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22129       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22130     }
22131   if (tag)
22132     {
22133       clib_memcpy (mp->tag, tag, vec_len (tag));
22134       vec_free (tag);
22135     }
22136
22137   S (mp);
22138   W (ret);
22139   return ret;
22140 }
22141
22142 static int
22143 api_session_rules_dump (vat_main_t * vam)
22144 {
22145   vl_api_session_rules_dump_t *mp;
22146   vl_api_control_ping_t *mp_ping;
22147   int ret;
22148
22149   if (!vam->json_output)
22150     {
22151       print (vam->ofp, "%=20s", "Session Rules");
22152     }
22153
22154   M (SESSION_RULES_DUMP, mp);
22155   /* send it... */
22156   S (mp);
22157
22158   /* Use a control ping for synchronization */
22159   MPING (CONTROL_PING, mp_ping);
22160   S (mp_ping);
22161
22162   /* Wait for a reply... */
22163   W (ret);
22164   return ret;
22165 }
22166
22167 static int
22168 api_ip_container_proxy_add_del (vat_main_t * vam)
22169 {
22170   vl_api_ip_container_proxy_add_del_t *mp;
22171   unformat_input_t *i = vam->input;
22172   u32 plen = ~0, sw_if_index = ~0;
22173   ip4_address_t ip4;
22174   ip6_address_t ip6;
22175   u8 is_ip4 = 1;
22176   u8 is_add = 1;
22177   int ret;
22178
22179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22180     {
22181       if (unformat (i, "del"))
22182         is_add = 0;
22183       else if (unformat (i, "add"))
22184         ;
22185       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22186         {
22187           is_ip4 = 1;
22188           plen = 32;
22189         }
22190       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22191         {
22192           is_ip4 = 0;
22193           plen = 128;
22194         }
22195       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22196         ;
22197       else
22198         break;
22199     }
22200   if (sw_if_index == ~0 || plen == ~0)
22201     {
22202       errmsg ("address and sw_if_index must be set");
22203       return -99;
22204     }
22205
22206   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22207
22208   mp->is_ip4 = is_ip4;
22209   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22210   mp->plen = plen;
22211   mp->is_add = is_add;
22212   if (is_ip4)
22213     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22214   else
22215     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22216
22217   S (mp);
22218   W (ret);
22219   return ret;
22220 }
22221
22222 static int
22223 q_or_quit (vat_main_t * vam)
22224 {
22225 #if VPP_API_TEST_BUILTIN == 0
22226   longjmp (vam->jump_buf, 1);
22227 #endif
22228   return 0;                     /* not so much */
22229 }
22230
22231 static int
22232 q (vat_main_t * vam)
22233 {
22234   return q_or_quit (vam);
22235 }
22236
22237 static int
22238 quit (vat_main_t * vam)
22239 {
22240   return q_or_quit (vam);
22241 }
22242
22243 static int
22244 comment (vat_main_t * vam)
22245 {
22246   return 0;
22247 }
22248
22249 static int
22250 cmd_cmp (void *a1, void *a2)
22251 {
22252   u8 **c1 = a1;
22253   u8 **c2 = a2;
22254
22255   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22256 }
22257
22258 static int
22259 help (vat_main_t * vam)
22260 {
22261   u8 **cmds = 0;
22262   u8 *name = 0;
22263   hash_pair_t *p;
22264   unformat_input_t *i = vam->input;
22265   int j;
22266
22267   if (unformat (i, "%s", &name))
22268     {
22269       uword *hs;
22270
22271       vec_add1 (name, 0);
22272
22273       hs = hash_get_mem (vam->help_by_name, name);
22274       if (hs)
22275         print (vam->ofp, "usage: %s %s", name, hs[0]);
22276       else
22277         print (vam->ofp, "No such msg / command '%s'", name);
22278       vec_free (name);
22279       return 0;
22280     }
22281
22282   print (vam->ofp, "Help is available for the following:");
22283
22284     /* *INDENT-OFF* */
22285     hash_foreach_pair (p, vam->function_by_name,
22286     ({
22287       vec_add1 (cmds, (u8 *)(p->key));
22288     }));
22289     /* *INDENT-ON* */
22290
22291   vec_sort_with_function (cmds, cmd_cmp);
22292
22293   for (j = 0; j < vec_len (cmds); j++)
22294     print (vam->ofp, "%s", cmds[j]);
22295
22296   vec_free (cmds);
22297   return 0;
22298 }
22299
22300 static int
22301 set (vat_main_t * vam)
22302 {
22303   u8 *name = 0, *value = 0;
22304   unformat_input_t *i = vam->input;
22305
22306   if (unformat (i, "%s", &name))
22307     {
22308       /* The input buffer is a vector, not a string. */
22309       value = vec_dup (i->buffer);
22310       vec_delete (value, i->index, 0);
22311       /* Almost certainly has a trailing newline */
22312       if (value[vec_len (value) - 1] == '\n')
22313         value[vec_len (value) - 1] = 0;
22314       /* Make sure it's a proper string, one way or the other */
22315       vec_add1 (value, 0);
22316       (void) clib_macro_set_value (&vam->macro_main,
22317                                    (char *) name, (char *) value);
22318     }
22319   else
22320     errmsg ("usage: set <name> <value>");
22321
22322   vec_free (name);
22323   vec_free (value);
22324   return 0;
22325 }
22326
22327 static int
22328 unset (vat_main_t * vam)
22329 {
22330   u8 *name = 0;
22331
22332   if (unformat (vam->input, "%s", &name))
22333     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22334       errmsg ("unset: %s wasn't set", name);
22335   vec_free (name);
22336   return 0;
22337 }
22338
22339 typedef struct
22340 {
22341   u8 *name;
22342   u8 *value;
22343 } macro_sort_t;
22344
22345
22346 static int
22347 macro_sort_cmp (void *a1, void *a2)
22348 {
22349   macro_sort_t *s1 = a1;
22350   macro_sort_t *s2 = a2;
22351
22352   return strcmp ((char *) (s1->name), (char *) (s2->name));
22353 }
22354
22355 static int
22356 dump_macro_table (vat_main_t * vam)
22357 {
22358   macro_sort_t *sort_me = 0, *sm;
22359   int i;
22360   hash_pair_t *p;
22361
22362     /* *INDENT-OFF* */
22363     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22364     ({
22365       vec_add2 (sort_me, sm, 1);
22366       sm->name = (u8 *)(p->key);
22367       sm->value = (u8 *) (p->value[0]);
22368     }));
22369     /* *INDENT-ON* */
22370
22371   vec_sort_with_function (sort_me, macro_sort_cmp);
22372
22373   if (vec_len (sort_me))
22374     print (vam->ofp, "%-15s%s", "Name", "Value");
22375   else
22376     print (vam->ofp, "The macro table is empty...");
22377
22378   for (i = 0; i < vec_len (sort_me); i++)
22379     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22380   return 0;
22381 }
22382
22383 static int
22384 dump_node_table (vat_main_t * vam)
22385 {
22386   int i, j;
22387   vlib_node_t *node, *next_node;
22388
22389   if (vec_len (vam->graph_nodes) == 0)
22390     {
22391       print (vam->ofp, "Node table empty, issue get_node_graph...");
22392       return 0;
22393     }
22394
22395   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22396     {
22397       node = vam->graph_nodes[i];
22398       print (vam->ofp, "[%d] %s", i, node->name);
22399       for (j = 0; j < vec_len (node->next_nodes); j++)
22400         {
22401           if (node->next_nodes[j] != ~0)
22402             {
22403               next_node = vam->graph_nodes[node->next_nodes[j]];
22404               print (vam->ofp, "  [%d] %s", j, next_node->name);
22405             }
22406         }
22407     }
22408   return 0;
22409 }
22410
22411 static int
22412 value_sort_cmp (void *a1, void *a2)
22413 {
22414   name_sort_t *n1 = a1;
22415   name_sort_t *n2 = a2;
22416
22417   if (n1->value < n2->value)
22418     return -1;
22419   if (n1->value > n2->value)
22420     return 1;
22421   return 0;
22422 }
22423
22424
22425 static int
22426 dump_msg_api_table (vat_main_t * vam)
22427 {
22428   api_main_t *am = &api_main;
22429   name_sort_t *nses = 0, *ns;
22430   hash_pair_t *hp;
22431   int i;
22432
22433   /* *INDENT-OFF* */
22434   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22435   ({
22436     vec_add2 (nses, ns, 1);
22437     ns->name = (u8 *)(hp->key);
22438     ns->value = (u32) hp->value[0];
22439   }));
22440   /* *INDENT-ON* */
22441
22442   vec_sort_with_function (nses, value_sort_cmp);
22443
22444   for (i = 0; i < vec_len (nses); i++)
22445     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22446   vec_free (nses);
22447   return 0;
22448 }
22449
22450 static int
22451 get_msg_id (vat_main_t * vam)
22452 {
22453   u8 *name_and_crc;
22454   u32 message_index;
22455
22456   if (unformat (vam->input, "%s", &name_and_crc))
22457     {
22458       message_index = vl_api_get_msg_index (name_and_crc);
22459       if (message_index == ~0)
22460         {
22461           print (vam->ofp, " '%s' not found", name_and_crc);
22462           return 0;
22463         }
22464       print (vam->ofp, " '%s' has message index %d",
22465              name_and_crc, message_index);
22466       return 0;
22467     }
22468   errmsg ("name_and_crc required...");
22469   return 0;
22470 }
22471
22472 static int
22473 search_node_table (vat_main_t * vam)
22474 {
22475   unformat_input_t *line_input = vam->input;
22476   u8 *node_to_find;
22477   int j;
22478   vlib_node_t *node, *next_node;
22479   uword *p;
22480
22481   if (vam->graph_node_index_by_name == 0)
22482     {
22483       print (vam->ofp, "Node table empty, issue get_node_graph...");
22484       return 0;
22485     }
22486
22487   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22488     {
22489       if (unformat (line_input, "%s", &node_to_find))
22490         {
22491           vec_add1 (node_to_find, 0);
22492           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22493           if (p == 0)
22494             {
22495               print (vam->ofp, "%s not found...", node_to_find);
22496               goto out;
22497             }
22498           node = vam->graph_nodes[p[0]];
22499           print (vam->ofp, "[%d] %s", p[0], node->name);
22500           for (j = 0; j < vec_len (node->next_nodes); j++)
22501             {
22502               if (node->next_nodes[j] != ~0)
22503                 {
22504                   next_node = vam->graph_nodes[node->next_nodes[j]];
22505                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22506                 }
22507             }
22508         }
22509
22510       else
22511         {
22512           clib_warning ("parse error '%U'", format_unformat_error,
22513                         line_input);
22514           return -99;
22515         }
22516
22517     out:
22518       vec_free (node_to_find);
22519
22520     }
22521
22522   return 0;
22523 }
22524
22525
22526 static int
22527 script (vat_main_t * vam)
22528 {
22529 #if (VPP_API_TEST_BUILTIN==0)
22530   u8 *s = 0;
22531   char *save_current_file;
22532   unformat_input_t save_input;
22533   jmp_buf save_jump_buf;
22534   u32 save_line_number;
22535
22536   FILE *new_fp, *save_ifp;
22537
22538   if (unformat (vam->input, "%s", &s))
22539     {
22540       new_fp = fopen ((char *) s, "r");
22541       if (new_fp == 0)
22542         {
22543           errmsg ("Couldn't open script file %s", s);
22544           vec_free (s);
22545           return -99;
22546         }
22547     }
22548   else
22549     {
22550       errmsg ("Missing script name");
22551       return -99;
22552     }
22553
22554   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22555   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22556   save_ifp = vam->ifp;
22557   save_line_number = vam->input_line_number;
22558   save_current_file = (char *) vam->current_file;
22559
22560   vam->input_line_number = 0;
22561   vam->ifp = new_fp;
22562   vam->current_file = s;
22563   do_one_file (vam);
22564
22565   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22566   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22567   vam->ifp = save_ifp;
22568   vam->input_line_number = save_line_number;
22569   vam->current_file = (u8 *) save_current_file;
22570   vec_free (s);
22571
22572   return 0;
22573 #else
22574   clib_warning ("use the exec command...");
22575   return -99;
22576 #endif
22577 }
22578
22579 static int
22580 echo (vat_main_t * vam)
22581 {
22582   print (vam->ofp, "%v", vam->input->buffer);
22583   return 0;
22584 }
22585
22586 /* List of API message constructors, CLI names map to api_xxx */
22587 #define foreach_vpe_api_msg                                             \
22588 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22589 _(sw_interface_dump,"")                                                 \
22590 _(sw_interface_set_flags,                                               \
22591   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22592 _(sw_interface_add_del_address,                                         \
22593   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22594 _(sw_interface_set_rx_mode,                                             \
22595   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22596 _(sw_interface_set_table,                                               \
22597   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22598 _(sw_interface_set_mpls_enable,                                         \
22599   "<intfc> | sw_if_index [disable | dis]")                              \
22600 _(sw_interface_set_vpath,                                               \
22601   "<intfc> | sw_if_index <id> enable | disable")                        \
22602 _(sw_interface_set_vxlan_bypass,                                        \
22603   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22604 _(sw_interface_set_geneve_bypass,                                       \
22605   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22606 _(sw_interface_set_l2_xconnect,                                         \
22607   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22608   "enable | disable")                                                   \
22609 _(sw_interface_set_l2_bridge,                                           \
22610   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22611   "[shg <split-horizon-group>] [bvi]\n"                                 \
22612   "enable | disable")                                                   \
22613 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22614 _(bridge_domain_add_del,                                                \
22615   "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") \
22616 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22617 _(l2fib_add_del,                                                        \
22618   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22619 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22620 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22621 _(l2_flags,                                                             \
22622   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22623 _(bridge_flags,                                                         \
22624   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22625 _(tap_connect,                                                          \
22626   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22627 _(tap_modify,                                                           \
22628   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22629 _(tap_delete,                                                           \
22630   "<vpp-if-name> | sw_if_index <id>")                                   \
22631 _(sw_interface_tap_dump, "")                                            \
22632 _(tap_create_v2,                                                        \
22633   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22634 _(tap_delete_v2,                                                        \
22635   "<vpp-if-name> | sw_if_index <id>")                                   \
22636 _(sw_interface_tap_v2_dump, "")                                         \
22637 _(ip_table_add_del,                                                     \
22638   "table-id <n> [ipv6]\n")                                              \
22639 _(ip_add_del_route,                                                     \
22640   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22641   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22642   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22643   "[multipath] [count <n>]")                                            \
22644 _(ip_mroute_add_del,                                                    \
22645   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22646   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22647 _(mpls_table_add_del,                                                   \
22648   "table-id <n>\n")                                                     \
22649 _(mpls_route_add_del,                                                   \
22650   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22651   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22652   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22653   "[multipath] [count <n>]")                                            \
22654 _(mpls_ip_bind_unbind,                                                  \
22655   "<label> <addr/len>")                                                 \
22656 _(mpls_tunnel_add_del,                                                  \
22657   " via <addr> [table-id <n>]\n"                                        \
22658   "sw_if_index <id>] [l2]  [del]")                                      \
22659 _(bier_table_add_del,                                                   \
22660   "<label> <sub-domain> <set> <bsl> [del]")                             \
22661 _(bier_route_add_del,                                                   \
22662   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22663   "[<intfc> | sw_if_index <id>]"                                        \
22664   "[weight <n>] [del] [multipath]")                                     \
22665 _(proxy_arp_add_del,                                                    \
22666   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22667 _(proxy_arp_intfc_enable_disable,                                       \
22668   "<intfc> | sw_if_index <id> enable | disable")                        \
22669 _(sw_interface_set_unnumbered,                                          \
22670   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22671 _(ip_neighbor_add_del,                                                  \
22672   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22673   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22674 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22675 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22676   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22677   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22678   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22679 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22680 _(reset_fib, "vrf <n> [ipv6]")                                          \
22681 _(dhcp_proxy_config,                                                    \
22682   "svr <v46-address> src <v46-address>\n"                               \
22683    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22684 _(dhcp_proxy_set_vss,                                                   \
22685   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22686 _(dhcp_proxy_dump, "ip6")                                               \
22687 _(dhcp_client_config,                                                   \
22688   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22689 _(set_ip_flow_hash,                                                     \
22690   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22691 _(sw_interface_ip6_enable_disable,                                      \
22692   "<intfc> | sw_if_index <id> enable | disable")                        \
22693 _(sw_interface_ip6_set_link_local_address,                              \
22694   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22695 _(ip6nd_proxy_add_del,                                                  \
22696   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22697 _(ip6nd_proxy_dump, "")                                                 \
22698 _(sw_interface_ip6nd_ra_prefix,                                         \
22699   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22700   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22701   "[nolink] [isno]")                                                    \
22702 _(sw_interface_ip6nd_ra_config,                                         \
22703   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22704   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22705   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22706 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22707 _(l2_patch_add_del,                                                     \
22708   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22709   "enable | disable")                                                   \
22710 _(sr_localsid_add_del,                                                  \
22711   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22712   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22713 _(classify_add_del_table,                                               \
22714   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22715   " [del] [del-chain] mask <mask-value>\n"                              \
22716   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22717   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22718 _(classify_add_del_session,                                             \
22719   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22720   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22721   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22722   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22723 _(classify_set_interface_ip_table,                                      \
22724   "<intfc> | sw_if_index <nn> table <nn>")                              \
22725 _(classify_set_interface_l2_tables,                                     \
22726   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22727   "  [other-table <nn>]")                                               \
22728 _(get_node_index, "node <node-name")                                    \
22729 _(add_node_next, "node <node-name> next <next-node-name>")              \
22730 _(l2tpv3_create_tunnel,                                                 \
22731   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22732   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22733   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22734 _(l2tpv3_set_tunnel_cookies,                                            \
22735   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22736   "[new_remote_cookie <nn>]\n")                                         \
22737 _(l2tpv3_interface_enable_disable,                                      \
22738   "<intfc> | sw_if_index <nn> enable | disable")                        \
22739 _(l2tpv3_set_lookup_key,                                                \
22740   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22741 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22742 _(vxlan_add_del_tunnel,                                                 \
22743   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22744   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22745   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22746 _(geneve_add_del_tunnel,                                                \
22747   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22748   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22749   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22750 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22751 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22752 _(gre_add_del_tunnel,                                                   \
22753   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22754 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22755 _(l2_fib_clear_table, "")                                               \
22756 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22757 _(l2_interface_vlan_tag_rewrite,                                        \
22758   "<intfc> | sw_if_index <nn> \n"                                       \
22759   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22760   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22761 _(create_vhost_user_if,                                                 \
22762         "socket <filename> [server] [renumber <dev_instance>] "         \
22763         "[mac <mac_address>]")                                          \
22764 _(modify_vhost_user_if,                                                 \
22765         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22766         "[server] [renumber <dev_instance>]")                           \
22767 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22768 _(sw_interface_vhost_user_dump, "")                                     \
22769 _(show_version, "")                                                     \
22770 _(vxlan_gpe_add_del_tunnel,                                             \
22771   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22772   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22773   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22774   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22775 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22776 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22777 _(interface_name_renumber,                                              \
22778   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22779 _(input_acl_set_interface,                                              \
22780   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22781   "  [l2-table <nn>] [del]")                                            \
22782 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22783 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22784 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22785 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22786 _(ip_dump, "ipv4 | ipv6")                                               \
22787 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22788 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22789   "  spid_id <n> ")                                                     \
22790 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22791   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22792   "  integ_alg <alg> integ_key <hex>")                                  \
22793 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22794   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22795   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22796   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22797 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22798 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22799   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22800   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22801   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22802 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22803 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22804   "  <alg> <hex>\n")                                                    \
22805 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22806 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22807 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22808   "(auth_data 0x<data> | auth_data <data>)")                            \
22809 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22810   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22811 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22812   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22813   "(local|remote)")                                                     \
22814 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22815 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22816 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22817 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22818 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22819 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22820 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22821 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22822 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22823 _(delete_loopback,"sw_if_index <nn>")                                   \
22824 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22825 _(map_add_domain,                                                       \
22826   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22827   "ip6-src <ip6addr> "                                                  \
22828   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22829 _(map_del_domain, "index <n>")                                          \
22830 _(map_add_del_rule,                                                     \
22831   "index <n> psid <n> dst <ip6addr> [del]")                             \
22832 _(map_domain_dump, "")                                                  \
22833 _(map_rule_dump, "index <map-domain>")                                  \
22834 _(want_interface_events,  "enable|disable")                             \
22835 _(want_stats,"enable|disable")                                          \
22836 _(get_first_msg_id, "client <name>")                                    \
22837 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22838 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22839   "fib-id <nn> [ip4][ip6][default]")                                    \
22840 _(get_node_graph, " ")                                                  \
22841 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22842 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22843 _(ioam_disable, "")                                                     \
22844 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22845                             " sw_if_index <sw_if_index> p <priority> "  \
22846                             "w <weight>] [del]")                        \
22847 _(one_add_del_locator, "locator-set <locator_name> "                    \
22848                         "iface <intf> | sw_if_index <sw_if_index> "     \
22849                         "p <priority> w <weight> [del]")                \
22850 _(one_add_del_local_eid,"vni <vni> eid "                                \
22851                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22852                          "locator-set <locator_name> [del]"             \
22853                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22854 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22855 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22856 _(one_enable_disable, "enable|disable")                                 \
22857 _(one_map_register_enable_disable, "enable|disable")                    \
22858 _(one_map_register_fallback_threshold, "<value>")                       \
22859 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22860 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22861                                "[seid <seid>] "                         \
22862                                "rloc <locator> p <prio> "               \
22863                                "w <weight> [rloc <loc> ... ] "          \
22864                                "action <action> [del-all]")             \
22865 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22866                           "<local-eid>")                                \
22867 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22868 _(one_use_petr, "ip-address> | disable")                                \
22869 _(one_map_request_mode, "src-dst|dst-only")                             \
22870 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22871 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22872 _(one_locator_set_dump, "[local | remote]")                             \
22873 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22874 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22875                        "[local] | [remote]")                            \
22876 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22877 _(one_ndp_bd_get, "")                                                   \
22878 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22879 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22880 _(one_l2_arp_bd_get, "")                                                \
22881 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22882 _(one_stats_enable_disable, "enable|disalbe")                           \
22883 _(show_one_stats_enable_disable, "")                                    \
22884 _(one_eid_table_vni_dump, "")                                           \
22885 _(one_eid_table_map_dump, "l2|l3")                                      \
22886 _(one_map_resolver_dump, "")                                            \
22887 _(one_map_server_dump, "")                                              \
22888 _(one_adjacencies_get, "vni <vni>")                                     \
22889 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22890 _(show_one_rloc_probe_state, "")                                        \
22891 _(show_one_map_register_state, "")                                      \
22892 _(show_one_status, "")                                                  \
22893 _(one_stats_dump, "")                                                   \
22894 _(one_stats_flush, "")                                                  \
22895 _(one_get_map_request_itr_rlocs, "")                                    \
22896 _(one_map_register_set_ttl, "<ttl>")                                    \
22897 _(one_set_transport_protocol, "udp|api")                                \
22898 _(one_get_transport_protocol, "")                                       \
22899 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22900 _(one_show_xtr_mode, "")                                                \
22901 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22902 _(one_show_pitr_mode, "")                                               \
22903 _(one_enable_disable_petr_mode, "enable|disable")                       \
22904 _(one_show_petr_mode, "")                                               \
22905 _(show_one_nsh_mapping, "")                                             \
22906 _(show_one_pitr, "")                                                    \
22907 _(show_one_use_petr, "")                                                \
22908 _(show_one_map_request_mode, "")                                        \
22909 _(show_one_map_register_ttl, "")                                        \
22910 _(show_one_map_register_fallback_threshold, "")                         \
22911 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22912                             " sw_if_index <sw_if_index> p <priority> "  \
22913                             "w <weight>] [del]")                        \
22914 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22915                         "iface <intf> | sw_if_index <sw_if_index> "     \
22916                         "p <priority> w <weight> [del]")                \
22917 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22918                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22919                          "locator-set <locator_name> [del]"             \
22920                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22921 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22922 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22923 _(lisp_enable_disable, "enable|disable")                                \
22924 _(lisp_map_register_enable_disable, "enable|disable")                   \
22925 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22926 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22927                                "[seid <seid>] "                         \
22928                                "rloc <locator> p <prio> "               \
22929                                "w <weight> [rloc <loc> ... ] "          \
22930                                "action <action> [del-all]")             \
22931 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22932                           "<local-eid>")                                \
22933 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22934 _(lisp_use_petr, "<ip-address> | disable")                              \
22935 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22936 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22937 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22938 _(lisp_locator_set_dump, "[local | remote]")                            \
22939 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22940 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22941                        "[local] | [remote]")                            \
22942 _(lisp_eid_table_vni_dump, "")                                          \
22943 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22944 _(lisp_map_resolver_dump, "")                                           \
22945 _(lisp_map_server_dump, "")                                             \
22946 _(lisp_adjacencies_get, "vni <vni>")                                    \
22947 _(gpe_fwd_entry_vnis_get, "")                                           \
22948 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22949 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22950                                 "[table <table-id>]")                   \
22951 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22952 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22953 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22954 _(gpe_get_encap_mode, "")                                               \
22955 _(lisp_gpe_add_del_iface, "up|down")                                    \
22956 _(lisp_gpe_enable_disable, "enable|disable")                            \
22957 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22958   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22959 _(show_lisp_rloc_probe_state, "")                                       \
22960 _(show_lisp_map_register_state, "")                                     \
22961 _(show_lisp_status, "")                                                 \
22962 _(lisp_get_map_request_itr_rlocs, "")                                   \
22963 _(show_lisp_pitr, "")                                                   \
22964 _(show_lisp_use_petr, "")                                               \
22965 _(show_lisp_map_request_mode, "")                                       \
22966 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22967 _(af_packet_delete, "name <host interface name>")                       \
22968 _(policer_add_del, "name <policer name> <params> [del]")                \
22969 _(policer_dump, "[name <policer name>]")                                \
22970 _(policer_classify_set_interface,                                       \
22971   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22972   "  [l2-table <nn>] [del]")                                            \
22973 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22974 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22975     "[master|slave]")                                                   \
22976 _(netmap_delete, "name <interface name>")                               \
22977 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22978 _(mpls_fib_dump, "")                                                    \
22979 _(classify_table_ids, "")                                               \
22980 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22981 _(classify_table_info, "table_id <nn>")                                 \
22982 _(classify_session_dump, "table_id <nn>")                               \
22983 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22984     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22985     "[template_interval <nn>] [udp_checksum]")                          \
22986 _(ipfix_exporter_dump, "")                                              \
22987 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22988 _(ipfix_classify_stream_dump, "")                                       \
22989 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22990 _(ipfix_classify_table_dump, "")                                        \
22991 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22992 _(sw_interface_span_dump, "[l2]")                                           \
22993 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22994 _(pg_create_interface, "if_id <nn>")                                    \
22995 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22996 _(pg_enable_disable, "[stream <id>] disable")                           \
22997 _(ip_source_and_port_range_check_add_del,                               \
22998   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22999 _(ip_source_and_port_range_check_interface_add_del,                     \
23000   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23001   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23002 _(ipsec_gre_add_del_tunnel,                                             \
23003   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23004 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23005 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23006 _(l2_interface_pbb_tag_rewrite,                                         \
23007   "<intfc> | sw_if_index <nn> \n"                                       \
23008   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23009   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23010 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23011 _(flow_classify_set_interface,                                          \
23012   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23013 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23014 _(ip_fib_dump, "")                                                      \
23015 _(ip_mfib_dump, "")                                                     \
23016 _(ip6_fib_dump, "")                                                     \
23017 _(ip6_mfib_dump, "")                                                    \
23018 _(feature_enable_disable, "arc_name <arc_name> "                        \
23019   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23020 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23021 "[disable]")                                                            \
23022 _(l2_xconnect_dump, "")                                                 \
23023 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23024 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23025 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23026 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23027 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23028 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23029 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23030   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23031 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23032 _(memfd_segment_create,"size <nnn>")                                    \
23033 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23034 _(dns_enable_disable, "[enable][disable]")                              \
23035 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23036 _(dns_resolve_name, "<hostname>")                                       \
23037 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23038 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23039 _(dns_resolve_name, "<hostname>")                                       \
23040 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23041   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23042 _(session_rules_dump, "")                                               \
23043 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23044
23045 /* List of command functions, CLI names map directly to functions */
23046 #define foreach_cli_function                                    \
23047 _(comment, "usage: comment <ignore-rest-of-line>")              \
23048 _(dump_interface_table, "usage: dump_interface_table")          \
23049 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23050 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23051 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23052 _(dump_stats_table, "usage: dump_stats_table")                  \
23053 _(dump_macro_table, "usage: dump_macro_table ")                 \
23054 _(dump_node_table, "usage: dump_node_table")                    \
23055 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23056 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23057 _(echo, "usage: echo <message>")                                \
23058 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23059 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23060 _(help, "usage: help")                                          \
23061 _(q, "usage: quit")                                             \
23062 _(quit, "usage: quit")                                          \
23063 _(search_node_table, "usage: search_node_table <name>...")      \
23064 _(set, "usage: set <variable-name> <value>")                    \
23065 _(script, "usage: script <file-name>")                          \
23066 _(unset, "usage: unset <variable-name>")
23067 #define _(N,n)                                  \
23068     static void vl_api_##n##_t_handler_uni      \
23069     (vl_api_##n##_t * mp)                       \
23070     {                                           \
23071         vat_main_t * vam = &vat_main;           \
23072         if (vam->json_output) {                 \
23073             vl_api_##n##_t_handler_json(mp);    \
23074         } else {                                \
23075             vl_api_##n##_t_handler(mp);         \
23076         }                                       \
23077     }
23078 foreach_vpe_api_reply_msg;
23079 #if VPP_API_TEST_BUILTIN == 0
23080 foreach_standalone_reply_msg;
23081 #endif
23082 #undef _
23083
23084 void
23085 vat_api_hookup (vat_main_t * vam)
23086 {
23087 #define _(N,n)                                                  \
23088     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23089                            vl_api_##n##_t_handler_uni,          \
23090                            vl_noop_handler,                     \
23091                            vl_api_##n##_t_endian,               \
23092                            vl_api_##n##_t_print,                \
23093                            sizeof(vl_api_##n##_t), 1);
23094   foreach_vpe_api_reply_msg;
23095 #if VPP_API_TEST_BUILTIN == 0
23096   foreach_standalone_reply_msg;
23097 #endif
23098 #undef _
23099
23100 #if (VPP_API_TEST_BUILTIN==0)
23101   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23102
23103   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23104
23105   vam->function_by_name = hash_create_string (0, sizeof (uword));
23106
23107   vam->help_by_name = hash_create_string (0, sizeof (uword));
23108 #endif
23109
23110   /* API messages we can send */
23111 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23112   foreach_vpe_api_msg;
23113 #undef _
23114
23115   /* Help strings */
23116 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23117   foreach_vpe_api_msg;
23118 #undef _
23119
23120   /* CLI functions */
23121 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23122   foreach_cli_function;
23123 #undef _
23124
23125   /* Help strings */
23126 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23127   foreach_cli_function;
23128 #undef _
23129 }
23130
23131 #if VPP_API_TEST_BUILTIN
23132 static clib_error_t *
23133 vat_api_hookup_shim (vlib_main_t * vm)
23134 {
23135   vat_api_hookup (&vat_main);
23136   return 0;
23137 }
23138
23139 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23140 #endif
23141
23142 /*
23143  * fd.io coding-style-patch-verification: ON
23144  *
23145  * Local Variables:
23146  * eval: (c-set-style "gnu")
23147  * End:
23148  */