tap_v2: include host-side parameters in the dump binary API
[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   u32 id = ~0;
7814   u8 *host_if_name = 0;
7815   u8 *host_ns = 0;
7816   u8 host_mac_addr[6];
7817   u8 host_mac_addr_set = 0;
7818   u8 *host_bridge = 0;
7819   ip4_address_t host_ip4_addr;
7820   u32 host_ip4_prefix_len = 0;
7821   ip6_address_t host_ip6_addr;
7822   u32 host_ip6_prefix_len = 0;
7823   int ret;
7824   int rx_ring_sz = 0, tx_ring_sz = 0;
7825
7826   memset (mac_address, 0, sizeof (mac_address));
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7832         {
7833           random_mac = 0;
7834         }
7835       else if (unformat (i, "id %s", &id))
7836         ;
7837       else if (unformat (i, "host-if-name %s", &host_if_name))
7838         ;
7839       else if (unformat (i, "host-ns %s", &host_ns))
7840         ;
7841       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7842                          host_mac_addr))
7843         host_mac_addr_set = 1;
7844       else if (unformat (i, "host-bridge %s", &host_bridge))
7845         ;
7846       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7847                          &host_ip4_addr, &host_ip4_prefix_len))
7848         ;
7849       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7850                          &host_ip6_addr, &host_ip6_prefix_len))
7851         ;
7852       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7853         ;
7854       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7855         ;
7856       else
7857         break;
7858     }
7859
7860   if (vec_len (host_if_name) > 63)
7861     {
7862       errmsg ("tap name too long. ");
7863       return -99;
7864     }
7865   if (vec_len (host_ns) > 63)
7866     {
7867       errmsg ("host name space too long. ");
7868       return -99;
7869     }
7870   if (vec_len (host_bridge) > 63)
7871     {
7872       errmsg ("host bridge name too long. ");
7873       return -99;
7874     }
7875   if (host_ip4_prefix_len > 32)
7876     {
7877       errmsg ("host ip4 prefix length not valid. ");
7878       return -99;
7879     }
7880   if (host_ip6_prefix_len > 128)
7881     {
7882       errmsg ("host ip6 prefix length not valid. ");
7883       return -99;
7884     }
7885   if (!is_pow2 (rx_ring_sz))
7886     {
7887       errmsg ("rx ring size must be power of 2. ");
7888       return -99;
7889     }
7890   if (rx_ring_sz > 32768)
7891     {
7892       errmsg ("rx ring size must be 32768 or lower. ");
7893       return -99;
7894     }
7895   if (!is_pow2 (tx_ring_sz))
7896     {
7897       errmsg ("tx ring size must be power of 2. ");
7898       return -99;
7899     }
7900   if (tx_ring_sz > 32768)
7901     {
7902       errmsg ("tx ring size must be 32768 or lower. ");
7903       return -99;
7904     }
7905
7906   /* Construct the API message */
7907   M (TAP_CREATE_V2, mp);
7908
7909   mp->use_random_mac = random_mac;
7910
7911   mp->id = id;
7912   mp->host_namespace_set = host_ns != 0;
7913   mp->host_bridge_set = host_bridge != 0;
7914   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7915   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7916   mp->rx_ring_sz = rx_ring_sz;
7917   mp->tx_ring_sz = tx_ring_sz;
7918
7919   if (random_mac)
7920     clib_memcpy (mp->mac_address, mac_address, 6);
7921   if (host_mac_addr_set)
7922     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7923   if (host_if_name)
7924     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7925   if (host_ns)
7926     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7927   if (host_bridge)
7928     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7929   if (host_ip4_prefix_len)
7930     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7931   if (host_ip4_prefix_len)
7932     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7933
7934
7935   vec_free (host_ns);
7936   vec_free (host_if_name);
7937   vec_free (host_bridge);
7938
7939   /* send it... */
7940   S (mp);
7941
7942   /* Wait for a reply... */
7943   W (ret);
7944   return ret;
7945 }
7946
7947 static int
7948 api_tap_delete_v2 (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_tap_delete_v2_t *mp;
7952   u32 sw_if_index = ~0;
7953   u8 sw_if_index_set = 0;
7954   int ret;
7955
7956   /* Parse args required to build the message */
7957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7960         sw_if_index_set = 1;
7961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7962         sw_if_index_set = 1;
7963       else
7964         break;
7965     }
7966
7967   if (sw_if_index_set == 0)
7968     {
7969       errmsg ("missing vpp interface name. ");
7970       return -99;
7971     }
7972
7973   /* Construct the API message */
7974   M (TAP_DELETE_V2, mp);
7975
7976   mp->sw_if_index = ntohl (sw_if_index);
7977
7978   /* send it... */
7979   S (mp);
7980
7981   /* Wait for a reply... */
7982   W (ret);
7983   return ret;
7984 }
7985
7986 static int
7987 api_ip_table_add_del (vat_main_t * vam)
7988 {
7989   unformat_input_t *i = vam->input;
7990   vl_api_ip_table_add_del_t *mp;
7991   u32 table_id = ~0;
7992   u8 is_ipv6 = 0;
7993   u8 is_add = 1;
7994   int ret = 0;
7995
7996   /* Parse args required to build the message */
7997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7998     {
7999       if (unformat (i, "ipv6"))
8000         is_ipv6 = 1;
8001       else if (unformat (i, "del"))
8002         is_add = 0;
8003       else if (unformat (i, "add"))
8004         is_add = 1;
8005       else if (unformat (i, "table %d", &table_id))
8006         ;
8007       else
8008         {
8009           clib_warning ("parse error '%U'", format_unformat_error, i);
8010           return -99;
8011         }
8012     }
8013
8014   if (~0 == table_id)
8015     {
8016       errmsg ("missing table-ID");
8017       return -99;
8018     }
8019
8020   /* Construct the API message */
8021   M (IP_TABLE_ADD_DEL, mp);
8022
8023   mp->table_id = ntohl (table_id);
8024   mp->is_ipv6 = is_ipv6;
8025   mp->is_add = is_add;
8026
8027   /* send it... */
8028   S (mp);
8029
8030   /* Wait for a reply... */
8031   W (ret);
8032
8033   return ret;
8034 }
8035
8036 static int
8037 api_ip_add_del_route (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_add_del_route_t *mp;
8041   u32 sw_if_index = ~0, vrf_id = 0;
8042   u8 is_ipv6 = 0;
8043   u8 is_local = 0, is_drop = 0;
8044   u8 is_unreach = 0, is_prohibit = 0;
8045   u8 is_add = 1;
8046   u32 next_hop_weight = 1;
8047   u8 is_multipath = 0;
8048   u8 address_set = 0;
8049   u8 address_length_set = 0;
8050   u32 next_hop_table_id = 0;
8051   u32 resolve_attempts = 0;
8052   u32 dst_address_length = 0;
8053   u8 next_hop_set = 0;
8054   ip4_address_t v4_dst_address, v4_next_hop_address;
8055   ip6_address_t v6_dst_address, v6_next_hop_address;
8056   int count = 1;
8057   int j;
8058   f64 before = 0;
8059   u32 random_add_del = 0;
8060   u32 *random_vector = 0;
8061   uword *random_hash;
8062   u32 random_seed = 0xdeaddabe;
8063   u32 classify_table_index = ~0;
8064   u8 is_classify = 0;
8065   u8 resolve_host = 0, resolve_attached = 0;
8066   mpls_label_t *next_hop_out_label_stack = NULL;
8067   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8068   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8069
8070   /* Parse args required to build the message */
8071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8074         ;
8075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8076         ;
8077       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8078         {
8079           address_set = 1;
8080           is_ipv6 = 0;
8081         }
8082       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8083         {
8084           address_set = 1;
8085           is_ipv6 = 1;
8086         }
8087       else if (unformat (i, "/%d", &dst_address_length))
8088         {
8089           address_length_set = 1;
8090         }
8091
8092       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8093                                          &v4_next_hop_address))
8094         {
8095           next_hop_set = 1;
8096         }
8097       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8098                                          &v6_next_hop_address))
8099         {
8100           next_hop_set = 1;
8101         }
8102       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8103         ;
8104       else if (unformat (i, "weight %d", &next_hop_weight))
8105         ;
8106       else if (unformat (i, "drop"))
8107         {
8108           is_drop = 1;
8109         }
8110       else if (unformat (i, "null-send-unreach"))
8111         {
8112           is_unreach = 1;
8113         }
8114       else if (unformat (i, "null-send-prohibit"))
8115         {
8116           is_prohibit = 1;
8117         }
8118       else if (unformat (i, "local"))
8119         {
8120           is_local = 1;
8121         }
8122       else if (unformat (i, "classify %d", &classify_table_index))
8123         {
8124           is_classify = 1;
8125         }
8126       else if (unformat (i, "del"))
8127         is_add = 0;
8128       else if (unformat (i, "add"))
8129         is_add = 1;
8130       else if (unformat (i, "resolve-via-host"))
8131         resolve_host = 1;
8132       else if (unformat (i, "resolve-via-attached"))
8133         resolve_attached = 1;
8134       else if (unformat (i, "multipath"))
8135         is_multipath = 1;
8136       else if (unformat (i, "vrf %d", &vrf_id))
8137         ;
8138       else if (unformat (i, "count %d", &count))
8139         ;
8140       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8141         ;
8142       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8143         ;
8144       else if (unformat (i, "out-label %d", &next_hop_out_label))
8145         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8146       else if (unformat (i, "via-label %d", &next_hop_via_label))
8147         ;
8148       else if (unformat (i, "random"))
8149         random_add_del = 1;
8150       else if (unformat (i, "seed %d", &random_seed))
8151         ;
8152       else
8153         {
8154           clib_warning ("parse error '%U'", format_unformat_error, i);
8155           return -99;
8156         }
8157     }
8158
8159   if (!next_hop_set && !is_drop && !is_local &&
8160       !is_classify && !is_unreach && !is_prohibit &&
8161       MPLS_LABEL_INVALID == next_hop_via_label)
8162     {
8163       errmsg
8164         ("next hop / local / drop / unreach / prohibit / classify not set");
8165       return -99;
8166     }
8167
8168   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8169     {
8170       errmsg ("next hop and next-hop via label set");
8171       return -99;
8172     }
8173   if (address_set == 0)
8174     {
8175       errmsg ("missing addresses");
8176       return -99;
8177     }
8178
8179   if (address_length_set == 0)
8180     {
8181       errmsg ("missing address length");
8182       return -99;
8183     }
8184
8185   /* Generate a pile of unique, random routes */
8186   if (random_add_del)
8187     {
8188       u32 this_random_address;
8189       random_hash = hash_create (count, sizeof (uword));
8190
8191       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8192       for (j = 0; j <= count; j++)
8193         {
8194           do
8195             {
8196               this_random_address = random_u32 (&random_seed);
8197               this_random_address =
8198                 clib_host_to_net_u32 (this_random_address);
8199             }
8200           while (hash_get (random_hash, this_random_address));
8201           vec_add1 (random_vector, this_random_address);
8202           hash_set (random_hash, this_random_address, 1);
8203         }
8204       hash_free (random_hash);
8205       v4_dst_address.as_u32 = random_vector[0];
8206     }
8207
8208   if (count > 1)
8209     {
8210       /* Turn on async mode */
8211       vam->async_mode = 1;
8212       vam->async_errors = 0;
8213       before = vat_time_now (vam);
8214     }
8215
8216   for (j = 0; j < count; j++)
8217     {
8218       /* Construct the API message */
8219       M2 (IP_ADD_DEL_ROUTE, mp,
8220           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8221
8222       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8223       mp->table_id = ntohl (vrf_id);
8224
8225       mp->is_add = is_add;
8226       mp->is_drop = is_drop;
8227       mp->is_unreach = is_unreach;
8228       mp->is_prohibit = is_prohibit;
8229       mp->is_ipv6 = is_ipv6;
8230       mp->is_local = is_local;
8231       mp->is_classify = is_classify;
8232       mp->is_multipath = is_multipath;
8233       mp->is_resolve_host = resolve_host;
8234       mp->is_resolve_attached = resolve_attached;
8235       mp->next_hop_weight = next_hop_weight;
8236       mp->dst_address_length = dst_address_length;
8237       mp->next_hop_table_id = ntohl (next_hop_table_id);
8238       mp->classify_table_index = ntohl (classify_table_index);
8239       mp->next_hop_via_label = ntohl (next_hop_via_label);
8240       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8241       if (0 != mp->next_hop_n_out_labels)
8242         {
8243           memcpy (mp->next_hop_out_label_stack,
8244                   next_hop_out_label_stack,
8245                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8246           vec_free (next_hop_out_label_stack);
8247         }
8248
8249       if (is_ipv6)
8250         {
8251           clib_memcpy (mp->dst_address, &v6_dst_address,
8252                        sizeof (v6_dst_address));
8253           if (next_hop_set)
8254             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8255                          sizeof (v6_next_hop_address));
8256           increment_v6_address (&v6_dst_address);
8257         }
8258       else
8259         {
8260           clib_memcpy (mp->dst_address, &v4_dst_address,
8261                        sizeof (v4_dst_address));
8262           if (next_hop_set)
8263             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8264                          sizeof (v4_next_hop_address));
8265           if (random_add_del)
8266             v4_dst_address.as_u32 = random_vector[j + 1];
8267           else
8268             increment_v4_address (&v4_dst_address);
8269         }
8270       /* send it... */
8271       S (mp);
8272       /* If we receive SIGTERM, stop now... */
8273       if (vam->do_exit)
8274         break;
8275     }
8276
8277   /* When testing multiple add/del ops, use a control-ping to sync */
8278   if (count > 1)
8279     {
8280       vl_api_control_ping_t *mp_ping;
8281       f64 after;
8282       f64 timeout;
8283
8284       /* Shut off async mode */
8285       vam->async_mode = 0;
8286
8287       MPING (CONTROL_PING, mp_ping);
8288       S (mp_ping);
8289
8290       timeout = vat_time_now (vam) + 1.0;
8291       while (vat_time_now (vam) < timeout)
8292         if (vam->result_ready == 1)
8293           goto out;
8294       vam->retval = -99;
8295
8296     out:
8297       if (vam->retval == -99)
8298         errmsg ("timeout");
8299
8300       if (vam->async_errors > 0)
8301         {
8302           errmsg ("%d asynchronous errors", vam->async_errors);
8303           vam->retval = -98;
8304         }
8305       vam->async_errors = 0;
8306       after = vat_time_now (vam);
8307
8308       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8309       if (j > 0)
8310         count = j;
8311
8312       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8313              count, after - before, count / (after - before));
8314     }
8315   else
8316     {
8317       int ret;
8318
8319       /* Wait for a reply... */
8320       W (ret);
8321       return ret;
8322     }
8323
8324   /* Return the good/bad news */
8325   return (vam->retval);
8326 }
8327
8328 static int
8329 api_ip_mroute_add_del (vat_main_t * vam)
8330 {
8331   unformat_input_t *i = vam->input;
8332   vl_api_ip_mroute_add_del_t *mp;
8333   u32 sw_if_index = ~0, vrf_id = 0;
8334   u8 is_ipv6 = 0;
8335   u8 is_local = 0;
8336   u8 is_add = 1;
8337   u8 address_set = 0;
8338   u32 grp_address_length = 0;
8339   ip4_address_t v4_grp_address, v4_src_address;
8340   ip6_address_t v6_grp_address, v6_src_address;
8341   mfib_itf_flags_t iflags = 0;
8342   mfib_entry_flags_t eflags = 0;
8343   int ret;
8344
8345   /* Parse args required to build the message */
8346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347     {
8348       if (unformat (i, "sw_if_index %d", &sw_if_index))
8349         ;
8350       else if (unformat (i, "%U %U",
8351                          unformat_ip4_address, &v4_src_address,
8352                          unformat_ip4_address, &v4_grp_address))
8353         {
8354           grp_address_length = 64;
8355           address_set = 1;
8356           is_ipv6 = 0;
8357         }
8358       else if (unformat (i, "%U %U",
8359                          unformat_ip6_address, &v6_src_address,
8360                          unformat_ip6_address, &v6_grp_address))
8361         {
8362           grp_address_length = 256;
8363           address_set = 1;
8364           is_ipv6 = 1;
8365         }
8366       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8367         {
8368           memset (&v4_src_address, 0, sizeof (v4_src_address));
8369           grp_address_length = 32;
8370           address_set = 1;
8371           is_ipv6 = 0;
8372         }
8373       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8374         {
8375           memset (&v6_src_address, 0, sizeof (v6_src_address));
8376           grp_address_length = 128;
8377           address_set = 1;
8378           is_ipv6 = 1;
8379         }
8380       else if (unformat (i, "/%d", &grp_address_length))
8381         ;
8382       else if (unformat (i, "local"))
8383         {
8384           is_local = 1;
8385         }
8386       else if (unformat (i, "del"))
8387         is_add = 0;
8388       else if (unformat (i, "add"))
8389         is_add = 1;
8390       else if (unformat (i, "vrf %d", &vrf_id))
8391         ;
8392       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8393         ;
8394       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8395         ;
8396       else
8397         {
8398           clib_warning ("parse error '%U'", format_unformat_error, i);
8399           return -99;
8400         }
8401     }
8402
8403   if (address_set == 0)
8404     {
8405       errmsg ("missing addresses\n");
8406       return -99;
8407     }
8408
8409   /* Construct the API message */
8410   M (IP_MROUTE_ADD_DEL, mp);
8411
8412   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8413   mp->table_id = ntohl (vrf_id);
8414
8415   mp->is_add = is_add;
8416   mp->is_ipv6 = is_ipv6;
8417   mp->is_local = is_local;
8418   mp->itf_flags = ntohl (iflags);
8419   mp->entry_flags = ntohl (eflags);
8420   mp->grp_address_length = grp_address_length;
8421   mp->grp_address_length = ntohs (mp->grp_address_length);
8422
8423   if (is_ipv6)
8424     {
8425       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8426       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8427     }
8428   else
8429     {
8430       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8431       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8432
8433     }
8434
8435   /* send it... */
8436   S (mp);
8437   /* Wait for a reply... */
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static int
8443 api_mpls_table_add_del (vat_main_t * vam)
8444 {
8445   unformat_input_t *i = vam->input;
8446   vl_api_mpls_table_add_del_t *mp;
8447   u32 table_id = ~0;
8448   u8 is_add = 1;
8449   int ret = 0;
8450
8451   /* Parse args required to build the message */
8452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8453     {
8454       if (unformat (i, "table %d", &table_id))
8455         ;
8456       else if (unformat (i, "del"))
8457         is_add = 0;
8458       else if (unformat (i, "add"))
8459         is_add = 1;
8460       else
8461         {
8462           clib_warning ("parse error '%U'", format_unformat_error, i);
8463           return -99;
8464         }
8465     }
8466
8467   if (~0 == table_id)
8468     {
8469       errmsg ("missing table-ID");
8470       return -99;
8471     }
8472
8473   /* Construct the API message */
8474   M (MPLS_TABLE_ADD_DEL, mp);
8475
8476   mp->mt_table_id = ntohl (table_id);
8477   mp->mt_is_add = is_add;
8478
8479   /* send it... */
8480   S (mp);
8481
8482   /* Wait for a reply... */
8483   W (ret);
8484
8485   return ret;
8486 }
8487
8488 static int
8489 api_mpls_route_add_del (vat_main_t * vam)
8490 {
8491   unformat_input_t *i = vam->input;
8492   vl_api_mpls_route_add_del_t *mp;
8493   u32 sw_if_index = ~0, table_id = 0;
8494   u8 is_add = 1;
8495   u32 next_hop_weight = 1;
8496   u8 is_multipath = 0;
8497   u32 next_hop_table_id = 0;
8498   u8 next_hop_set = 0;
8499   ip4_address_t v4_next_hop_address = {
8500     .as_u32 = 0,
8501   };
8502   ip6_address_t v6_next_hop_address = { {0} };
8503   int count = 1;
8504   int j;
8505   f64 before = 0;
8506   u32 classify_table_index = ~0;
8507   u8 is_classify = 0;
8508   u8 resolve_host = 0, resolve_attached = 0;
8509   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8510   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8511   mpls_label_t *next_hop_out_label_stack = NULL;
8512   mpls_label_t local_label = MPLS_LABEL_INVALID;
8513   u8 is_eos = 0;
8514   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8515
8516   /* Parse args required to build the message */
8517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8518     {
8519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8520         ;
8521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8522         ;
8523       else if (unformat (i, "%d", &local_label))
8524         ;
8525       else if (unformat (i, "eos"))
8526         is_eos = 1;
8527       else if (unformat (i, "non-eos"))
8528         is_eos = 0;
8529       else if (unformat (i, "via %U", unformat_ip4_address,
8530                          &v4_next_hop_address))
8531         {
8532           next_hop_set = 1;
8533           next_hop_proto = DPO_PROTO_IP4;
8534         }
8535       else if (unformat (i, "via %U", unformat_ip6_address,
8536                          &v6_next_hop_address))
8537         {
8538           next_hop_set = 1;
8539           next_hop_proto = DPO_PROTO_IP6;
8540         }
8541       else if (unformat (i, "weight %d", &next_hop_weight))
8542         ;
8543       else if (unformat (i, "classify %d", &classify_table_index))
8544         {
8545           is_classify = 1;
8546         }
8547       else if (unformat (i, "del"))
8548         is_add = 0;
8549       else if (unformat (i, "add"))
8550         is_add = 1;
8551       else if (unformat (i, "resolve-via-host"))
8552         resolve_host = 1;
8553       else if (unformat (i, "resolve-via-attached"))
8554         resolve_attached = 1;
8555       else if (unformat (i, "multipath"))
8556         is_multipath = 1;
8557       else if (unformat (i, "count %d", &count))
8558         ;
8559       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8560         {
8561           next_hop_set = 1;
8562           next_hop_proto = DPO_PROTO_IP4;
8563         }
8564       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8565         {
8566           next_hop_set = 1;
8567           next_hop_proto = DPO_PROTO_IP6;
8568         }
8569       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8570         ;
8571       else if (unformat (i, "via-label %d", &next_hop_via_label))
8572         ;
8573       else if (unformat (i, "out-label %d", &next_hop_out_label))
8574         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8575       else
8576         {
8577           clib_warning ("parse error '%U'", format_unformat_error, i);
8578           return -99;
8579         }
8580     }
8581
8582   if (!next_hop_set && !is_classify)
8583     {
8584       errmsg ("next hop / classify not set");
8585       return -99;
8586     }
8587
8588   if (MPLS_LABEL_INVALID == local_label)
8589     {
8590       errmsg ("missing label");
8591       return -99;
8592     }
8593
8594   if (count > 1)
8595     {
8596       /* Turn on async mode */
8597       vam->async_mode = 1;
8598       vam->async_errors = 0;
8599       before = vat_time_now (vam);
8600     }
8601
8602   for (j = 0; j < count; j++)
8603     {
8604       /* Construct the API message */
8605       M2 (MPLS_ROUTE_ADD_DEL, mp,
8606           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8607
8608       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8609       mp->mr_table_id = ntohl (table_id);
8610
8611       mp->mr_is_add = is_add;
8612       mp->mr_next_hop_proto = next_hop_proto;
8613       mp->mr_is_classify = is_classify;
8614       mp->mr_is_multipath = is_multipath;
8615       mp->mr_is_resolve_host = resolve_host;
8616       mp->mr_is_resolve_attached = resolve_attached;
8617       mp->mr_next_hop_weight = next_hop_weight;
8618       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8619       mp->mr_classify_table_index = ntohl (classify_table_index);
8620       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8621       mp->mr_label = ntohl (local_label);
8622       mp->mr_eos = is_eos;
8623
8624       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8625       if (0 != mp->mr_next_hop_n_out_labels)
8626         {
8627           memcpy (mp->mr_next_hop_out_label_stack,
8628                   next_hop_out_label_stack,
8629                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8630           vec_free (next_hop_out_label_stack);
8631         }
8632
8633       if (next_hop_set)
8634         {
8635           if (DPO_PROTO_IP4 == next_hop_proto)
8636             {
8637               clib_memcpy (mp->mr_next_hop,
8638                            &v4_next_hop_address,
8639                            sizeof (v4_next_hop_address));
8640             }
8641           else if (DPO_PROTO_IP6 == next_hop_proto)
8642
8643             {
8644               clib_memcpy (mp->mr_next_hop,
8645                            &v6_next_hop_address,
8646                            sizeof (v6_next_hop_address));
8647             }
8648         }
8649       local_label++;
8650
8651       /* send it... */
8652       S (mp);
8653       /* If we receive SIGTERM, stop now... */
8654       if (vam->do_exit)
8655         break;
8656     }
8657
8658   /* When testing multiple add/del ops, use a control-ping to sync */
8659   if (count > 1)
8660     {
8661       vl_api_control_ping_t *mp_ping;
8662       f64 after;
8663       f64 timeout;
8664
8665       /* Shut off async mode */
8666       vam->async_mode = 0;
8667
8668       MPING (CONTROL_PING, mp_ping);
8669       S (mp_ping);
8670
8671       timeout = vat_time_now (vam) + 1.0;
8672       while (vat_time_now (vam) < timeout)
8673         if (vam->result_ready == 1)
8674           goto out;
8675       vam->retval = -99;
8676
8677     out:
8678       if (vam->retval == -99)
8679         errmsg ("timeout");
8680
8681       if (vam->async_errors > 0)
8682         {
8683           errmsg ("%d asynchronous errors", vam->async_errors);
8684           vam->retval = -98;
8685         }
8686       vam->async_errors = 0;
8687       after = vat_time_now (vam);
8688
8689       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8690       if (j > 0)
8691         count = j;
8692
8693       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8694              count, after - before, count / (after - before));
8695     }
8696   else
8697     {
8698       int ret;
8699
8700       /* Wait for a reply... */
8701       W (ret);
8702       return ret;
8703     }
8704
8705   /* Return the good/bad news */
8706   return (vam->retval);
8707 }
8708
8709 static int
8710 api_mpls_ip_bind_unbind (vat_main_t * vam)
8711 {
8712   unformat_input_t *i = vam->input;
8713   vl_api_mpls_ip_bind_unbind_t *mp;
8714   u32 ip_table_id = 0;
8715   u8 is_bind = 1;
8716   u8 is_ip4 = 1;
8717   ip4_address_t v4_address;
8718   ip6_address_t v6_address;
8719   u32 address_length;
8720   u8 address_set = 0;
8721   mpls_label_t local_label = MPLS_LABEL_INVALID;
8722   int ret;
8723
8724   /* Parse args required to build the message */
8725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8726     {
8727       if (unformat (i, "%U/%d", unformat_ip4_address,
8728                     &v4_address, &address_length))
8729         {
8730           is_ip4 = 1;
8731           address_set = 1;
8732         }
8733       else if (unformat (i, "%U/%d", unformat_ip6_address,
8734                          &v6_address, &address_length))
8735         {
8736           is_ip4 = 0;
8737           address_set = 1;
8738         }
8739       else if (unformat (i, "%d", &local_label))
8740         ;
8741       else if (unformat (i, "table-id %d", &ip_table_id))
8742         ;
8743       else if (unformat (i, "unbind"))
8744         is_bind = 0;
8745       else if (unformat (i, "bind"))
8746         is_bind = 1;
8747       else
8748         {
8749           clib_warning ("parse error '%U'", format_unformat_error, i);
8750           return -99;
8751         }
8752     }
8753
8754   if (!address_set)
8755     {
8756       errmsg ("IP addres not set");
8757       return -99;
8758     }
8759
8760   if (MPLS_LABEL_INVALID == local_label)
8761     {
8762       errmsg ("missing label");
8763       return -99;
8764     }
8765
8766   /* Construct the API message */
8767   M (MPLS_IP_BIND_UNBIND, mp);
8768
8769   mp->mb_is_bind = is_bind;
8770   mp->mb_is_ip4 = is_ip4;
8771   mp->mb_ip_table_id = ntohl (ip_table_id);
8772   mp->mb_mpls_table_id = 0;
8773   mp->mb_label = ntohl (local_label);
8774   mp->mb_address_length = address_length;
8775
8776   if (is_ip4)
8777     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8778   else
8779     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8780
8781   /* send it... */
8782   S (mp);
8783
8784   /* Wait for a reply... */
8785   W (ret);
8786   return ret;
8787 }
8788
8789 static int
8790 api_bier_table_add_del (vat_main_t * vam)
8791 {
8792   unformat_input_t *i = vam->input;
8793   vl_api_bier_table_add_del_t *mp;
8794   u8 is_add = 1;
8795   u32 set = 0, sub_domain = 0, hdr_len = 3;
8796   mpls_label_t local_label = MPLS_LABEL_INVALID;
8797   int ret;
8798
8799   /* Parse args required to build the message */
8800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8801     {
8802       if (unformat (i, "sub-domain %d", &sub_domain))
8803         ;
8804       else if (unformat (i, "set %d", &set))
8805         ;
8806       else if (unformat (i, "label %d", &local_label))
8807         ;
8808       else if (unformat (i, "hdr-len %d", &hdr_len))
8809         ;
8810       else if (unformat (i, "add"))
8811         is_add = 1;
8812       else if (unformat (i, "del"))
8813         is_add = 0;
8814       else
8815         {
8816           clib_warning ("parse error '%U'", format_unformat_error, i);
8817           return -99;
8818         }
8819     }
8820
8821   if (MPLS_LABEL_INVALID == local_label)
8822     {
8823       errmsg ("missing label\n");
8824       return -99;
8825     }
8826
8827   /* Construct the API message */
8828   M (BIER_TABLE_ADD_DEL, mp);
8829
8830   mp->bt_is_add = is_add;
8831   mp->bt_label = ntohl (local_label);
8832   mp->bt_tbl_id.bt_set = set;
8833   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8834   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8835
8836   /* send it... */
8837   S (mp);
8838
8839   /* Wait for a reply... */
8840   W (ret);
8841
8842   return (ret);
8843 }
8844
8845 static int
8846 api_bier_route_add_del (vat_main_t * vam)
8847 {
8848   unformat_input_t *i = vam->input;
8849   vl_api_bier_route_add_del_t *mp;
8850   u8 is_add = 1;
8851   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8852   ip4_address_t v4_next_hop_address;
8853   ip6_address_t v6_next_hop_address;
8854   u8 next_hop_set = 0;
8855   u8 next_hop_proto_is_ip4 = 1;
8856   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8857   int ret;
8858
8859   /* Parse args required to build the message */
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8863         {
8864           next_hop_proto_is_ip4 = 1;
8865           next_hop_set = 1;
8866         }
8867       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8868         {
8869           next_hop_proto_is_ip4 = 0;
8870           next_hop_set = 1;
8871         }
8872       if (unformat (i, "sub-domain %d", &sub_domain))
8873         ;
8874       else if (unformat (i, "set %d", &set))
8875         ;
8876       else if (unformat (i, "hdr-len %d", &hdr_len))
8877         ;
8878       else if (unformat (i, "bp %d", &bp))
8879         ;
8880       else if (unformat (i, "add"))
8881         is_add = 1;
8882       else if (unformat (i, "del"))
8883         is_add = 0;
8884       else if (unformat (i, "out-label %d", &next_hop_out_label))
8885         ;
8886       else
8887         {
8888           clib_warning ("parse error '%U'", format_unformat_error, i);
8889           return -99;
8890         }
8891     }
8892
8893   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8894     {
8895       errmsg ("next hop / label set\n");
8896       return -99;
8897     }
8898   if (0 == bp)
8899     {
8900       errmsg ("bit=position not set\n");
8901       return -99;
8902     }
8903
8904   /* Construct the API message */
8905   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8906
8907   mp->br_is_add = is_add;
8908   mp->br_tbl_id.bt_set = set;
8909   mp->br_tbl_id.bt_sub_domain = sub_domain;
8910   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8911   mp->br_bp = ntohs (bp);
8912   mp->br_n_paths = 1;
8913   mp->br_paths[0].n_labels = 1;
8914   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8915   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8916
8917   if (next_hop_proto_is_ip4)
8918     {
8919       clib_memcpy (mp->br_paths[0].next_hop,
8920                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8921     }
8922   else
8923     {
8924       clib_memcpy (mp->br_paths[0].next_hop,
8925                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8926     }
8927
8928   /* send it... */
8929   S (mp);
8930
8931   /* Wait for a reply... */
8932   W (ret);
8933
8934   return (ret);
8935 }
8936
8937 static int
8938 api_proxy_arp_add_del (vat_main_t * vam)
8939 {
8940   unformat_input_t *i = vam->input;
8941   vl_api_proxy_arp_add_del_t *mp;
8942   u32 vrf_id = 0;
8943   u8 is_add = 1;
8944   ip4_address_t lo, hi;
8945   u8 range_set = 0;
8946   int ret;
8947
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "vrf %d", &vrf_id))
8951         ;
8952       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8953                          unformat_ip4_address, &hi))
8954         range_set = 1;
8955       else if (unformat (i, "del"))
8956         is_add = 0;
8957       else
8958         {
8959           clib_warning ("parse error '%U'", format_unformat_error, i);
8960           return -99;
8961         }
8962     }
8963
8964   if (range_set == 0)
8965     {
8966       errmsg ("address range not set");
8967       return -99;
8968     }
8969
8970   M (PROXY_ARP_ADD_DEL, mp);
8971
8972   mp->vrf_id = ntohl (vrf_id);
8973   mp->is_add = is_add;
8974   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8975   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8976
8977   S (mp);
8978   W (ret);
8979   return ret;
8980 }
8981
8982 static int
8983 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8984 {
8985   unformat_input_t *i = vam->input;
8986   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8987   u32 sw_if_index;
8988   u8 enable = 1;
8989   u8 sw_if_index_set = 0;
8990   int ret;
8991
8992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8995         sw_if_index_set = 1;
8996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8997         sw_if_index_set = 1;
8998       else if (unformat (i, "enable"))
8999         enable = 1;
9000       else if (unformat (i, "disable"))
9001         enable = 0;
9002       else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (sw_if_index_set == 0)
9010     {
9011       errmsg ("missing interface name or sw_if_index");
9012       return -99;
9013     }
9014
9015   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9016
9017   mp->sw_if_index = ntohl (sw_if_index);
9018   mp->enable_disable = enable;
9019
9020   S (mp);
9021   W (ret);
9022   return ret;
9023 }
9024
9025 static int
9026 api_mpls_tunnel_add_del (vat_main_t * vam)
9027 {
9028   unformat_input_t *i = vam->input;
9029   vl_api_mpls_tunnel_add_del_t *mp;
9030
9031   u8 is_add = 1;
9032   u8 l2_only = 0;
9033   u32 sw_if_index = ~0;
9034   u32 next_hop_sw_if_index = ~0;
9035   u32 next_hop_proto_is_ip4 = 1;
9036
9037   u32 next_hop_table_id = 0;
9038   ip4_address_t v4_next_hop_address = {
9039     .as_u32 = 0,
9040   };
9041   ip6_address_t v6_next_hop_address = { {0} };
9042   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9043   int ret;
9044
9045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (i, "add"))
9048         is_add = 1;
9049       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9050         is_add = 0;
9051       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9052         ;
9053       else if (unformat (i, "via %U",
9054                          unformat_ip4_address, &v4_next_hop_address))
9055         {
9056           next_hop_proto_is_ip4 = 1;
9057         }
9058       else if (unformat (i, "via %U",
9059                          unformat_ip6_address, &v6_next_hop_address))
9060         {
9061           next_hop_proto_is_ip4 = 0;
9062         }
9063       else if (unformat (i, "l2-only"))
9064         l2_only = 1;
9065       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9066         ;
9067       else if (unformat (i, "out-label %d", &next_hop_out_label))
9068         vec_add1 (labels, ntohl (next_hop_out_label));
9069       else
9070         {
9071           clib_warning ("parse error '%U'", format_unformat_error, i);
9072           return -99;
9073         }
9074     }
9075
9076   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9077
9078   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9079   mp->mt_sw_if_index = ntohl (sw_if_index);
9080   mp->mt_is_add = is_add;
9081   mp->mt_l2_only = l2_only;
9082   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9083   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9084
9085   mp->mt_next_hop_n_out_labels = vec_len (labels);
9086
9087   if (0 != mp->mt_next_hop_n_out_labels)
9088     {
9089       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9090                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9091       vec_free (labels);
9092     }
9093
9094   if (next_hop_proto_is_ip4)
9095     {
9096       clib_memcpy (mp->mt_next_hop,
9097                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9098     }
9099   else
9100     {
9101       clib_memcpy (mp->mt_next_hop,
9102                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9103     }
9104
9105   S (mp);
9106   W (ret);
9107   return ret;
9108 }
9109
9110 static int
9111 api_sw_interface_set_unnumbered (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_sw_interface_set_unnumbered_t *mp;
9115   u32 sw_if_index;
9116   u32 unnum_sw_index = ~0;
9117   u8 is_add = 1;
9118   u8 sw_if_index_set = 0;
9119   int ret;
9120
9121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9122     {
9123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9124         sw_if_index_set = 1;
9125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9126         sw_if_index_set = 1;
9127       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9128         ;
9129       else if (unformat (i, "del"))
9130         is_add = 0;
9131       else
9132         {
9133           clib_warning ("parse error '%U'", format_unformat_error, i);
9134           return -99;
9135         }
9136     }
9137
9138   if (sw_if_index_set == 0)
9139     {
9140       errmsg ("missing interface name or sw_if_index");
9141       return -99;
9142     }
9143
9144   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9145
9146   mp->sw_if_index = ntohl (sw_if_index);
9147   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9148   mp->is_add = is_add;
9149
9150   S (mp);
9151   W (ret);
9152   return ret;
9153 }
9154
9155 static int
9156 api_ip_neighbor_add_del (vat_main_t * vam)
9157 {
9158   unformat_input_t *i = vam->input;
9159   vl_api_ip_neighbor_add_del_t *mp;
9160   u32 sw_if_index;
9161   u8 sw_if_index_set = 0;
9162   u8 is_add = 1;
9163   u8 is_static = 0;
9164   u8 is_no_fib_entry = 0;
9165   u8 mac_address[6];
9166   u8 mac_set = 0;
9167   u8 v4_address_set = 0;
9168   u8 v6_address_set = 0;
9169   ip4_address_t v4address;
9170   ip6_address_t v6address;
9171   int ret;
9172
9173   memset (mac_address, 0, sizeof (mac_address));
9174
9175   /* Parse args required to build the message */
9176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9177     {
9178       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9179         {
9180           mac_set = 1;
9181         }
9182       else if (unformat (i, "del"))
9183         is_add = 0;
9184       else
9185         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9186         sw_if_index_set = 1;
9187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9188         sw_if_index_set = 1;
9189       else if (unformat (i, "is_static"))
9190         is_static = 1;
9191       else if (unformat (i, "no-fib-entry"))
9192         is_no_fib_entry = 1;
9193       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9194         v4_address_set = 1;
9195       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9196         v6_address_set = 1;
9197       else
9198         {
9199           clib_warning ("parse error '%U'", format_unformat_error, i);
9200           return -99;
9201         }
9202     }
9203
9204   if (sw_if_index_set == 0)
9205     {
9206       errmsg ("missing interface name or sw_if_index");
9207       return -99;
9208     }
9209   if (v4_address_set && v6_address_set)
9210     {
9211       errmsg ("both v4 and v6 addresses set");
9212       return -99;
9213     }
9214   if (!v4_address_set && !v6_address_set)
9215     {
9216       errmsg ("no address set");
9217       return -99;
9218     }
9219
9220   /* Construct the API message */
9221   M (IP_NEIGHBOR_ADD_DEL, mp);
9222
9223   mp->sw_if_index = ntohl (sw_if_index);
9224   mp->is_add = is_add;
9225   mp->is_static = is_static;
9226   mp->is_no_adj_fib = is_no_fib_entry;
9227   if (mac_set)
9228     clib_memcpy (mp->mac_address, mac_address, 6);
9229   if (v6_address_set)
9230     {
9231       mp->is_ipv6 = 1;
9232       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9233     }
9234   else
9235     {
9236       /* mp->is_ipv6 = 0; via memset in M macro above */
9237       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9238     }
9239
9240   /* send it... */
9241   S (mp);
9242
9243   /* Wait for a reply, return good/bad news  */
9244   W (ret);
9245   return ret;
9246 }
9247
9248 static int
9249 api_create_vlan_subif (vat_main_t * vam)
9250 {
9251   unformat_input_t *i = vam->input;
9252   vl_api_create_vlan_subif_t *mp;
9253   u32 sw_if_index;
9254   u8 sw_if_index_set = 0;
9255   u32 vlan_id;
9256   u8 vlan_id_set = 0;
9257   int ret;
9258
9259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9260     {
9261       if (unformat (i, "sw_if_index %d", &sw_if_index))
9262         sw_if_index_set = 1;
9263       else
9264         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9265         sw_if_index_set = 1;
9266       else if (unformat (i, "vlan %d", &vlan_id))
9267         vlan_id_set = 1;
9268       else
9269         {
9270           clib_warning ("parse error '%U'", format_unformat_error, i);
9271           return -99;
9272         }
9273     }
9274
9275   if (sw_if_index_set == 0)
9276     {
9277       errmsg ("missing interface name or sw_if_index");
9278       return -99;
9279     }
9280
9281   if (vlan_id_set == 0)
9282     {
9283       errmsg ("missing vlan_id");
9284       return -99;
9285     }
9286   M (CREATE_VLAN_SUBIF, mp);
9287
9288   mp->sw_if_index = ntohl (sw_if_index);
9289   mp->vlan_id = ntohl (vlan_id);
9290
9291   S (mp);
9292   W (ret);
9293   return ret;
9294 }
9295
9296 #define foreach_create_subif_bit                \
9297 _(no_tags)                                      \
9298 _(one_tag)                                      \
9299 _(two_tags)                                     \
9300 _(dot1ad)                                       \
9301 _(exact_match)                                  \
9302 _(default_sub)                                  \
9303 _(outer_vlan_id_any)                            \
9304 _(inner_vlan_id_any)
9305
9306 static int
9307 api_create_subif (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_create_subif_t *mp;
9311   u32 sw_if_index;
9312   u8 sw_if_index_set = 0;
9313   u32 sub_id;
9314   u8 sub_id_set = 0;
9315   u32 no_tags = 0;
9316   u32 one_tag = 0;
9317   u32 two_tags = 0;
9318   u32 dot1ad = 0;
9319   u32 exact_match = 0;
9320   u32 default_sub = 0;
9321   u32 outer_vlan_id_any = 0;
9322   u32 inner_vlan_id_any = 0;
9323   u32 tmp;
9324   u16 outer_vlan_id = 0;
9325   u16 inner_vlan_id = 0;
9326   int ret;
9327
9328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9329     {
9330       if (unformat (i, "sw_if_index %d", &sw_if_index))
9331         sw_if_index_set = 1;
9332       else
9333         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9334         sw_if_index_set = 1;
9335       else if (unformat (i, "sub_id %d", &sub_id))
9336         sub_id_set = 1;
9337       else if (unformat (i, "outer_vlan_id %d", &tmp))
9338         outer_vlan_id = tmp;
9339       else if (unformat (i, "inner_vlan_id %d", &tmp))
9340         inner_vlan_id = tmp;
9341
9342 #define _(a) else if (unformat (i, #a)) a = 1 ;
9343       foreach_create_subif_bit
9344 #undef _
9345         else
9346         {
9347           clib_warning ("parse error '%U'", format_unformat_error, i);
9348           return -99;
9349         }
9350     }
9351
9352   if (sw_if_index_set == 0)
9353     {
9354       errmsg ("missing interface name or sw_if_index");
9355       return -99;
9356     }
9357
9358   if (sub_id_set == 0)
9359     {
9360       errmsg ("missing sub_id");
9361       return -99;
9362     }
9363   M (CREATE_SUBIF, mp);
9364
9365   mp->sw_if_index = ntohl (sw_if_index);
9366   mp->sub_id = ntohl (sub_id);
9367
9368 #define _(a) mp->a = a;
9369   foreach_create_subif_bit;
9370 #undef _
9371
9372   mp->outer_vlan_id = ntohs (outer_vlan_id);
9373   mp->inner_vlan_id = ntohs (inner_vlan_id);
9374
9375   S (mp);
9376   W (ret);
9377   return ret;
9378 }
9379
9380 static int
9381 api_oam_add_del (vat_main_t * vam)
9382 {
9383   unformat_input_t *i = vam->input;
9384   vl_api_oam_add_del_t *mp;
9385   u32 vrf_id = 0;
9386   u8 is_add = 1;
9387   ip4_address_t src, dst;
9388   u8 src_set = 0;
9389   u8 dst_set = 0;
9390   int ret;
9391
9392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (unformat (i, "vrf %d", &vrf_id))
9395         ;
9396       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9397         src_set = 1;
9398       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9399         dst_set = 1;
9400       else if (unformat (i, "del"))
9401         is_add = 0;
9402       else
9403         {
9404           clib_warning ("parse error '%U'", format_unformat_error, i);
9405           return -99;
9406         }
9407     }
9408
9409   if (src_set == 0)
9410     {
9411       errmsg ("missing src addr");
9412       return -99;
9413     }
9414
9415   if (dst_set == 0)
9416     {
9417       errmsg ("missing dst addr");
9418       return -99;
9419     }
9420
9421   M (OAM_ADD_DEL, mp);
9422
9423   mp->vrf_id = ntohl (vrf_id);
9424   mp->is_add = is_add;
9425   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9426   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9427
9428   S (mp);
9429   W (ret);
9430   return ret;
9431 }
9432
9433 static int
9434 api_reset_fib (vat_main_t * vam)
9435 {
9436   unformat_input_t *i = vam->input;
9437   vl_api_reset_fib_t *mp;
9438   u32 vrf_id = 0;
9439   u8 is_ipv6 = 0;
9440   u8 vrf_id_set = 0;
9441
9442   int ret;
9443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9444     {
9445       if (unformat (i, "vrf %d", &vrf_id))
9446         vrf_id_set = 1;
9447       else if (unformat (i, "ipv6"))
9448         is_ipv6 = 1;
9449       else
9450         {
9451           clib_warning ("parse error '%U'", format_unformat_error, i);
9452           return -99;
9453         }
9454     }
9455
9456   if (vrf_id_set == 0)
9457     {
9458       errmsg ("missing vrf id");
9459       return -99;
9460     }
9461
9462   M (RESET_FIB, mp);
9463
9464   mp->vrf_id = ntohl (vrf_id);
9465   mp->is_ipv6 = is_ipv6;
9466
9467   S (mp);
9468   W (ret);
9469   return ret;
9470 }
9471
9472 static int
9473 api_dhcp_proxy_config (vat_main_t * vam)
9474 {
9475   unformat_input_t *i = vam->input;
9476   vl_api_dhcp_proxy_config_t *mp;
9477   u32 rx_vrf_id = 0;
9478   u32 server_vrf_id = 0;
9479   u8 is_add = 1;
9480   u8 v4_address_set = 0;
9481   u8 v6_address_set = 0;
9482   ip4_address_t v4address;
9483   ip6_address_t v6address;
9484   u8 v4_src_address_set = 0;
9485   u8 v6_src_address_set = 0;
9486   ip4_address_t v4srcaddress;
9487   ip6_address_t v6srcaddress;
9488   int ret;
9489
9490   /* Parse args required to build the message */
9491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (i, "del"))
9494         is_add = 0;
9495       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9496         ;
9497       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9498         ;
9499       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9500         v4_address_set = 1;
9501       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9502         v6_address_set = 1;
9503       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9504         v4_src_address_set = 1;
9505       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9506         v6_src_address_set = 1;
9507       else
9508         break;
9509     }
9510
9511   if (v4_address_set && v6_address_set)
9512     {
9513       errmsg ("both v4 and v6 server addresses set");
9514       return -99;
9515     }
9516   if (!v4_address_set && !v6_address_set)
9517     {
9518       errmsg ("no server addresses set");
9519       return -99;
9520     }
9521
9522   if (v4_src_address_set && v6_src_address_set)
9523     {
9524       errmsg ("both v4 and v6  src addresses set");
9525       return -99;
9526     }
9527   if (!v4_src_address_set && !v6_src_address_set)
9528     {
9529       errmsg ("no src addresses set");
9530       return -99;
9531     }
9532
9533   if (!(v4_src_address_set && v4_address_set) &&
9534       !(v6_src_address_set && v6_address_set))
9535     {
9536       errmsg ("no matching server and src addresses set");
9537       return -99;
9538     }
9539
9540   /* Construct the API message */
9541   M (DHCP_PROXY_CONFIG, mp);
9542
9543   mp->is_add = is_add;
9544   mp->rx_vrf_id = ntohl (rx_vrf_id);
9545   mp->server_vrf_id = ntohl (server_vrf_id);
9546   if (v6_address_set)
9547     {
9548       mp->is_ipv6 = 1;
9549       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9550       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9551     }
9552   else
9553     {
9554       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9555       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9556     }
9557
9558   /* send it... */
9559   S (mp);
9560
9561   /* Wait for a reply, return good/bad news  */
9562   W (ret);
9563   return ret;
9564 }
9565
9566 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9567 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9568
9569 static void
9570 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9571 {
9572   vat_main_t *vam = &vat_main;
9573   u32 i, count = mp->count;
9574   vl_api_dhcp_server_t *s;
9575
9576   if (mp->is_ipv6)
9577     print (vam->ofp,
9578            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9579            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9580            ntohl (mp->rx_vrf_id),
9581            format_ip6_address, mp->dhcp_src_address,
9582            mp->vss_type, mp->vss_vpn_ascii_id,
9583            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9584   else
9585     print (vam->ofp,
9586            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9587            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9588            ntohl (mp->rx_vrf_id),
9589            format_ip4_address, mp->dhcp_src_address,
9590            mp->vss_type, mp->vss_vpn_ascii_id,
9591            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9592
9593   for (i = 0; i < count; i++)
9594     {
9595       s = &mp->servers[i];
9596
9597       if (mp->is_ipv6)
9598         print (vam->ofp,
9599                " Server Table-ID %d, Server Address %U",
9600                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9601       else
9602         print (vam->ofp,
9603                " Server Table-ID %d, Server Address %U",
9604                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9605     }
9606 }
9607
9608 static void vl_api_dhcp_proxy_details_t_handler_json
9609   (vl_api_dhcp_proxy_details_t * mp)
9610 {
9611   vat_main_t *vam = &vat_main;
9612   vat_json_node_t *node = NULL;
9613   u32 i, count = mp->count;
9614   struct in_addr ip4;
9615   struct in6_addr ip6;
9616   vl_api_dhcp_server_t *s;
9617
9618   if (VAT_JSON_ARRAY != vam->json_tree.type)
9619     {
9620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9621       vat_json_init_array (&vam->json_tree);
9622     }
9623   node = vat_json_array_add (&vam->json_tree);
9624
9625   vat_json_init_object (node);
9626   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9627   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9628                              sizeof (mp->vss_type));
9629   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9630                                    mp->vss_vpn_ascii_id);
9631   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9632   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9633
9634   if (mp->is_ipv6)
9635     {
9636       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9637       vat_json_object_add_ip6 (node, "src_address", ip6);
9638     }
9639   else
9640     {
9641       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9642       vat_json_object_add_ip4 (node, "src_address", ip4);
9643     }
9644
9645   for (i = 0; i < count; i++)
9646     {
9647       s = &mp->servers[i];
9648
9649       vat_json_object_add_uint (node, "server-table-id",
9650                                 ntohl (s->server_vrf_id));
9651
9652       if (mp->is_ipv6)
9653         {
9654           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9655           vat_json_object_add_ip4 (node, "src_address", ip4);
9656         }
9657       else
9658         {
9659           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9660           vat_json_object_add_ip6 (node, "server_address", ip6);
9661         }
9662     }
9663 }
9664
9665 static int
9666 api_dhcp_proxy_dump (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_control_ping_t *mp_ping;
9670   vl_api_dhcp_proxy_dump_t *mp;
9671   u8 is_ipv6 = 0;
9672   int ret;
9673
9674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9675     {
9676       if (unformat (i, "ipv6"))
9677         is_ipv6 = 1;
9678       else
9679         {
9680           clib_warning ("parse error '%U'", format_unformat_error, i);
9681           return -99;
9682         }
9683     }
9684
9685   M (DHCP_PROXY_DUMP, mp);
9686
9687   mp->is_ip6 = is_ipv6;
9688   S (mp);
9689
9690   /* Use a control ping for synchronization */
9691   MPING (CONTROL_PING, mp_ping);
9692   S (mp_ping);
9693
9694   W (ret);
9695   return ret;
9696 }
9697
9698 static int
9699 api_dhcp_proxy_set_vss (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_dhcp_proxy_set_vss_t *mp;
9703   u8 is_ipv6 = 0;
9704   u8 is_add = 1;
9705   u32 tbl_id = ~0;
9706   u8 vss_type = VSS_TYPE_DEFAULT;
9707   u8 *vpn_ascii_id = 0;
9708   u32 oui = 0;
9709   u32 fib_id = 0;
9710   int ret;
9711
9712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9713     {
9714       if (unformat (i, "tbl_id %d", &tbl_id))
9715         ;
9716       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9717         vss_type = VSS_TYPE_ASCII;
9718       else if (unformat (i, "fib_id %d", &fib_id))
9719         vss_type = VSS_TYPE_VPN_ID;
9720       else if (unformat (i, "oui %d", &oui))
9721         vss_type = VSS_TYPE_VPN_ID;
9722       else if (unformat (i, "ipv6"))
9723         is_ipv6 = 1;
9724       else if (unformat (i, "del"))
9725         is_add = 0;
9726       else
9727         break;
9728     }
9729
9730   if (tbl_id == ~0)
9731     {
9732       errmsg ("missing tbl_id ");
9733       vec_free (vpn_ascii_id);
9734       return -99;
9735     }
9736
9737   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9738     {
9739       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9740       vec_free (vpn_ascii_id);
9741       return -99;
9742     }
9743
9744   M (DHCP_PROXY_SET_VSS, mp);
9745   mp->tbl_id = ntohl (tbl_id);
9746   mp->vss_type = vss_type;
9747   if (vpn_ascii_id)
9748     {
9749       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9750       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9751     }
9752   mp->vpn_index = ntohl (fib_id);
9753   mp->oui = ntohl (oui);
9754   mp->is_ipv6 = is_ipv6;
9755   mp->is_add = is_add;
9756
9757   S (mp);
9758   W (ret);
9759
9760   vec_free (vpn_ascii_id);
9761   return ret;
9762 }
9763
9764 static int
9765 api_dhcp_client_config (vat_main_t * vam)
9766 {
9767   unformat_input_t *i = vam->input;
9768   vl_api_dhcp_client_config_t *mp;
9769   u32 sw_if_index;
9770   u8 sw_if_index_set = 0;
9771   u8 is_add = 1;
9772   u8 *hostname = 0;
9773   u8 disable_event = 0;
9774   int ret;
9775
9776   /* Parse args required to build the message */
9777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (i, "del"))
9780         is_add = 0;
9781       else
9782         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9783         sw_if_index_set = 1;
9784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9785         sw_if_index_set = 1;
9786       else if (unformat (i, "hostname %s", &hostname))
9787         ;
9788       else if (unformat (i, "disable_event"))
9789         disable_event = 1;
9790       else
9791         break;
9792     }
9793
9794   if (sw_if_index_set == 0)
9795     {
9796       errmsg ("missing interface name or sw_if_index");
9797       return -99;
9798     }
9799
9800   if (vec_len (hostname) > 63)
9801     {
9802       errmsg ("hostname too long");
9803     }
9804   vec_add1 (hostname, 0);
9805
9806   /* Construct the API message */
9807   M (DHCP_CLIENT_CONFIG, mp);
9808
9809   mp->sw_if_index = htonl (sw_if_index);
9810   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9811   vec_free (hostname);
9812   mp->is_add = is_add;
9813   mp->want_dhcp_event = disable_event ? 0 : 1;
9814   mp->pid = htonl (getpid ());
9815
9816   /* send it... */
9817   S (mp);
9818
9819   /* Wait for a reply, return good/bad news  */
9820   W (ret);
9821   return ret;
9822 }
9823
9824 static int
9825 api_set_ip_flow_hash (vat_main_t * vam)
9826 {
9827   unformat_input_t *i = vam->input;
9828   vl_api_set_ip_flow_hash_t *mp;
9829   u32 vrf_id = 0;
9830   u8 is_ipv6 = 0;
9831   u8 vrf_id_set = 0;
9832   u8 src = 0;
9833   u8 dst = 0;
9834   u8 sport = 0;
9835   u8 dport = 0;
9836   u8 proto = 0;
9837   u8 reverse = 0;
9838   int ret;
9839
9840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9841     {
9842       if (unformat (i, "vrf %d", &vrf_id))
9843         vrf_id_set = 1;
9844       else if (unformat (i, "ipv6"))
9845         is_ipv6 = 1;
9846       else if (unformat (i, "src"))
9847         src = 1;
9848       else if (unformat (i, "dst"))
9849         dst = 1;
9850       else if (unformat (i, "sport"))
9851         sport = 1;
9852       else if (unformat (i, "dport"))
9853         dport = 1;
9854       else if (unformat (i, "proto"))
9855         proto = 1;
9856       else if (unformat (i, "reverse"))
9857         reverse = 1;
9858
9859       else
9860         {
9861           clib_warning ("parse error '%U'", format_unformat_error, i);
9862           return -99;
9863         }
9864     }
9865
9866   if (vrf_id_set == 0)
9867     {
9868       errmsg ("missing vrf id");
9869       return -99;
9870     }
9871
9872   M (SET_IP_FLOW_HASH, mp);
9873   mp->src = src;
9874   mp->dst = dst;
9875   mp->sport = sport;
9876   mp->dport = dport;
9877   mp->proto = proto;
9878   mp->reverse = reverse;
9879   mp->vrf_id = ntohl (vrf_id);
9880   mp->is_ipv6 = is_ipv6;
9881
9882   S (mp);
9883   W (ret);
9884   return ret;
9885 }
9886
9887 static int
9888 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9889 {
9890   unformat_input_t *i = vam->input;
9891   vl_api_sw_interface_ip6_enable_disable_t *mp;
9892   u32 sw_if_index;
9893   u8 sw_if_index_set = 0;
9894   u8 enable = 0;
9895   int ret;
9896
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "enable"))
9904         enable = 1;
9905       else if (unformat (i, "disable"))
9906         enable = 0;
9907       else
9908         {
9909           clib_warning ("parse error '%U'", format_unformat_error, i);
9910           return -99;
9911         }
9912     }
9913
9914   if (sw_if_index_set == 0)
9915     {
9916       errmsg ("missing interface name or sw_if_index");
9917       return -99;
9918     }
9919
9920   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9921
9922   mp->sw_if_index = ntohl (sw_if_index);
9923   mp->enable = enable;
9924
9925   S (mp);
9926   W (ret);
9927   return ret;
9928 }
9929
9930 static int
9931 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9935   u32 sw_if_index;
9936   u8 sw_if_index_set = 0;
9937   u8 v6_address_set = 0;
9938   ip6_address_t v6address;
9939   int ret;
9940
9941   /* Parse args required to build the message */
9942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9945         sw_if_index_set = 1;
9946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9947         sw_if_index_set = 1;
9948       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9949         v6_address_set = 1;
9950       else
9951         break;
9952     }
9953
9954   if (sw_if_index_set == 0)
9955     {
9956       errmsg ("missing interface name or sw_if_index");
9957       return -99;
9958     }
9959   if (!v6_address_set)
9960     {
9961       errmsg ("no address set");
9962       return -99;
9963     }
9964
9965   /* Construct the API message */
9966   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9967
9968   mp->sw_if_index = ntohl (sw_if_index);
9969   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9970
9971   /* send it... */
9972   S (mp);
9973
9974   /* Wait for a reply, return good/bad news  */
9975   W (ret);
9976   return ret;
9977 }
9978
9979 static int
9980 api_ip6nd_proxy_add_del (vat_main_t * vam)
9981 {
9982   unformat_input_t *i = vam->input;
9983   vl_api_ip6nd_proxy_add_del_t *mp;
9984   u32 sw_if_index = ~0;
9985   u8 v6_address_set = 0;
9986   ip6_address_t v6address;
9987   u8 is_del = 0;
9988   int ret;
9989
9990   /* Parse args required to build the message */
9991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9992     {
9993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9994         ;
9995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9996         ;
9997       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9998         v6_address_set = 1;
9999       if (unformat (i, "del"))
10000         is_del = 1;
10001       else
10002         {
10003           clib_warning ("parse error '%U'", format_unformat_error, i);
10004           return -99;
10005         }
10006     }
10007
10008   if (sw_if_index == ~0)
10009     {
10010       errmsg ("missing interface name or sw_if_index");
10011       return -99;
10012     }
10013   if (!v6_address_set)
10014     {
10015       errmsg ("no address set");
10016       return -99;
10017     }
10018
10019   /* Construct the API message */
10020   M (IP6ND_PROXY_ADD_DEL, mp);
10021
10022   mp->is_del = is_del;
10023   mp->sw_if_index = ntohl (sw_if_index);
10024   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10025
10026   /* send it... */
10027   S (mp);
10028
10029   /* Wait for a reply, return good/bad news  */
10030   W (ret);
10031   return ret;
10032 }
10033
10034 static int
10035 api_ip6nd_proxy_dump (vat_main_t * vam)
10036 {
10037   vl_api_ip6nd_proxy_dump_t *mp;
10038   vl_api_control_ping_t *mp_ping;
10039   int ret;
10040
10041   M (IP6ND_PROXY_DUMP, mp);
10042
10043   S (mp);
10044
10045   /* Use a control ping for synchronization */
10046   MPING (CONTROL_PING, mp_ping);
10047   S (mp_ping);
10048
10049   W (ret);
10050   return ret;
10051 }
10052
10053 static void vl_api_ip6nd_proxy_details_t_handler
10054   (vl_api_ip6nd_proxy_details_t * mp)
10055 {
10056   vat_main_t *vam = &vat_main;
10057
10058   print (vam->ofp, "host %U sw_if_index %d",
10059          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10060 }
10061
10062 static void vl_api_ip6nd_proxy_details_t_handler_json
10063   (vl_api_ip6nd_proxy_details_t * mp)
10064 {
10065   vat_main_t *vam = &vat_main;
10066   struct in6_addr ip6;
10067   vat_json_node_t *node = NULL;
10068
10069   if (VAT_JSON_ARRAY != vam->json_tree.type)
10070     {
10071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10072       vat_json_init_array (&vam->json_tree);
10073     }
10074   node = vat_json_array_add (&vam->json_tree);
10075
10076   vat_json_init_object (node);
10077   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10078
10079   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10080   vat_json_object_add_ip6 (node, "host", ip6);
10081 }
10082
10083 static int
10084 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10085 {
10086   unformat_input_t *i = vam->input;
10087   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10088   u32 sw_if_index;
10089   u8 sw_if_index_set = 0;
10090   u32 address_length = 0;
10091   u8 v6_address_set = 0;
10092   ip6_address_t v6address;
10093   u8 use_default = 0;
10094   u8 no_advertise = 0;
10095   u8 off_link = 0;
10096   u8 no_autoconfig = 0;
10097   u8 no_onlink = 0;
10098   u8 is_no = 0;
10099   u32 val_lifetime = 0;
10100   u32 pref_lifetime = 0;
10101   int ret;
10102
10103   /* Parse args required to build the message */
10104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10105     {
10106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10107         sw_if_index_set = 1;
10108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10109         sw_if_index_set = 1;
10110       else if (unformat (i, "%U/%d",
10111                          unformat_ip6_address, &v6address, &address_length))
10112         v6_address_set = 1;
10113       else if (unformat (i, "val_life %d", &val_lifetime))
10114         ;
10115       else if (unformat (i, "pref_life %d", &pref_lifetime))
10116         ;
10117       else if (unformat (i, "def"))
10118         use_default = 1;
10119       else if (unformat (i, "noadv"))
10120         no_advertise = 1;
10121       else if (unformat (i, "offl"))
10122         off_link = 1;
10123       else if (unformat (i, "noauto"))
10124         no_autoconfig = 1;
10125       else if (unformat (i, "nolink"))
10126         no_onlink = 1;
10127       else if (unformat (i, "isno"))
10128         is_no = 1;
10129       else
10130         {
10131           clib_warning ("parse error '%U'", format_unformat_error, i);
10132           return -99;
10133         }
10134     }
10135
10136   if (sw_if_index_set == 0)
10137     {
10138       errmsg ("missing interface name or sw_if_index");
10139       return -99;
10140     }
10141   if (!v6_address_set)
10142     {
10143       errmsg ("no address set");
10144       return -99;
10145     }
10146
10147   /* Construct the API message */
10148   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10149
10150   mp->sw_if_index = ntohl (sw_if_index);
10151   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10152   mp->address_length = address_length;
10153   mp->use_default = use_default;
10154   mp->no_advertise = no_advertise;
10155   mp->off_link = off_link;
10156   mp->no_autoconfig = no_autoconfig;
10157   mp->no_onlink = no_onlink;
10158   mp->is_no = is_no;
10159   mp->val_lifetime = ntohl (val_lifetime);
10160   mp->pref_lifetime = ntohl (pref_lifetime);
10161
10162   /* send it... */
10163   S (mp);
10164
10165   /* Wait for a reply, return good/bad news  */
10166   W (ret);
10167   return ret;
10168 }
10169
10170 static int
10171 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10172 {
10173   unformat_input_t *i = vam->input;
10174   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10175   u32 sw_if_index;
10176   u8 sw_if_index_set = 0;
10177   u8 suppress = 0;
10178   u8 managed = 0;
10179   u8 other = 0;
10180   u8 ll_option = 0;
10181   u8 send_unicast = 0;
10182   u8 cease = 0;
10183   u8 is_no = 0;
10184   u8 default_router = 0;
10185   u32 max_interval = 0;
10186   u32 min_interval = 0;
10187   u32 lifetime = 0;
10188   u32 initial_count = 0;
10189   u32 initial_interval = 0;
10190   int ret;
10191
10192
10193   /* Parse args required to build the message */
10194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10197         sw_if_index_set = 1;
10198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10199         sw_if_index_set = 1;
10200       else if (unformat (i, "maxint %d", &max_interval))
10201         ;
10202       else if (unformat (i, "minint %d", &min_interval))
10203         ;
10204       else if (unformat (i, "life %d", &lifetime))
10205         ;
10206       else if (unformat (i, "count %d", &initial_count))
10207         ;
10208       else if (unformat (i, "interval %d", &initial_interval))
10209         ;
10210       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10211         suppress = 1;
10212       else if (unformat (i, "managed"))
10213         managed = 1;
10214       else if (unformat (i, "other"))
10215         other = 1;
10216       else if (unformat (i, "ll"))
10217         ll_option = 1;
10218       else if (unformat (i, "send"))
10219         send_unicast = 1;
10220       else if (unformat (i, "cease"))
10221         cease = 1;
10222       else if (unformat (i, "isno"))
10223         is_no = 1;
10224       else if (unformat (i, "def"))
10225         default_router = 1;
10226       else
10227         {
10228           clib_warning ("parse error '%U'", format_unformat_error, i);
10229           return -99;
10230         }
10231     }
10232
10233   if (sw_if_index_set == 0)
10234     {
10235       errmsg ("missing interface name or sw_if_index");
10236       return -99;
10237     }
10238
10239   /* Construct the API message */
10240   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10241
10242   mp->sw_if_index = ntohl (sw_if_index);
10243   mp->max_interval = ntohl (max_interval);
10244   mp->min_interval = ntohl (min_interval);
10245   mp->lifetime = ntohl (lifetime);
10246   mp->initial_count = ntohl (initial_count);
10247   mp->initial_interval = ntohl (initial_interval);
10248   mp->suppress = suppress;
10249   mp->managed = managed;
10250   mp->other = other;
10251   mp->ll_option = ll_option;
10252   mp->send_unicast = send_unicast;
10253   mp->cease = cease;
10254   mp->is_no = is_no;
10255   mp->default_router = default_router;
10256
10257   /* send it... */
10258   S (mp);
10259
10260   /* Wait for a reply, return good/bad news  */
10261   W (ret);
10262   return ret;
10263 }
10264
10265 static int
10266 api_set_arp_neighbor_limit (vat_main_t * vam)
10267 {
10268   unformat_input_t *i = vam->input;
10269   vl_api_set_arp_neighbor_limit_t *mp;
10270   u32 arp_nbr_limit;
10271   u8 limit_set = 0;
10272   u8 is_ipv6 = 0;
10273   int ret;
10274
10275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10276     {
10277       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10278         limit_set = 1;
10279       else if (unformat (i, "ipv6"))
10280         is_ipv6 = 1;
10281       else
10282         {
10283           clib_warning ("parse error '%U'", format_unformat_error, i);
10284           return -99;
10285         }
10286     }
10287
10288   if (limit_set == 0)
10289     {
10290       errmsg ("missing limit value");
10291       return -99;
10292     }
10293
10294   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10295
10296   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10297   mp->is_ipv6 = is_ipv6;
10298
10299   S (mp);
10300   W (ret);
10301   return ret;
10302 }
10303
10304 static int
10305 api_l2_patch_add_del (vat_main_t * vam)
10306 {
10307   unformat_input_t *i = vam->input;
10308   vl_api_l2_patch_add_del_t *mp;
10309   u32 rx_sw_if_index;
10310   u8 rx_sw_if_index_set = 0;
10311   u32 tx_sw_if_index;
10312   u8 tx_sw_if_index_set = 0;
10313   u8 is_add = 1;
10314   int ret;
10315
10316   /* Parse args required to build the message */
10317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10318     {
10319       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10320         rx_sw_if_index_set = 1;
10321       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10322         tx_sw_if_index_set = 1;
10323       else if (unformat (i, "rx"))
10324         {
10325           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10326             {
10327               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10328                             &rx_sw_if_index))
10329                 rx_sw_if_index_set = 1;
10330             }
10331           else
10332             break;
10333         }
10334       else if (unformat (i, "tx"))
10335         {
10336           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10337             {
10338               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10339                             &tx_sw_if_index))
10340                 tx_sw_if_index_set = 1;
10341             }
10342           else
10343             break;
10344         }
10345       else if (unformat (i, "del"))
10346         is_add = 0;
10347       else
10348         break;
10349     }
10350
10351   if (rx_sw_if_index_set == 0)
10352     {
10353       errmsg ("missing rx interface name or rx_sw_if_index");
10354       return -99;
10355     }
10356
10357   if (tx_sw_if_index_set == 0)
10358     {
10359       errmsg ("missing tx interface name or tx_sw_if_index");
10360       return -99;
10361     }
10362
10363   M (L2_PATCH_ADD_DEL, mp);
10364
10365   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10366   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10367   mp->is_add = is_add;
10368
10369   S (mp);
10370   W (ret);
10371   return ret;
10372 }
10373
10374 u8 is_del;
10375 u8 localsid_addr[16];
10376 u8 end_psp;
10377 u8 behavior;
10378 u32 sw_if_index;
10379 u32 vlan_index;
10380 u32 fib_table;
10381 u8 nh_addr[16];
10382
10383 static int
10384 api_sr_localsid_add_del (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_sr_localsid_add_del_t *mp;
10388
10389   u8 is_del;
10390   ip6_address_t localsid;
10391   u8 end_psp = 0;
10392   u8 behavior = ~0;
10393   u32 sw_if_index;
10394   u32 fib_table = ~(u32) 0;
10395   ip6_address_t next_hop;
10396
10397   bool nexthop_set = 0;
10398
10399   int ret;
10400
10401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10402     {
10403       if (unformat (i, "del"))
10404         is_del = 1;
10405       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10406       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10407         nexthop_set = 1;
10408       else if (unformat (i, "behavior %u", &behavior));
10409       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10410       else if (unformat (i, "fib-table %u", &fib_table));
10411       else if (unformat (i, "end.psp %u", &behavior));
10412       else
10413         break;
10414     }
10415
10416   M (SR_LOCALSID_ADD_DEL, mp);
10417
10418   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10419   if (nexthop_set)
10420     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10421   mp->behavior = behavior;
10422   mp->sw_if_index = ntohl (sw_if_index);
10423   mp->fib_table = ntohl (fib_table);
10424   mp->end_psp = end_psp;
10425   mp->is_del = is_del;
10426
10427   S (mp);
10428   W (ret);
10429   return ret;
10430 }
10431
10432 static int
10433 api_ioam_enable (vat_main_t * vam)
10434 {
10435   unformat_input_t *input = vam->input;
10436   vl_api_ioam_enable_t *mp;
10437   u32 id = 0;
10438   int has_trace_option = 0;
10439   int has_pot_option = 0;
10440   int has_seqno_option = 0;
10441   int has_analyse_option = 0;
10442   int ret;
10443
10444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (input, "trace"))
10447         has_trace_option = 1;
10448       else if (unformat (input, "pot"))
10449         has_pot_option = 1;
10450       else if (unformat (input, "seqno"))
10451         has_seqno_option = 1;
10452       else if (unformat (input, "analyse"))
10453         has_analyse_option = 1;
10454       else
10455         break;
10456     }
10457   M (IOAM_ENABLE, mp);
10458   mp->id = htons (id);
10459   mp->seqno = has_seqno_option;
10460   mp->analyse = has_analyse_option;
10461   mp->pot_enable = has_pot_option;
10462   mp->trace_enable = has_trace_option;
10463
10464   S (mp);
10465   W (ret);
10466   return ret;
10467 }
10468
10469
10470 static int
10471 api_ioam_disable (vat_main_t * vam)
10472 {
10473   vl_api_ioam_disable_t *mp;
10474   int ret;
10475
10476   M (IOAM_DISABLE, mp);
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482 #define foreach_tcp_proto_field                 \
10483 _(src_port)                                     \
10484 _(dst_port)
10485
10486 #define foreach_udp_proto_field                 \
10487 _(src_port)                                     \
10488 _(dst_port)
10489
10490 #define foreach_ip4_proto_field                 \
10491 _(src_address)                                  \
10492 _(dst_address)                                  \
10493 _(tos)                                          \
10494 _(length)                                       \
10495 _(fragment_id)                                  \
10496 _(ttl)                                          \
10497 _(protocol)                                     \
10498 _(checksum)
10499
10500 typedef struct
10501 {
10502   u16 src_port, dst_port;
10503 } tcpudp_header_t;
10504
10505 #if VPP_API_TEST_BUILTIN == 0
10506 uword
10507 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10508 {
10509   u8 **maskp = va_arg (*args, u8 **);
10510   u8 *mask = 0;
10511   u8 found_something = 0;
10512   tcp_header_t *tcp;
10513
10514 #define _(a) u8 a=0;
10515   foreach_tcp_proto_field;
10516 #undef _
10517
10518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10519     {
10520       if (0);
10521 #define _(a) else if (unformat (input, #a)) a=1;
10522       foreach_tcp_proto_field
10523 #undef _
10524         else
10525         break;
10526     }
10527
10528 #define _(a) found_something += a;
10529   foreach_tcp_proto_field;
10530 #undef _
10531
10532   if (found_something == 0)
10533     return 0;
10534
10535   vec_validate (mask, sizeof (*tcp) - 1);
10536
10537   tcp = (tcp_header_t *) mask;
10538
10539 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10540   foreach_tcp_proto_field;
10541 #undef _
10542
10543   *maskp = mask;
10544   return 1;
10545 }
10546
10547 uword
10548 unformat_udp_mask (unformat_input_t * input, va_list * args)
10549 {
10550   u8 **maskp = va_arg (*args, u8 **);
10551   u8 *mask = 0;
10552   u8 found_something = 0;
10553   udp_header_t *udp;
10554
10555 #define _(a) u8 a=0;
10556   foreach_udp_proto_field;
10557 #undef _
10558
10559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10560     {
10561       if (0);
10562 #define _(a) else if (unformat (input, #a)) a=1;
10563       foreach_udp_proto_field
10564 #undef _
10565         else
10566         break;
10567     }
10568
10569 #define _(a) found_something += a;
10570   foreach_udp_proto_field;
10571 #undef _
10572
10573   if (found_something == 0)
10574     return 0;
10575
10576   vec_validate (mask, sizeof (*udp) - 1);
10577
10578   udp = (udp_header_t *) mask;
10579
10580 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10581   foreach_udp_proto_field;
10582 #undef _
10583
10584   *maskp = mask;
10585   return 1;
10586 }
10587
10588 uword
10589 unformat_l4_mask (unformat_input_t * input, va_list * args)
10590 {
10591   u8 **maskp = va_arg (*args, u8 **);
10592   u16 src_port = 0, dst_port = 0;
10593   tcpudp_header_t *tcpudp;
10594
10595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10598         return 1;
10599       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10600         return 1;
10601       else if (unformat (input, "src_port"))
10602         src_port = 0xFFFF;
10603       else if (unformat (input, "dst_port"))
10604         dst_port = 0xFFFF;
10605       else
10606         return 0;
10607     }
10608
10609   if (!src_port && !dst_port)
10610     return 0;
10611
10612   u8 *mask = 0;
10613   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10614
10615   tcpudp = (tcpudp_header_t *) mask;
10616   tcpudp->src_port = src_port;
10617   tcpudp->dst_port = dst_port;
10618
10619   *maskp = mask;
10620
10621   return 1;
10622 }
10623
10624 uword
10625 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10626 {
10627   u8 **maskp = va_arg (*args, u8 **);
10628   u8 *mask = 0;
10629   u8 found_something = 0;
10630   ip4_header_t *ip;
10631
10632 #define _(a) u8 a=0;
10633   foreach_ip4_proto_field;
10634 #undef _
10635   u8 version = 0;
10636   u8 hdr_length = 0;
10637
10638
10639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10640     {
10641       if (unformat (input, "version"))
10642         version = 1;
10643       else if (unformat (input, "hdr_length"))
10644         hdr_length = 1;
10645       else if (unformat (input, "src"))
10646         src_address = 1;
10647       else if (unformat (input, "dst"))
10648         dst_address = 1;
10649       else if (unformat (input, "proto"))
10650         protocol = 1;
10651
10652 #define _(a) else if (unformat (input, #a)) a=1;
10653       foreach_ip4_proto_field
10654 #undef _
10655         else
10656         break;
10657     }
10658
10659 #define _(a) found_something += a;
10660   foreach_ip4_proto_field;
10661 #undef _
10662
10663   if (found_something == 0)
10664     return 0;
10665
10666   vec_validate (mask, sizeof (*ip) - 1);
10667
10668   ip = (ip4_header_t *) mask;
10669
10670 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10671   foreach_ip4_proto_field;
10672 #undef _
10673
10674   ip->ip_version_and_header_length = 0;
10675
10676   if (version)
10677     ip->ip_version_and_header_length |= 0xF0;
10678
10679   if (hdr_length)
10680     ip->ip_version_and_header_length |= 0x0F;
10681
10682   *maskp = mask;
10683   return 1;
10684 }
10685
10686 #define foreach_ip6_proto_field                 \
10687 _(src_address)                                  \
10688 _(dst_address)                                  \
10689 _(payload_length)                               \
10690 _(hop_limit)                                    \
10691 _(protocol)
10692
10693 uword
10694 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10695 {
10696   u8 **maskp = va_arg (*args, u8 **);
10697   u8 *mask = 0;
10698   u8 found_something = 0;
10699   ip6_header_t *ip;
10700   u32 ip_version_traffic_class_and_flow_label;
10701
10702 #define _(a) u8 a=0;
10703   foreach_ip6_proto_field;
10704 #undef _
10705   u8 version = 0;
10706   u8 traffic_class = 0;
10707   u8 flow_label = 0;
10708
10709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10710     {
10711       if (unformat (input, "version"))
10712         version = 1;
10713       else if (unformat (input, "traffic-class"))
10714         traffic_class = 1;
10715       else if (unformat (input, "flow-label"))
10716         flow_label = 1;
10717       else if (unformat (input, "src"))
10718         src_address = 1;
10719       else if (unformat (input, "dst"))
10720         dst_address = 1;
10721       else if (unformat (input, "proto"))
10722         protocol = 1;
10723
10724 #define _(a) else if (unformat (input, #a)) a=1;
10725       foreach_ip6_proto_field
10726 #undef _
10727         else
10728         break;
10729     }
10730
10731 #define _(a) found_something += a;
10732   foreach_ip6_proto_field;
10733 #undef _
10734
10735   if (found_something == 0)
10736     return 0;
10737
10738   vec_validate (mask, sizeof (*ip) - 1);
10739
10740   ip = (ip6_header_t *) mask;
10741
10742 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10743   foreach_ip6_proto_field;
10744 #undef _
10745
10746   ip_version_traffic_class_and_flow_label = 0;
10747
10748   if (version)
10749     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10750
10751   if (traffic_class)
10752     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10753
10754   if (flow_label)
10755     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10756
10757   ip->ip_version_traffic_class_and_flow_label =
10758     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10759
10760   *maskp = mask;
10761   return 1;
10762 }
10763
10764 uword
10765 unformat_l3_mask (unformat_input_t * input, va_list * args)
10766 {
10767   u8 **maskp = va_arg (*args, u8 **);
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10772         return 1;
10773       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10774         return 1;
10775       else
10776         break;
10777     }
10778   return 0;
10779 }
10780
10781 uword
10782 unformat_l2_mask (unformat_input_t * input, va_list * args)
10783 {
10784   u8 **maskp = va_arg (*args, u8 **);
10785   u8 *mask = 0;
10786   u8 src = 0;
10787   u8 dst = 0;
10788   u8 proto = 0;
10789   u8 tag1 = 0;
10790   u8 tag2 = 0;
10791   u8 ignore_tag1 = 0;
10792   u8 ignore_tag2 = 0;
10793   u8 cos1 = 0;
10794   u8 cos2 = 0;
10795   u8 dot1q = 0;
10796   u8 dot1ad = 0;
10797   int len = 14;
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "src"))
10802         src = 1;
10803       else if (unformat (input, "dst"))
10804         dst = 1;
10805       else if (unformat (input, "proto"))
10806         proto = 1;
10807       else if (unformat (input, "tag1"))
10808         tag1 = 1;
10809       else if (unformat (input, "tag2"))
10810         tag2 = 1;
10811       else if (unformat (input, "ignore-tag1"))
10812         ignore_tag1 = 1;
10813       else if (unformat (input, "ignore-tag2"))
10814         ignore_tag2 = 1;
10815       else if (unformat (input, "cos1"))
10816         cos1 = 1;
10817       else if (unformat (input, "cos2"))
10818         cos2 = 1;
10819       else if (unformat (input, "dot1q"))
10820         dot1q = 1;
10821       else if (unformat (input, "dot1ad"))
10822         dot1ad = 1;
10823       else
10824         break;
10825     }
10826   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10827        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10828     return 0;
10829
10830   if (tag1 || ignore_tag1 || cos1 || dot1q)
10831     len = 18;
10832   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10833     len = 22;
10834
10835   vec_validate (mask, len - 1);
10836
10837   if (dst)
10838     memset (mask, 0xff, 6);
10839
10840   if (src)
10841     memset (mask + 6, 0xff, 6);
10842
10843   if (tag2 || dot1ad)
10844     {
10845       /* inner vlan tag */
10846       if (tag2)
10847         {
10848           mask[19] = 0xff;
10849           mask[18] = 0x0f;
10850         }
10851       if (cos2)
10852         mask[18] |= 0xe0;
10853       if (proto)
10854         mask[21] = mask[20] = 0xff;
10855       if (tag1)
10856         {
10857           mask[15] = 0xff;
10858           mask[14] = 0x0f;
10859         }
10860       if (cos1)
10861         mask[14] |= 0xe0;
10862       *maskp = mask;
10863       return 1;
10864     }
10865   if (tag1 | dot1q)
10866     {
10867       if (tag1)
10868         {
10869           mask[15] = 0xff;
10870           mask[14] = 0x0f;
10871         }
10872       if (cos1)
10873         mask[14] |= 0xe0;
10874       if (proto)
10875         mask[16] = mask[17] = 0xff;
10876
10877       *maskp = mask;
10878       return 1;
10879     }
10880   if (cos2)
10881     mask[18] |= 0xe0;
10882   if (cos1)
10883     mask[14] |= 0xe0;
10884   if (proto)
10885     mask[12] = mask[13] = 0xff;
10886
10887   *maskp = mask;
10888   return 1;
10889 }
10890
10891 uword
10892 unformat_classify_mask (unformat_input_t * input, va_list * args)
10893 {
10894   u8 **maskp = va_arg (*args, u8 **);
10895   u32 *skipp = va_arg (*args, u32 *);
10896   u32 *matchp = va_arg (*args, u32 *);
10897   u32 match;
10898   u8 *mask = 0;
10899   u8 *l2 = 0;
10900   u8 *l3 = 0;
10901   u8 *l4 = 0;
10902   int i;
10903
10904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10907         ;
10908       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10909         ;
10910       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10911         ;
10912       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10913         ;
10914       else
10915         break;
10916     }
10917
10918   if (l4 && !l3)
10919     {
10920       vec_free (mask);
10921       vec_free (l2);
10922       vec_free (l4);
10923       return 0;
10924     }
10925
10926   if (mask || l2 || l3 || l4)
10927     {
10928       if (l2 || l3 || l4)
10929         {
10930           /* "With a free Ethernet header in every package" */
10931           if (l2 == 0)
10932             vec_validate (l2, 13);
10933           mask = l2;
10934           if (vec_len (l3))
10935             {
10936               vec_append (mask, l3);
10937               vec_free (l3);
10938             }
10939           if (vec_len (l4))
10940             {
10941               vec_append (mask, l4);
10942               vec_free (l4);
10943             }
10944         }
10945
10946       /* Scan forward looking for the first significant mask octet */
10947       for (i = 0; i < vec_len (mask); i++)
10948         if (mask[i])
10949           break;
10950
10951       /* compute (skip, match) params */
10952       *skipp = i / sizeof (u32x4);
10953       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10954
10955       /* Pad mask to an even multiple of the vector size */
10956       while (vec_len (mask) % sizeof (u32x4))
10957         vec_add1 (mask, 0);
10958
10959       match = vec_len (mask) / sizeof (u32x4);
10960
10961       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10962         {
10963           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10964           if (*tmp || *(tmp + 1))
10965             break;
10966           match--;
10967         }
10968       if (match == 0)
10969         clib_warning ("BUG: match 0");
10970
10971       _vec_len (mask) = match * sizeof (u32x4);
10972
10973       *matchp = match;
10974       *maskp = mask;
10975
10976       return 1;
10977     }
10978
10979   return 0;
10980 }
10981 #endif /* VPP_API_TEST_BUILTIN */
10982
10983 #define foreach_l2_next                         \
10984 _(drop, DROP)                                   \
10985 _(ethernet, ETHERNET_INPUT)                     \
10986 _(ip4, IP4_INPUT)                               \
10987 _(ip6, IP6_INPUT)
10988
10989 uword
10990 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10991 {
10992   u32 *miss_next_indexp = va_arg (*args, u32 *);
10993   u32 next_index = 0;
10994   u32 tmp;
10995
10996 #define _(n,N) \
10997   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10998   foreach_l2_next;
10999 #undef _
11000
11001   if (unformat (input, "%d", &tmp))
11002     {
11003       next_index = tmp;
11004       goto out;
11005     }
11006
11007   return 0;
11008
11009 out:
11010   *miss_next_indexp = next_index;
11011   return 1;
11012 }
11013
11014 #define foreach_ip_next                         \
11015 _(drop, DROP)                                   \
11016 _(local, LOCAL)                                 \
11017 _(rewrite, REWRITE)
11018
11019 uword
11020 api_unformat_ip_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 = IP_LOOKUP_NEXT_##N; goto out;}
11028   foreach_ip_next;
11029 #undef _
11030
11031   if (unformat (input, "%d", &tmp))
11032     {
11033       next_index = tmp;
11034       goto out;
11035     }
11036
11037   return 0;
11038
11039 out:
11040   *miss_next_indexp = next_index;
11041   return 1;
11042 }
11043
11044 #define foreach_acl_next                        \
11045 _(deny, DENY)
11046
11047 uword
11048 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *miss_next_indexp = va_arg (*args, u32 *);
11051   u32 next_index = 0;
11052   u32 tmp;
11053
11054 #define _(n,N) \
11055   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11056   foreach_acl_next;
11057 #undef _
11058
11059   if (unformat (input, "permit"))
11060     {
11061       next_index = ~0;
11062       goto out;
11063     }
11064   else if (unformat (input, "%d", &tmp))
11065     {
11066       next_index = tmp;
11067       goto out;
11068     }
11069
11070   return 0;
11071
11072 out:
11073   *miss_next_indexp = next_index;
11074   return 1;
11075 }
11076
11077 uword
11078 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11079 {
11080   u32 *r = va_arg (*args, u32 *);
11081
11082   if (unformat (input, "conform-color"))
11083     *r = POLICE_CONFORM;
11084   else if (unformat (input, "exceed-color"))
11085     *r = POLICE_EXCEED;
11086   else
11087     return 0;
11088
11089   return 1;
11090 }
11091
11092 static int
11093 api_classify_add_del_table (vat_main_t * vam)
11094 {
11095   unformat_input_t *i = vam->input;
11096   vl_api_classify_add_del_table_t *mp;
11097
11098   u32 nbuckets = 2;
11099   u32 skip = ~0;
11100   u32 match = ~0;
11101   int is_add = 1;
11102   int del_chain = 0;
11103   u32 table_index = ~0;
11104   u32 next_table_index = ~0;
11105   u32 miss_next_index = ~0;
11106   u32 memory_size = 32 << 20;
11107   u8 *mask = 0;
11108   u32 current_data_flag = 0;
11109   int current_data_offset = 0;
11110   int ret;
11111
11112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11113     {
11114       if (unformat (i, "del"))
11115         is_add = 0;
11116       else if (unformat (i, "del-chain"))
11117         {
11118           is_add = 0;
11119           del_chain = 1;
11120         }
11121       else if (unformat (i, "buckets %d", &nbuckets))
11122         ;
11123       else if (unformat (i, "memory_size %d", &memory_size))
11124         ;
11125       else if (unformat (i, "skip %d", &skip))
11126         ;
11127       else if (unformat (i, "match %d", &match))
11128         ;
11129       else if (unformat (i, "table %d", &table_index))
11130         ;
11131       else if (unformat (i, "mask %U", unformat_classify_mask,
11132                          &mask, &skip, &match))
11133         ;
11134       else if (unformat (i, "next-table %d", &next_table_index))
11135         ;
11136       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11137                          &miss_next_index))
11138         ;
11139       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11140                          &miss_next_index))
11141         ;
11142       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11143                          &miss_next_index))
11144         ;
11145       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11146         ;
11147       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11148         ;
11149       else
11150         break;
11151     }
11152
11153   if (is_add && mask == 0)
11154     {
11155       errmsg ("Mask required");
11156       return -99;
11157     }
11158
11159   if (is_add && skip == ~0)
11160     {
11161       errmsg ("skip count required");
11162       return -99;
11163     }
11164
11165   if (is_add && match == ~0)
11166     {
11167       errmsg ("match count required");
11168       return -99;
11169     }
11170
11171   if (!is_add && table_index == ~0)
11172     {
11173       errmsg ("table index required for delete");
11174       return -99;
11175     }
11176
11177   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11178
11179   mp->is_add = is_add;
11180   mp->del_chain = del_chain;
11181   mp->table_index = ntohl (table_index);
11182   mp->nbuckets = ntohl (nbuckets);
11183   mp->memory_size = ntohl (memory_size);
11184   mp->skip_n_vectors = ntohl (skip);
11185   mp->match_n_vectors = ntohl (match);
11186   mp->next_table_index = ntohl (next_table_index);
11187   mp->miss_next_index = ntohl (miss_next_index);
11188   mp->current_data_flag = ntohl (current_data_flag);
11189   mp->current_data_offset = ntohl (current_data_offset);
11190   clib_memcpy (mp->mask, mask, vec_len (mask));
11191
11192   vec_free (mask);
11193
11194   S (mp);
11195   W (ret);
11196   return ret;
11197 }
11198
11199 #if VPP_API_TEST_BUILTIN == 0
11200 uword
11201 unformat_l4_match (unformat_input_t * input, va_list * args)
11202 {
11203   u8 **matchp = va_arg (*args, u8 **);
11204
11205   u8 *proto_header = 0;
11206   int src_port = 0;
11207   int dst_port = 0;
11208
11209   tcpudp_header_t h;
11210
11211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11212     {
11213       if (unformat (input, "src_port %d", &src_port))
11214         ;
11215       else if (unformat (input, "dst_port %d", &dst_port))
11216         ;
11217       else
11218         return 0;
11219     }
11220
11221   h.src_port = clib_host_to_net_u16 (src_port);
11222   h.dst_port = clib_host_to_net_u16 (dst_port);
11223   vec_validate (proto_header, sizeof (h) - 1);
11224   memcpy (proto_header, &h, sizeof (h));
11225
11226   *matchp = proto_header;
11227
11228   return 1;
11229 }
11230
11231 uword
11232 unformat_ip4_match (unformat_input_t * input, va_list * args)
11233 {
11234   u8 **matchp = va_arg (*args, u8 **);
11235   u8 *match = 0;
11236   ip4_header_t *ip;
11237   int version = 0;
11238   u32 version_val;
11239   int hdr_length = 0;
11240   u32 hdr_length_val;
11241   int src = 0, dst = 0;
11242   ip4_address_t src_val, dst_val;
11243   int proto = 0;
11244   u32 proto_val;
11245   int tos = 0;
11246   u32 tos_val;
11247   int length = 0;
11248   u32 length_val;
11249   int fragment_id = 0;
11250   u32 fragment_id_val;
11251   int ttl = 0;
11252   int ttl_val;
11253   int checksum = 0;
11254   u32 checksum_val;
11255
11256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11257     {
11258       if (unformat (input, "version %d", &version_val))
11259         version = 1;
11260       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11261         hdr_length = 1;
11262       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11263         src = 1;
11264       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11265         dst = 1;
11266       else if (unformat (input, "proto %d", &proto_val))
11267         proto = 1;
11268       else if (unformat (input, "tos %d", &tos_val))
11269         tos = 1;
11270       else if (unformat (input, "length %d", &length_val))
11271         length = 1;
11272       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11273         fragment_id = 1;
11274       else if (unformat (input, "ttl %d", &ttl_val))
11275         ttl = 1;
11276       else if (unformat (input, "checksum %d", &checksum_val))
11277         checksum = 1;
11278       else
11279         break;
11280     }
11281
11282   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11283       + ttl + checksum == 0)
11284     return 0;
11285
11286   /*
11287    * Aligned because we use the real comparison functions
11288    */
11289   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11290
11291   ip = (ip4_header_t *) match;
11292
11293   /* These are realistically matched in practice */
11294   if (src)
11295     ip->src_address.as_u32 = src_val.as_u32;
11296
11297   if (dst)
11298     ip->dst_address.as_u32 = dst_val.as_u32;
11299
11300   if (proto)
11301     ip->protocol = proto_val;
11302
11303
11304   /* These are not, but they're included for completeness */
11305   if (version)
11306     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11307
11308   if (hdr_length)
11309     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11310
11311   if (tos)
11312     ip->tos = tos_val;
11313
11314   if (length)
11315     ip->length = clib_host_to_net_u16 (length_val);
11316
11317   if (ttl)
11318     ip->ttl = ttl_val;
11319
11320   if (checksum)
11321     ip->checksum = clib_host_to_net_u16 (checksum_val);
11322
11323   *matchp = match;
11324   return 1;
11325 }
11326
11327 uword
11328 unformat_ip6_match (unformat_input_t * input, va_list * args)
11329 {
11330   u8 **matchp = va_arg (*args, u8 **);
11331   u8 *match = 0;
11332   ip6_header_t *ip;
11333   int version = 0;
11334   u32 version_val;
11335   u8 traffic_class = 0;
11336   u32 traffic_class_val = 0;
11337   u8 flow_label = 0;
11338   u8 flow_label_val;
11339   int src = 0, dst = 0;
11340   ip6_address_t src_val, dst_val;
11341   int proto = 0;
11342   u32 proto_val;
11343   int payload_length = 0;
11344   u32 payload_length_val;
11345   int hop_limit = 0;
11346   int hop_limit_val;
11347   u32 ip_version_traffic_class_and_flow_label;
11348
11349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (input, "version %d", &version_val))
11352         version = 1;
11353       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11354         traffic_class = 1;
11355       else if (unformat (input, "flow_label %d", &flow_label_val))
11356         flow_label = 1;
11357       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11358         src = 1;
11359       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11360         dst = 1;
11361       else if (unformat (input, "proto %d", &proto_val))
11362         proto = 1;
11363       else if (unformat (input, "payload_length %d", &payload_length_val))
11364         payload_length = 1;
11365       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11366         hop_limit = 1;
11367       else
11368         break;
11369     }
11370
11371   if (version + traffic_class + flow_label + src + dst + proto +
11372       payload_length + hop_limit == 0)
11373     return 0;
11374
11375   /*
11376    * Aligned because we use the real comparison functions
11377    */
11378   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11379
11380   ip = (ip6_header_t *) match;
11381
11382   if (src)
11383     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11384
11385   if (dst)
11386     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11387
11388   if (proto)
11389     ip->protocol = proto_val;
11390
11391   ip_version_traffic_class_and_flow_label = 0;
11392
11393   if (version)
11394     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11395
11396   if (traffic_class)
11397     ip_version_traffic_class_and_flow_label |=
11398       (traffic_class_val & 0xFF) << 20;
11399
11400   if (flow_label)
11401     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11402
11403   ip->ip_version_traffic_class_and_flow_label =
11404     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11405
11406   if (payload_length)
11407     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11408
11409   if (hop_limit)
11410     ip->hop_limit = hop_limit_val;
11411
11412   *matchp = match;
11413   return 1;
11414 }
11415
11416 uword
11417 unformat_l3_match (unformat_input_t * input, va_list * args)
11418 {
11419   u8 **matchp = va_arg (*args, u8 **);
11420
11421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11422     {
11423       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11424         return 1;
11425       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11426         return 1;
11427       else
11428         break;
11429     }
11430   return 0;
11431 }
11432
11433 uword
11434 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11435 {
11436   u8 *tagp = va_arg (*args, u8 *);
11437   u32 tag;
11438
11439   if (unformat (input, "%d", &tag))
11440     {
11441       tagp[0] = (tag >> 8) & 0x0F;
11442       tagp[1] = tag & 0xFF;
11443       return 1;
11444     }
11445
11446   return 0;
11447 }
11448
11449 uword
11450 unformat_l2_match (unformat_input_t * input, va_list * args)
11451 {
11452   u8 **matchp = va_arg (*args, u8 **);
11453   u8 *match = 0;
11454   u8 src = 0;
11455   u8 src_val[6];
11456   u8 dst = 0;
11457   u8 dst_val[6];
11458   u8 proto = 0;
11459   u16 proto_val;
11460   u8 tag1 = 0;
11461   u8 tag1_val[2];
11462   u8 tag2 = 0;
11463   u8 tag2_val[2];
11464   int len = 14;
11465   u8 ignore_tag1 = 0;
11466   u8 ignore_tag2 = 0;
11467   u8 cos1 = 0;
11468   u8 cos2 = 0;
11469   u32 cos1_val = 0;
11470   u32 cos2_val = 0;
11471
11472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11473     {
11474       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11475         src = 1;
11476       else
11477         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11478         dst = 1;
11479       else if (unformat (input, "proto %U",
11480                          unformat_ethernet_type_host_byte_order, &proto_val))
11481         proto = 1;
11482       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11483         tag1 = 1;
11484       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11485         tag2 = 1;
11486       else if (unformat (input, "ignore-tag1"))
11487         ignore_tag1 = 1;
11488       else if (unformat (input, "ignore-tag2"))
11489         ignore_tag2 = 1;
11490       else if (unformat (input, "cos1 %d", &cos1_val))
11491         cos1 = 1;
11492       else if (unformat (input, "cos2 %d", &cos2_val))
11493         cos2 = 1;
11494       else
11495         break;
11496     }
11497   if ((src + dst + proto + tag1 + tag2 +
11498        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11499     return 0;
11500
11501   if (tag1 || ignore_tag1 || cos1)
11502     len = 18;
11503   if (tag2 || ignore_tag2 || cos2)
11504     len = 22;
11505
11506   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11507
11508   if (dst)
11509     clib_memcpy (match, dst_val, 6);
11510
11511   if (src)
11512     clib_memcpy (match + 6, src_val, 6);
11513
11514   if (tag2)
11515     {
11516       /* inner vlan tag */
11517       match[19] = tag2_val[1];
11518       match[18] = tag2_val[0];
11519       if (cos2)
11520         match[18] |= (cos2_val & 0x7) << 5;
11521       if (proto)
11522         {
11523           match[21] = proto_val & 0xff;
11524           match[20] = proto_val >> 8;
11525         }
11526       if (tag1)
11527         {
11528           match[15] = tag1_val[1];
11529           match[14] = tag1_val[0];
11530         }
11531       if (cos1)
11532         match[14] |= (cos1_val & 0x7) << 5;
11533       *matchp = match;
11534       return 1;
11535     }
11536   if (tag1)
11537     {
11538       match[15] = tag1_val[1];
11539       match[14] = tag1_val[0];
11540       if (proto)
11541         {
11542           match[17] = proto_val & 0xff;
11543           match[16] = proto_val >> 8;
11544         }
11545       if (cos1)
11546         match[14] |= (cos1_val & 0x7) << 5;
11547
11548       *matchp = match;
11549       return 1;
11550     }
11551   if (cos2)
11552     match[18] |= (cos2_val & 0x7) << 5;
11553   if (cos1)
11554     match[14] |= (cos1_val & 0x7) << 5;
11555   if (proto)
11556     {
11557       match[13] = proto_val & 0xff;
11558       match[12] = proto_val >> 8;
11559     }
11560
11561   *matchp = match;
11562   return 1;
11563 }
11564 #endif
11565
11566 uword
11567 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11568 {
11569   u8 **matchp = va_arg (*args, u8 **);
11570   u32 skip_n_vectors = va_arg (*args, u32);
11571   u32 match_n_vectors = va_arg (*args, u32);
11572
11573   u8 *match = 0;
11574   u8 *l2 = 0;
11575   u8 *l3 = 0;
11576   u8 *l4 = 0;
11577
11578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (input, "hex %U", unformat_hex_string, &match))
11581         ;
11582       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11583         ;
11584       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11585         ;
11586       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11587         ;
11588       else
11589         break;
11590     }
11591
11592   if (l4 && !l3)
11593     {
11594       vec_free (match);
11595       vec_free (l2);
11596       vec_free (l4);
11597       return 0;
11598     }
11599
11600   if (match || l2 || l3 || l4)
11601     {
11602       if (l2 || l3 || l4)
11603         {
11604           /* "Win a free Ethernet header in every packet" */
11605           if (l2 == 0)
11606             vec_validate_aligned (l2, 13, sizeof (u32x4));
11607           match = l2;
11608           if (vec_len (l3))
11609             {
11610               vec_append_aligned (match, l3, sizeof (u32x4));
11611               vec_free (l3);
11612             }
11613           if (vec_len (l4))
11614             {
11615               vec_append_aligned (match, l4, sizeof (u32x4));
11616               vec_free (l4);
11617             }
11618         }
11619
11620       /* Make sure the vector is big enough even if key is all 0's */
11621       vec_validate_aligned
11622         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11623          sizeof (u32x4));
11624
11625       /* Set size, include skipped vectors */
11626       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11627
11628       *matchp = match;
11629
11630       return 1;
11631     }
11632
11633   return 0;
11634 }
11635
11636 static int
11637 api_classify_add_del_session (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   vl_api_classify_add_del_session_t *mp;
11641   int is_add = 1;
11642   u32 table_index = ~0;
11643   u32 hit_next_index = ~0;
11644   u32 opaque_index = ~0;
11645   u8 *match = 0;
11646   i32 advance = 0;
11647   u32 skip_n_vectors = 0;
11648   u32 match_n_vectors = 0;
11649   u32 action = 0;
11650   u32 metadata = 0;
11651   int ret;
11652
11653   /*
11654    * Warning: you have to supply skip_n and match_n
11655    * because the API client cant simply look at the classify
11656    * table object.
11657    */
11658
11659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11660     {
11661       if (unformat (i, "del"))
11662         is_add = 0;
11663       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11664                          &hit_next_index))
11665         ;
11666       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11667                          &hit_next_index))
11668         ;
11669       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11670                          &hit_next_index))
11671         ;
11672       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11673         ;
11674       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11675         ;
11676       else if (unformat (i, "opaque-index %d", &opaque_index))
11677         ;
11678       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11679         ;
11680       else if (unformat (i, "match_n %d", &match_n_vectors))
11681         ;
11682       else if (unformat (i, "match %U", api_unformat_classify_match,
11683                          &match, skip_n_vectors, match_n_vectors))
11684         ;
11685       else if (unformat (i, "advance %d", &advance))
11686         ;
11687       else if (unformat (i, "table-index %d", &table_index))
11688         ;
11689       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11690         action = 1;
11691       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11692         action = 2;
11693       else if (unformat (i, "action %d", &action))
11694         ;
11695       else if (unformat (i, "metadata %d", &metadata))
11696         ;
11697       else
11698         break;
11699     }
11700
11701   if (table_index == ~0)
11702     {
11703       errmsg ("Table index required");
11704       return -99;
11705     }
11706
11707   if (is_add && match == 0)
11708     {
11709       errmsg ("Match value required");
11710       return -99;
11711     }
11712
11713   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11714
11715   mp->is_add = is_add;
11716   mp->table_index = ntohl (table_index);
11717   mp->hit_next_index = ntohl (hit_next_index);
11718   mp->opaque_index = ntohl (opaque_index);
11719   mp->advance = ntohl (advance);
11720   mp->action = action;
11721   mp->metadata = ntohl (metadata);
11722   clib_memcpy (mp->match, match, vec_len (match));
11723   vec_free (match);
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_classify_set_interface_ip_table (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_classify_set_interface_ip_table_t *mp;
11735   u32 sw_if_index;
11736   int sw_if_index_set;
11737   u32 table_index = ~0;
11738   u8 is_ipv6 = 0;
11739   int ret;
11740
11741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11744         sw_if_index_set = 1;
11745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11746         sw_if_index_set = 1;
11747       else if (unformat (i, "table %d", &table_index))
11748         ;
11749       else
11750         {
11751           clib_warning ("parse error '%U'", format_unformat_error, i);
11752           return -99;
11753         }
11754     }
11755
11756   if (sw_if_index_set == 0)
11757     {
11758       errmsg ("missing interface name or sw_if_index");
11759       return -99;
11760     }
11761
11762
11763   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11764
11765   mp->sw_if_index = ntohl (sw_if_index);
11766   mp->table_index = ntohl (table_index);
11767   mp->is_ipv6 = is_ipv6;
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static int
11775 api_classify_set_interface_l2_tables (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_classify_set_interface_l2_tables_t *mp;
11779   u32 sw_if_index;
11780   int sw_if_index_set;
11781   u32 ip4_table_index = ~0;
11782   u32 ip6_table_index = ~0;
11783   u32 other_table_index = ~0;
11784   u32 is_input = 1;
11785   int ret;
11786
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11790         sw_if_index_set = 1;
11791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11792         sw_if_index_set = 1;
11793       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11794         ;
11795       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11796         ;
11797       else if (unformat (i, "other-table %d", &other_table_index))
11798         ;
11799       else if (unformat (i, "is-input %d", &is_input))
11800         ;
11801       else
11802         {
11803           clib_warning ("parse error '%U'", format_unformat_error, i);
11804           return -99;
11805         }
11806     }
11807
11808   if (sw_if_index_set == 0)
11809     {
11810       errmsg ("missing interface name or sw_if_index");
11811       return -99;
11812     }
11813
11814
11815   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11816
11817   mp->sw_if_index = ntohl (sw_if_index);
11818   mp->ip4_table_index = ntohl (ip4_table_index);
11819   mp->ip6_table_index = ntohl (ip6_table_index);
11820   mp->other_table_index = ntohl (other_table_index);
11821   mp->is_input = (u8) is_input;
11822
11823   S (mp);
11824   W (ret);
11825   return ret;
11826 }
11827
11828 static int
11829 api_set_ipfix_exporter (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_set_ipfix_exporter_t *mp;
11833   ip4_address_t collector_address;
11834   u8 collector_address_set = 0;
11835   u32 collector_port = ~0;
11836   ip4_address_t src_address;
11837   u8 src_address_set = 0;
11838   u32 vrf_id = ~0;
11839   u32 path_mtu = ~0;
11840   u32 template_interval = ~0;
11841   u8 udp_checksum = 0;
11842   int ret;
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "collector_address %U", unformat_ip4_address,
11847                     &collector_address))
11848         collector_address_set = 1;
11849       else if (unformat (i, "collector_port %d", &collector_port))
11850         ;
11851       else if (unformat (i, "src_address %U", unformat_ip4_address,
11852                          &src_address))
11853         src_address_set = 1;
11854       else if (unformat (i, "vrf_id %d", &vrf_id))
11855         ;
11856       else if (unformat (i, "path_mtu %d", &path_mtu))
11857         ;
11858       else if (unformat (i, "template_interval %d", &template_interval))
11859         ;
11860       else if (unformat (i, "udp_checksum"))
11861         udp_checksum = 1;
11862       else
11863         break;
11864     }
11865
11866   if (collector_address_set == 0)
11867     {
11868       errmsg ("collector_address required");
11869       return -99;
11870     }
11871
11872   if (src_address_set == 0)
11873     {
11874       errmsg ("src_address required");
11875       return -99;
11876     }
11877
11878   M (SET_IPFIX_EXPORTER, mp);
11879
11880   memcpy (mp->collector_address, collector_address.data,
11881           sizeof (collector_address.data));
11882   mp->collector_port = htons ((u16) collector_port);
11883   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11884   mp->vrf_id = htonl (vrf_id);
11885   mp->path_mtu = htonl (path_mtu);
11886   mp->template_interval = htonl (template_interval);
11887   mp->udp_checksum = udp_checksum;
11888
11889   S (mp);
11890   W (ret);
11891   return ret;
11892 }
11893
11894 static int
11895 api_set_ipfix_classify_stream (vat_main_t * vam)
11896 {
11897   unformat_input_t *i = vam->input;
11898   vl_api_set_ipfix_classify_stream_t *mp;
11899   u32 domain_id = 0;
11900   u32 src_port = UDP_DST_PORT_ipfix;
11901   int ret;
11902
11903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11904     {
11905       if (unformat (i, "domain %d", &domain_id))
11906         ;
11907       else if (unformat (i, "src_port %d", &src_port))
11908         ;
11909       else
11910         {
11911           errmsg ("unknown input `%U'", format_unformat_error, i);
11912           return -99;
11913         }
11914     }
11915
11916   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11917
11918   mp->domain_id = htonl (domain_id);
11919   mp->src_port = htons ((u16) src_port);
11920
11921   S (mp);
11922   W (ret);
11923   return ret;
11924 }
11925
11926 static int
11927 api_ipfix_classify_table_add_del (vat_main_t * vam)
11928 {
11929   unformat_input_t *i = vam->input;
11930   vl_api_ipfix_classify_table_add_del_t *mp;
11931   int is_add = -1;
11932   u32 classify_table_index = ~0;
11933   u8 ip_version = 0;
11934   u8 transport_protocol = 255;
11935   int ret;
11936
11937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11938     {
11939       if (unformat (i, "add"))
11940         is_add = 1;
11941       else if (unformat (i, "del"))
11942         is_add = 0;
11943       else if (unformat (i, "table %d", &classify_table_index))
11944         ;
11945       else if (unformat (i, "ip4"))
11946         ip_version = 4;
11947       else if (unformat (i, "ip6"))
11948         ip_version = 6;
11949       else if (unformat (i, "tcp"))
11950         transport_protocol = 6;
11951       else if (unformat (i, "udp"))
11952         transport_protocol = 17;
11953       else
11954         {
11955           errmsg ("unknown input `%U'", format_unformat_error, i);
11956           return -99;
11957         }
11958     }
11959
11960   if (is_add == -1)
11961     {
11962       errmsg ("expecting: add|del");
11963       return -99;
11964     }
11965   if (classify_table_index == ~0)
11966     {
11967       errmsg ("classifier table not specified");
11968       return -99;
11969     }
11970   if (ip_version == 0)
11971     {
11972       errmsg ("IP version not specified");
11973       return -99;
11974     }
11975
11976   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11977
11978   mp->is_add = is_add;
11979   mp->table_id = htonl (classify_table_index);
11980   mp->ip_version = ip_version;
11981   mp->transport_protocol = transport_protocol;
11982
11983   S (mp);
11984   W (ret);
11985   return ret;
11986 }
11987
11988 static int
11989 api_get_node_index (vat_main_t * vam)
11990 {
11991   unformat_input_t *i = vam->input;
11992   vl_api_get_node_index_t *mp;
11993   u8 *name = 0;
11994   int ret;
11995
11996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (i, "node %s", &name))
11999         ;
12000       else
12001         break;
12002     }
12003   if (name == 0)
12004     {
12005       errmsg ("node name required");
12006       return -99;
12007     }
12008   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12009     {
12010       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12011       return -99;
12012     }
12013
12014   M (GET_NODE_INDEX, mp);
12015   clib_memcpy (mp->node_name, name, vec_len (name));
12016   vec_free (name);
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static int
12024 api_get_next_index (vat_main_t * vam)
12025 {
12026   unformat_input_t *i = vam->input;
12027   vl_api_get_next_index_t *mp;
12028   u8 *node_name = 0, *next_node_name = 0;
12029   int ret;
12030
12031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (i, "node-name %s", &node_name))
12034         ;
12035       else if (unformat (i, "next-node-name %s", &next_node_name))
12036         break;
12037     }
12038
12039   if (node_name == 0)
12040     {
12041       errmsg ("node name required");
12042       return -99;
12043     }
12044   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12045     {
12046       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12047       return -99;
12048     }
12049
12050   if (next_node_name == 0)
12051     {
12052       errmsg ("next node name required");
12053       return -99;
12054     }
12055   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12056     {
12057       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12058       return -99;
12059     }
12060
12061   M (GET_NEXT_INDEX, mp);
12062   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12063   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12064   vec_free (node_name);
12065   vec_free (next_node_name);
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 static int
12073 api_add_node_next (vat_main_t * vam)
12074 {
12075   unformat_input_t *i = vam->input;
12076   vl_api_add_node_next_t *mp;
12077   u8 *name = 0;
12078   u8 *next = 0;
12079   int ret;
12080
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "node %s", &name))
12084         ;
12085       else if (unformat (i, "next %s", &next))
12086         ;
12087       else
12088         break;
12089     }
12090   if (name == 0)
12091     {
12092       errmsg ("node name required");
12093       return -99;
12094     }
12095   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12096     {
12097       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12098       return -99;
12099     }
12100   if (next == 0)
12101     {
12102       errmsg ("next node required");
12103       return -99;
12104     }
12105   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12106     {
12107       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12108       return -99;
12109     }
12110
12111   M (ADD_NODE_NEXT, mp);
12112   clib_memcpy (mp->node_name, name, vec_len (name));
12113   clib_memcpy (mp->next_name, next, vec_len (next));
12114   vec_free (name);
12115   vec_free (next);
12116
12117   S (mp);
12118   W (ret);
12119   return ret;
12120 }
12121
12122 static int
12123 api_l2tpv3_create_tunnel (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   ip6_address_t client_address, our_address;
12127   int client_address_set = 0;
12128   int our_address_set = 0;
12129   u32 local_session_id = 0;
12130   u32 remote_session_id = 0;
12131   u64 local_cookie = 0;
12132   u64 remote_cookie = 0;
12133   u8 l2_sublayer_present = 0;
12134   vl_api_l2tpv3_create_tunnel_t *mp;
12135   int ret;
12136
12137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (i, "client_address %U", unformat_ip6_address,
12140                     &client_address))
12141         client_address_set = 1;
12142       else if (unformat (i, "our_address %U", unformat_ip6_address,
12143                          &our_address))
12144         our_address_set = 1;
12145       else if (unformat (i, "local_session_id %d", &local_session_id))
12146         ;
12147       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12148         ;
12149       else if (unformat (i, "local_cookie %lld", &local_cookie))
12150         ;
12151       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12152         ;
12153       else if (unformat (i, "l2-sublayer-present"))
12154         l2_sublayer_present = 1;
12155       else
12156         break;
12157     }
12158
12159   if (client_address_set == 0)
12160     {
12161       errmsg ("client_address required");
12162       return -99;
12163     }
12164
12165   if (our_address_set == 0)
12166     {
12167       errmsg ("our_address required");
12168       return -99;
12169     }
12170
12171   M (L2TPV3_CREATE_TUNNEL, mp);
12172
12173   clib_memcpy (mp->client_address, client_address.as_u8,
12174                sizeof (mp->client_address));
12175
12176   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12177
12178   mp->local_session_id = ntohl (local_session_id);
12179   mp->remote_session_id = ntohl (remote_session_id);
12180   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12181   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12182   mp->l2_sublayer_present = l2_sublayer_present;
12183   mp->is_ipv6 = 1;
12184
12185   S (mp);
12186   W (ret);
12187   return ret;
12188 }
12189
12190 static int
12191 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12192 {
12193   unformat_input_t *i = vam->input;
12194   u32 sw_if_index;
12195   u8 sw_if_index_set = 0;
12196   u64 new_local_cookie = 0;
12197   u64 new_remote_cookie = 0;
12198   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12199   int ret;
12200
12201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12202     {
12203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12204         sw_if_index_set = 1;
12205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12206         sw_if_index_set = 1;
12207       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12208         ;
12209       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12210         ;
12211       else
12212         break;
12213     }
12214
12215   if (sw_if_index_set == 0)
12216     {
12217       errmsg ("missing interface name or sw_if_index");
12218       return -99;
12219     }
12220
12221   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12222
12223   mp->sw_if_index = ntohl (sw_if_index);
12224   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12225   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12226
12227   S (mp);
12228   W (ret);
12229   return ret;
12230 }
12231
12232 static int
12233 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12234 {
12235   unformat_input_t *i = vam->input;
12236   vl_api_l2tpv3_interface_enable_disable_t *mp;
12237   u32 sw_if_index;
12238   u8 sw_if_index_set = 0;
12239   u8 enable_disable = 1;
12240   int ret;
12241
12242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12243     {
12244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12245         sw_if_index_set = 1;
12246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12247         sw_if_index_set = 1;
12248       else if (unformat (i, "enable"))
12249         enable_disable = 1;
12250       else if (unformat (i, "disable"))
12251         enable_disable = 0;
12252       else
12253         break;
12254     }
12255
12256   if (sw_if_index_set == 0)
12257     {
12258       errmsg ("missing interface name or sw_if_index");
12259       return -99;
12260     }
12261
12262   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12263
12264   mp->sw_if_index = ntohl (sw_if_index);
12265   mp->enable_disable = enable_disable;
12266
12267   S (mp);
12268   W (ret);
12269   return ret;
12270 }
12271
12272 static int
12273 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12274 {
12275   unformat_input_t *i = vam->input;
12276   vl_api_l2tpv3_set_lookup_key_t *mp;
12277   u8 key = ~0;
12278   int ret;
12279
12280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12281     {
12282       if (unformat (i, "lookup_v6_src"))
12283         key = L2T_LOOKUP_SRC_ADDRESS;
12284       else if (unformat (i, "lookup_v6_dst"))
12285         key = L2T_LOOKUP_DST_ADDRESS;
12286       else if (unformat (i, "lookup_session_id"))
12287         key = L2T_LOOKUP_SESSION_ID;
12288       else
12289         break;
12290     }
12291
12292   if (key == (u8) ~ 0)
12293     {
12294       errmsg ("l2tp session lookup key unset");
12295       return -99;
12296     }
12297
12298   M (L2TPV3_SET_LOOKUP_KEY, mp);
12299
12300   mp->key = key;
12301
12302   S (mp);
12303   W (ret);
12304   return ret;
12305 }
12306
12307 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12308   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12309 {
12310   vat_main_t *vam = &vat_main;
12311
12312   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12313          format_ip6_address, mp->our_address,
12314          format_ip6_address, mp->client_address,
12315          clib_net_to_host_u32 (mp->sw_if_index));
12316
12317   print (vam->ofp,
12318          "   local cookies %016llx %016llx remote cookie %016llx",
12319          clib_net_to_host_u64 (mp->local_cookie[0]),
12320          clib_net_to_host_u64 (mp->local_cookie[1]),
12321          clib_net_to_host_u64 (mp->remote_cookie));
12322
12323   print (vam->ofp, "   local session-id %d remote session-id %d",
12324          clib_net_to_host_u32 (mp->local_session_id),
12325          clib_net_to_host_u32 (mp->remote_session_id));
12326
12327   print (vam->ofp, "   l2 specific sublayer %s\n",
12328          mp->l2_sublayer_present ? "preset" : "absent");
12329
12330 }
12331
12332 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12333   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12334 {
12335   vat_main_t *vam = &vat_main;
12336   vat_json_node_t *node = NULL;
12337   struct in6_addr addr;
12338
12339   if (VAT_JSON_ARRAY != vam->json_tree.type)
12340     {
12341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12342       vat_json_init_array (&vam->json_tree);
12343     }
12344   node = vat_json_array_add (&vam->json_tree);
12345
12346   vat_json_init_object (node);
12347
12348   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12349   vat_json_object_add_ip6 (node, "our_address", addr);
12350   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12351   vat_json_object_add_ip6 (node, "client_address", addr);
12352
12353   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12354   vat_json_init_array (lc);
12355   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12356   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12357   vat_json_object_add_uint (node, "remote_cookie",
12358                             clib_net_to_host_u64 (mp->remote_cookie));
12359
12360   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12361   vat_json_object_add_uint (node, "local_session_id",
12362                             clib_net_to_host_u32 (mp->local_session_id));
12363   vat_json_object_add_uint (node, "remote_session_id",
12364                             clib_net_to_host_u32 (mp->remote_session_id));
12365   vat_json_object_add_string_copy (node, "l2_sublayer",
12366                                    mp->l2_sublayer_present ? (u8 *) "present"
12367                                    : (u8 *) "absent");
12368 }
12369
12370 static int
12371 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12372 {
12373   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12374   vl_api_control_ping_t *mp_ping;
12375   int ret;
12376
12377   /* Get list of l2tpv3-tunnel interfaces */
12378   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12379   S (mp);
12380
12381   /* Use a control ping for synchronization */
12382   MPING (CONTROL_PING, mp_ping);
12383   S (mp_ping);
12384
12385   W (ret);
12386   return ret;
12387 }
12388
12389
12390 static void vl_api_sw_interface_tap_details_t_handler
12391   (vl_api_sw_interface_tap_details_t * mp)
12392 {
12393   vat_main_t *vam = &vat_main;
12394
12395   print (vam->ofp, "%-16s %d",
12396          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12397 }
12398
12399 static void vl_api_sw_interface_tap_details_t_handler_json
12400   (vl_api_sw_interface_tap_details_t * mp)
12401 {
12402   vat_main_t *vam = &vat_main;
12403   vat_json_node_t *node = NULL;
12404
12405   if (VAT_JSON_ARRAY != vam->json_tree.type)
12406     {
12407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12408       vat_json_init_array (&vam->json_tree);
12409     }
12410   node = vat_json_array_add (&vam->json_tree);
12411
12412   vat_json_init_object (node);
12413   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12414   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12415 }
12416
12417 static int
12418 api_sw_interface_tap_dump (vat_main_t * vam)
12419 {
12420   vl_api_sw_interface_tap_dump_t *mp;
12421   vl_api_control_ping_t *mp_ping;
12422   int ret;
12423
12424   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12425   /* Get list of tap interfaces */
12426   M (SW_INTERFACE_TAP_DUMP, mp);
12427   S (mp);
12428
12429   /* Use a control ping for synchronization */
12430   MPING (CONTROL_PING, mp_ping);
12431   S (mp_ping);
12432
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static void vl_api_sw_interface_tap_v2_details_t_handler
12438   (vl_api_sw_interface_tap_v2_details_t * mp)
12439 {
12440   vat_main_t *vam = &vat_main;
12441
12442   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12443                     mp->host_ip4_prefix_len);
12444   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12445                     mp->host_ip6_prefix_len);
12446
12447   print (vam->ofp,
12448          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12449          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12450          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12451          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12452          mp->host_bridge, ip4, ip6);
12453
12454   vec_free (ip4);
12455   vec_free (ip6);
12456 }
12457
12458 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12459   (vl_api_sw_interface_tap_v2_details_t * mp)
12460 {
12461   vat_main_t *vam = &vat_main;
12462   vat_json_node_t *node = NULL;
12463
12464   if (VAT_JSON_ARRAY != vam->json_tree.type)
12465     {
12466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12467       vat_json_init_array (&vam->json_tree);
12468     }
12469   node = vat_json_array_add (&vam->json_tree);
12470
12471   vat_json_init_object (node);
12472   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12473   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12474   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12475   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12476   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12477   vat_json_object_add_string_copy (node, "host_mac_addr",
12478                                    format (0, "%U", format_ethernet_address,
12479                                            &mp->host_mac_addr));
12480   vat_json_object_add_string_copy (node, "host_namespace",
12481                                    mp->host_namespace);
12482   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12483   vat_json_object_add_string_copy (node, "host_ip4_addr",
12484                                    format (0, "%U/%d", format_ip4_address,
12485                                            mp->host_ip4_addr,
12486                                            mp->host_ip4_prefix_len));
12487   vat_json_object_add_string_copy (node, "host_ip6_addr",
12488                                    format (0, "%U/%d", format_ip6_address,
12489                                            mp->host_ip6_addr,
12490                                            mp->host_ip6_prefix_len));
12491
12492 }
12493
12494 static int
12495 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12496 {
12497   vl_api_sw_interface_tap_v2_dump_t *mp;
12498   vl_api_control_ping_t *mp_ping;
12499   int ret;
12500
12501   print (vam->ofp,
12502          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12503          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12504          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12505          "host_ip6_addr");
12506
12507   /* Get list of tap interfaces */
12508   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12509   S (mp);
12510
12511   /* Use a control ping for synchronization */
12512   MPING (CONTROL_PING, mp_ping);
12513   S (mp_ping);
12514
12515   W (ret);
12516   return ret;
12517 }
12518
12519 static uword unformat_vxlan_decap_next
12520   (unformat_input_t * input, va_list * args)
12521 {
12522   u32 *result = va_arg (*args, u32 *);
12523   u32 tmp;
12524
12525   if (unformat (input, "l2"))
12526     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12527   else if (unformat (input, "%d", &tmp))
12528     *result = tmp;
12529   else
12530     return 0;
12531   return 1;
12532 }
12533
12534 static int
12535 api_vxlan_add_del_tunnel (vat_main_t * vam)
12536 {
12537   unformat_input_t *line_input = vam->input;
12538   vl_api_vxlan_add_del_tunnel_t *mp;
12539   ip46_address_t src, dst;
12540   u8 is_add = 1;
12541   u8 ipv4_set = 0, ipv6_set = 0;
12542   u8 src_set = 0;
12543   u8 dst_set = 0;
12544   u8 grp_set = 0;
12545   u32 mcast_sw_if_index = ~0;
12546   u32 encap_vrf_id = 0;
12547   u32 decap_next_index = ~0;
12548   u32 vni = 0;
12549   int ret;
12550
12551   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12552   memset (&src, 0, sizeof src);
12553   memset (&dst, 0, sizeof dst);
12554
12555   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12556     {
12557       if (unformat (line_input, "del"))
12558         is_add = 0;
12559       else
12560         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12561         {
12562           ipv4_set = 1;
12563           src_set = 1;
12564         }
12565       else
12566         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12567         {
12568           ipv4_set = 1;
12569           dst_set = 1;
12570         }
12571       else
12572         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12573         {
12574           ipv6_set = 1;
12575           src_set = 1;
12576         }
12577       else
12578         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12579         {
12580           ipv6_set = 1;
12581           dst_set = 1;
12582         }
12583       else if (unformat (line_input, "group %U %U",
12584                          unformat_ip4_address, &dst.ip4,
12585                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12586         {
12587           grp_set = dst_set = 1;
12588           ipv4_set = 1;
12589         }
12590       else if (unformat (line_input, "group %U",
12591                          unformat_ip4_address, &dst.ip4))
12592         {
12593           grp_set = dst_set = 1;
12594           ipv4_set = 1;
12595         }
12596       else if (unformat (line_input, "group %U %U",
12597                          unformat_ip6_address, &dst.ip6,
12598                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12599         {
12600           grp_set = dst_set = 1;
12601           ipv6_set = 1;
12602         }
12603       else if (unformat (line_input, "group %U",
12604                          unformat_ip6_address, &dst.ip6))
12605         {
12606           grp_set = dst_set = 1;
12607           ipv6_set = 1;
12608         }
12609       else
12610         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12611         ;
12612       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12613         ;
12614       else if (unformat (line_input, "decap-next %U",
12615                          unformat_vxlan_decap_next, &decap_next_index))
12616         ;
12617       else if (unformat (line_input, "vni %d", &vni))
12618         ;
12619       else
12620         {
12621           errmsg ("parse error '%U'", format_unformat_error, line_input);
12622           return -99;
12623         }
12624     }
12625
12626   if (src_set == 0)
12627     {
12628       errmsg ("tunnel src address not specified");
12629       return -99;
12630     }
12631   if (dst_set == 0)
12632     {
12633       errmsg ("tunnel dst address not specified");
12634       return -99;
12635     }
12636
12637   if (grp_set && !ip46_address_is_multicast (&dst))
12638     {
12639       errmsg ("tunnel group address not multicast");
12640       return -99;
12641     }
12642   if (grp_set && mcast_sw_if_index == ~0)
12643     {
12644       errmsg ("tunnel nonexistent multicast device");
12645       return -99;
12646     }
12647   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12648     {
12649       errmsg ("tunnel dst address must be unicast");
12650       return -99;
12651     }
12652
12653
12654   if (ipv4_set && ipv6_set)
12655     {
12656       errmsg ("both IPv4 and IPv6 addresses specified");
12657       return -99;
12658     }
12659
12660   if ((vni == 0) || (vni >> 24))
12661     {
12662       errmsg ("vni not specified or out of range");
12663       return -99;
12664     }
12665
12666   M (VXLAN_ADD_DEL_TUNNEL, mp);
12667
12668   if (ipv6_set)
12669     {
12670       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12671       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12672     }
12673   else
12674     {
12675       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12676       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12677     }
12678   mp->encap_vrf_id = ntohl (encap_vrf_id);
12679   mp->decap_next_index = ntohl (decap_next_index);
12680   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12681   mp->vni = ntohl (vni);
12682   mp->is_add = is_add;
12683   mp->is_ipv6 = ipv6_set;
12684
12685   S (mp);
12686   W (ret);
12687   return ret;
12688 }
12689
12690 static void vl_api_vxlan_tunnel_details_t_handler
12691   (vl_api_vxlan_tunnel_details_t * mp)
12692 {
12693   vat_main_t *vam = &vat_main;
12694   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12695   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12696
12697   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12698          ntohl (mp->sw_if_index),
12699          format_ip46_address, &src, IP46_TYPE_ANY,
12700          format_ip46_address, &dst, IP46_TYPE_ANY,
12701          ntohl (mp->encap_vrf_id),
12702          ntohl (mp->decap_next_index), ntohl (mp->vni),
12703          ntohl (mp->mcast_sw_if_index));
12704 }
12705
12706 static void vl_api_vxlan_tunnel_details_t_handler_json
12707   (vl_api_vxlan_tunnel_details_t * mp)
12708 {
12709   vat_main_t *vam = &vat_main;
12710   vat_json_node_t *node = NULL;
12711
12712   if (VAT_JSON_ARRAY != vam->json_tree.type)
12713     {
12714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12715       vat_json_init_array (&vam->json_tree);
12716     }
12717   node = vat_json_array_add (&vam->json_tree);
12718
12719   vat_json_init_object (node);
12720   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12721   if (mp->is_ipv6)
12722     {
12723       struct in6_addr ip6;
12724
12725       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12726       vat_json_object_add_ip6 (node, "src_address", ip6);
12727       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12728       vat_json_object_add_ip6 (node, "dst_address", ip6);
12729     }
12730   else
12731     {
12732       struct in_addr ip4;
12733
12734       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12735       vat_json_object_add_ip4 (node, "src_address", ip4);
12736       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12737       vat_json_object_add_ip4 (node, "dst_address", ip4);
12738     }
12739   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12740   vat_json_object_add_uint (node, "decap_next_index",
12741                             ntohl (mp->decap_next_index));
12742   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12743   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12744   vat_json_object_add_uint (node, "mcast_sw_if_index",
12745                             ntohl (mp->mcast_sw_if_index));
12746 }
12747
12748 static int
12749 api_vxlan_tunnel_dump (vat_main_t * vam)
12750 {
12751   unformat_input_t *i = vam->input;
12752   vl_api_vxlan_tunnel_dump_t *mp;
12753   vl_api_control_ping_t *mp_ping;
12754   u32 sw_if_index;
12755   u8 sw_if_index_set = 0;
12756   int ret;
12757
12758   /* Parse args required to build the message */
12759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (i, "sw_if_index %d", &sw_if_index))
12762         sw_if_index_set = 1;
12763       else
12764         break;
12765     }
12766
12767   if (sw_if_index_set == 0)
12768     {
12769       sw_if_index = ~0;
12770     }
12771
12772   if (!vam->json_output)
12773     {
12774       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12775              "sw_if_index", "src_address", "dst_address",
12776              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12777     }
12778
12779   /* Get list of vxlan-tunnel interfaces */
12780   M (VXLAN_TUNNEL_DUMP, mp);
12781
12782   mp->sw_if_index = htonl (sw_if_index);
12783
12784   S (mp);
12785
12786   /* Use a control ping for synchronization */
12787   MPING (CONTROL_PING, mp_ping);
12788   S (mp_ping);
12789
12790   W (ret);
12791   return ret;
12792 }
12793
12794 static uword unformat_geneve_decap_next
12795   (unformat_input_t * input, va_list * args)
12796 {
12797   u32 *result = va_arg (*args, u32 *);
12798   u32 tmp;
12799
12800   if (unformat (input, "l2"))
12801     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12802   else if (unformat (input, "%d", &tmp))
12803     *result = tmp;
12804   else
12805     return 0;
12806   return 1;
12807 }
12808
12809 static int
12810 api_geneve_add_del_tunnel (vat_main_t * vam)
12811 {
12812   unformat_input_t *line_input = vam->input;
12813   vl_api_geneve_add_del_tunnel_t *mp;
12814   ip46_address_t src, dst;
12815   u8 is_add = 1;
12816   u8 ipv4_set = 0, ipv6_set = 0;
12817   u8 src_set = 0;
12818   u8 dst_set = 0;
12819   u8 grp_set = 0;
12820   u32 mcast_sw_if_index = ~0;
12821   u32 encap_vrf_id = 0;
12822   u32 decap_next_index = ~0;
12823   u32 vni = 0;
12824   int ret;
12825
12826   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12827   memset (&src, 0, sizeof src);
12828   memset (&dst, 0, sizeof dst);
12829
12830   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12831     {
12832       if (unformat (line_input, "del"))
12833         is_add = 0;
12834       else
12835         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12836         {
12837           ipv4_set = 1;
12838           src_set = 1;
12839         }
12840       else
12841         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12842         {
12843           ipv4_set = 1;
12844           dst_set = 1;
12845         }
12846       else
12847         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12848         {
12849           ipv6_set = 1;
12850           src_set = 1;
12851         }
12852       else
12853         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12854         {
12855           ipv6_set = 1;
12856           dst_set = 1;
12857         }
12858       else if (unformat (line_input, "group %U %U",
12859                          unformat_ip4_address, &dst.ip4,
12860                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12861         {
12862           grp_set = dst_set = 1;
12863           ipv4_set = 1;
12864         }
12865       else if (unformat (line_input, "group %U",
12866                          unformat_ip4_address, &dst.ip4))
12867         {
12868           grp_set = dst_set = 1;
12869           ipv4_set = 1;
12870         }
12871       else if (unformat (line_input, "group %U %U",
12872                          unformat_ip6_address, &dst.ip6,
12873                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12874         {
12875           grp_set = dst_set = 1;
12876           ipv6_set = 1;
12877         }
12878       else if (unformat (line_input, "group %U",
12879                          unformat_ip6_address, &dst.ip6))
12880         {
12881           grp_set = dst_set = 1;
12882           ipv6_set = 1;
12883         }
12884       else
12885         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12886         ;
12887       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12888         ;
12889       else if (unformat (line_input, "decap-next %U",
12890                          unformat_geneve_decap_next, &decap_next_index))
12891         ;
12892       else if (unformat (line_input, "vni %d", &vni))
12893         ;
12894       else
12895         {
12896           errmsg ("parse error '%U'", format_unformat_error, line_input);
12897           return -99;
12898         }
12899     }
12900
12901   if (src_set == 0)
12902     {
12903       errmsg ("tunnel src address not specified");
12904       return -99;
12905     }
12906   if (dst_set == 0)
12907     {
12908       errmsg ("tunnel dst address not specified");
12909       return -99;
12910     }
12911
12912   if (grp_set && !ip46_address_is_multicast (&dst))
12913     {
12914       errmsg ("tunnel group address not multicast");
12915       return -99;
12916     }
12917   if (grp_set && mcast_sw_if_index == ~0)
12918     {
12919       errmsg ("tunnel nonexistent multicast device");
12920       return -99;
12921     }
12922   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12923     {
12924       errmsg ("tunnel dst address must be unicast");
12925       return -99;
12926     }
12927
12928
12929   if (ipv4_set && ipv6_set)
12930     {
12931       errmsg ("both IPv4 and IPv6 addresses specified");
12932       return -99;
12933     }
12934
12935   if ((vni == 0) || (vni >> 24))
12936     {
12937       errmsg ("vni not specified or out of range");
12938       return -99;
12939     }
12940
12941   M (GENEVE_ADD_DEL_TUNNEL, mp);
12942
12943   if (ipv6_set)
12944     {
12945       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12946       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12947     }
12948   else
12949     {
12950       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12951       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12952     }
12953   mp->encap_vrf_id = ntohl (encap_vrf_id);
12954   mp->decap_next_index = ntohl (decap_next_index);
12955   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12956   mp->vni = ntohl (vni);
12957   mp->is_add = is_add;
12958   mp->is_ipv6 = ipv6_set;
12959
12960   S (mp);
12961   W (ret);
12962   return ret;
12963 }
12964
12965 static void vl_api_geneve_tunnel_details_t_handler
12966   (vl_api_geneve_tunnel_details_t * mp)
12967 {
12968   vat_main_t *vam = &vat_main;
12969   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12970   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12971
12972   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12973          ntohl (mp->sw_if_index),
12974          format_ip46_address, &src, IP46_TYPE_ANY,
12975          format_ip46_address, &dst, IP46_TYPE_ANY,
12976          ntohl (mp->encap_vrf_id),
12977          ntohl (mp->decap_next_index), ntohl (mp->vni),
12978          ntohl (mp->mcast_sw_if_index));
12979 }
12980
12981 static void vl_api_geneve_tunnel_details_t_handler_json
12982   (vl_api_geneve_tunnel_details_t * mp)
12983 {
12984   vat_main_t *vam = &vat_main;
12985   vat_json_node_t *node = NULL;
12986
12987   if (VAT_JSON_ARRAY != vam->json_tree.type)
12988     {
12989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12990       vat_json_init_array (&vam->json_tree);
12991     }
12992   node = vat_json_array_add (&vam->json_tree);
12993
12994   vat_json_init_object (node);
12995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12996   if (mp->is_ipv6)
12997     {
12998       struct in6_addr ip6;
12999
13000       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13001       vat_json_object_add_ip6 (node, "src_address", ip6);
13002       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13003       vat_json_object_add_ip6 (node, "dst_address", ip6);
13004     }
13005   else
13006     {
13007       struct in_addr ip4;
13008
13009       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13010       vat_json_object_add_ip4 (node, "src_address", ip4);
13011       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13012       vat_json_object_add_ip4 (node, "dst_address", ip4);
13013     }
13014   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13015   vat_json_object_add_uint (node, "decap_next_index",
13016                             ntohl (mp->decap_next_index));
13017   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13018   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13019   vat_json_object_add_uint (node, "mcast_sw_if_index",
13020                             ntohl (mp->mcast_sw_if_index));
13021 }
13022
13023 static int
13024 api_geneve_tunnel_dump (vat_main_t * vam)
13025 {
13026   unformat_input_t *i = vam->input;
13027   vl_api_geneve_tunnel_dump_t *mp;
13028   vl_api_control_ping_t *mp_ping;
13029   u32 sw_if_index;
13030   u8 sw_if_index_set = 0;
13031   int ret;
13032
13033   /* Parse args required to build the message */
13034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13035     {
13036       if (unformat (i, "sw_if_index %d", &sw_if_index))
13037         sw_if_index_set = 1;
13038       else
13039         break;
13040     }
13041
13042   if (sw_if_index_set == 0)
13043     {
13044       sw_if_index = ~0;
13045     }
13046
13047   if (!vam->json_output)
13048     {
13049       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13050              "sw_if_index", "local_address", "remote_address",
13051              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13052     }
13053
13054   /* Get list of geneve-tunnel interfaces */
13055   M (GENEVE_TUNNEL_DUMP, mp);
13056
13057   mp->sw_if_index = htonl (sw_if_index);
13058
13059   S (mp);
13060
13061   /* Use a control ping for synchronization */
13062   M (CONTROL_PING, mp_ping);
13063   S (mp_ping);
13064
13065   W (ret);
13066   return ret;
13067 }
13068
13069 static int
13070 api_gre_add_del_tunnel (vat_main_t * vam)
13071 {
13072   unformat_input_t *line_input = vam->input;
13073   vl_api_gre_add_del_tunnel_t *mp;
13074   ip4_address_t src4, dst4;
13075   ip6_address_t src6, dst6;
13076   u8 is_add = 1;
13077   u8 ipv4_set = 0;
13078   u8 ipv6_set = 0;
13079   u8 teb = 0;
13080   u8 src_set = 0;
13081   u8 dst_set = 0;
13082   u32 outer_fib_id = 0;
13083   int ret;
13084
13085   memset (&src4, 0, sizeof src4);
13086   memset (&dst4, 0, sizeof dst4);
13087   memset (&src6, 0, sizeof src6);
13088   memset (&dst6, 0, sizeof dst6);
13089
13090   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13091     {
13092       if (unformat (line_input, "del"))
13093         is_add = 0;
13094       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13095         {
13096           src_set = 1;
13097           ipv4_set = 1;
13098         }
13099       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13100         {
13101           dst_set = 1;
13102           ipv4_set = 1;
13103         }
13104       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13105         {
13106           src_set = 1;
13107           ipv6_set = 1;
13108         }
13109       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13110         {
13111           dst_set = 1;
13112           ipv6_set = 1;
13113         }
13114       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13115         ;
13116       else if (unformat (line_input, "teb"))
13117         teb = 1;
13118       else
13119         {
13120           errmsg ("parse error '%U'", format_unformat_error, line_input);
13121           return -99;
13122         }
13123     }
13124
13125   if (src_set == 0)
13126     {
13127       errmsg ("tunnel src address not specified");
13128       return -99;
13129     }
13130   if (dst_set == 0)
13131     {
13132       errmsg ("tunnel dst address not specified");
13133       return -99;
13134     }
13135   if (ipv4_set && ipv6_set)
13136     {
13137       errmsg ("both IPv4 and IPv6 addresses specified");
13138       return -99;
13139     }
13140
13141
13142   M (GRE_ADD_DEL_TUNNEL, mp);
13143
13144   if (ipv4_set)
13145     {
13146       clib_memcpy (&mp->src_address, &src4, 4);
13147       clib_memcpy (&mp->dst_address, &dst4, 4);
13148     }
13149   else
13150     {
13151       clib_memcpy (&mp->src_address, &src6, 16);
13152       clib_memcpy (&mp->dst_address, &dst6, 16);
13153     }
13154   mp->outer_fib_id = ntohl (outer_fib_id);
13155   mp->is_add = is_add;
13156   mp->teb = teb;
13157   mp->is_ipv6 = ipv6_set;
13158
13159   S (mp);
13160   W (ret);
13161   return ret;
13162 }
13163
13164 static void vl_api_gre_tunnel_details_t_handler
13165   (vl_api_gre_tunnel_details_t * mp)
13166 {
13167   vat_main_t *vam = &vat_main;
13168   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13169   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13170
13171   print (vam->ofp, "%11d%24U%24U%6d%14d",
13172          ntohl (mp->sw_if_index),
13173          format_ip46_address, &src, IP46_TYPE_ANY,
13174          format_ip46_address, &dst, IP46_TYPE_ANY,
13175          mp->teb, ntohl (mp->outer_fib_id));
13176 }
13177
13178 static void vl_api_gre_tunnel_details_t_handler_json
13179   (vl_api_gre_tunnel_details_t * mp)
13180 {
13181   vat_main_t *vam = &vat_main;
13182   vat_json_node_t *node = NULL;
13183   struct in_addr ip4;
13184   struct in6_addr ip6;
13185
13186   if (VAT_JSON_ARRAY != vam->json_tree.type)
13187     {
13188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13189       vat_json_init_array (&vam->json_tree);
13190     }
13191   node = vat_json_array_add (&vam->json_tree);
13192
13193   vat_json_init_object (node);
13194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13195   if (!mp->is_ipv6)
13196     {
13197       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13198       vat_json_object_add_ip4 (node, "src_address", ip4);
13199       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13200       vat_json_object_add_ip4 (node, "dst_address", ip4);
13201     }
13202   else
13203     {
13204       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13205       vat_json_object_add_ip6 (node, "src_address", ip6);
13206       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13207       vat_json_object_add_ip6 (node, "dst_address", ip6);
13208     }
13209   vat_json_object_add_uint (node, "teb", mp->teb);
13210   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13211   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13212 }
13213
13214 static int
13215 api_gre_tunnel_dump (vat_main_t * vam)
13216 {
13217   unformat_input_t *i = vam->input;
13218   vl_api_gre_tunnel_dump_t *mp;
13219   vl_api_control_ping_t *mp_ping;
13220   u32 sw_if_index;
13221   u8 sw_if_index_set = 0;
13222   int ret;
13223
13224   /* Parse args required to build the message */
13225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13226     {
13227       if (unformat (i, "sw_if_index %d", &sw_if_index))
13228         sw_if_index_set = 1;
13229       else
13230         break;
13231     }
13232
13233   if (sw_if_index_set == 0)
13234     {
13235       sw_if_index = ~0;
13236     }
13237
13238   if (!vam->json_output)
13239     {
13240       print (vam->ofp, "%11s%24s%24s%6s%14s",
13241              "sw_if_index", "src_address", "dst_address", "teb",
13242              "outer_fib_id");
13243     }
13244
13245   /* Get list of gre-tunnel interfaces */
13246   M (GRE_TUNNEL_DUMP, mp);
13247
13248   mp->sw_if_index = htonl (sw_if_index);
13249
13250   S (mp);
13251
13252   /* Use a control ping for synchronization */
13253   MPING (CONTROL_PING, mp_ping);
13254   S (mp_ping);
13255
13256   W (ret);
13257   return ret;
13258 }
13259
13260 static int
13261 api_l2_fib_clear_table (vat_main_t * vam)
13262 {
13263 //  unformat_input_t * i = vam->input;
13264   vl_api_l2_fib_clear_table_t *mp;
13265   int ret;
13266
13267   M (L2_FIB_CLEAR_TABLE, mp);
13268
13269   S (mp);
13270   W (ret);
13271   return ret;
13272 }
13273
13274 static int
13275 api_l2_interface_efp_filter (vat_main_t * vam)
13276 {
13277   unformat_input_t *i = vam->input;
13278   vl_api_l2_interface_efp_filter_t *mp;
13279   u32 sw_if_index;
13280   u8 enable = 1;
13281   u8 sw_if_index_set = 0;
13282   int ret;
13283
13284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13287         sw_if_index_set = 1;
13288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13289         sw_if_index_set = 1;
13290       else if (unformat (i, "enable"))
13291         enable = 1;
13292       else if (unformat (i, "disable"))
13293         enable = 0;
13294       else
13295         {
13296           clib_warning ("parse error '%U'", format_unformat_error, i);
13297           return -99;
13298         }
13299     }
13300
13301   if (sw_if_index_set == 0)
13302     {
13303       errmsg ("missing sw_if_index");
13304       return -99;
13305     }
13306
13307   M (L2_INTERFACE_EFP_FILTER, mp);
13308
13309   mp->sw_if_index = ntohl (sw_if_index);
13310   mp->enable_disable = enable;
13311
13312   S (mp);
13313   W (ret);
13314   return ret;
13315 }
13316
13317 #define foreach_vtr_op                          \
13318 _("disable",  L2_VTR_DISABLED)                  \
13319 _("push-1",  L2_VTR_PUSH_1)                     \
13320 _("push-2",  L2_VTR_PUSH_2)                     \
13321 _("pop-1",  L2_VTR_POP_1)                       \
13322 _("pop-2",  L2_VTR_POP_2)                       \
13323 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13324 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13325 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13326 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13327
13328 static int
13329 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13330 {
13331   unformat_input_t *i = vam->input;
13332   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13333   u32 sw_if_index;
13334   u8 sw_if_index_set = 0;
13335   u8 vtr_op_set = 0;
13336   u32 vtr_op = 0;
13337   u32 push_dot1q = 1;
13338   u32 tag1 = ~0;
13339   u32 tag2 = ~0;
13340   int ret;
13341
13342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13343     {
13344       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13345         sw_if_index_set = 1;
13346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13347         sw_if_index_set = 1;
13348       else if (unformat (i, "vtr_op %d", &vtr_op))
13349         vtr_op_set = 1;
13350 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13351       foreach_vtr_op
13352 #undef _
13353         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13354         ;
13355       else if (unformat (i, "tag1 %d", &tag1))
13356         ;
13357       else if (unformat (i, "tag2 %d", &tag2))
13358         ;
13359       else
13360         {
13361           clib_warning ("parse error '%U'", format_unformat_error, i);
13362           return -99;
13363         }
13364     }
13365
13366   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13367     {
13368       errmsg ("missing vtr operation or sw_if_index");
13369       return -99;
13370     }
13371
13372   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13373   mp->sw_if_index = ntohl (sw_if_index);
13374   mp->vtr_op = ntohl (vtr_op);
13375   mp->push_dot1q = ntohl (push_dot1q);
13376   mp->tag1 = ntohl (tag1);
13377   mp->tag2 = ntohl (tag2);
13378
13379   S (mp);
13380   W (ret);
13381   return ret;
13382 }
13383
13384 static int
13385 api_create_vhost_user_if (vat_main_t * vam)
13386 {
13387   unformat_input_t *i = vam->input;
13388   vl_api_create_vhost_user_if_t *mp;
13389   u8 *file_name;
13390   u8 is_server = 0;
13391   u8 file_name_set = 0;
13392   u32 custom_dev_instance = ~0;
13393   u8 hwaddr[6];
13394   u8 use_custom_mac = 0;
13395   u8 *tag = 0;
13396   int ret;
13397
13398   /* Shut up coverity */
13399   memset (hwaddr, 0, sizeof (hwaddr));
13400
13401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13402     {
13403       if (unformat (i, "socket %s", &file_name))
13404         {
13405           file_name_set = 1;
13406         }
13407       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13408         ;
13409       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13410         use_custom_mac = 1;
13411       else if (unformat (i, "server"))
13412         is_server = 1;
13413       else if (unformat (i, "tag %s", &tag))
13414         ;
13415       else
13416         break;
13417     }
13418
13419   if (file_name_set == 0)
13420     {
13421       errmsg ("missing socket file name");
13422       return -99;
13423     }
13424
13425   if (vec_len (file_name) > 255)
13426     {
13427       errmsg ("socket file name too long");
13428       return -99;
13429     }
13430   vec_add1 (file_name, 0);
13431
13432   M (CREATE_VHOST_USER_IF, mp);
13433
13434   mp->is_server = is_server;
13435   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13436   vec_free (file_name);
13437   if (custom_dev_instance != ~0)
13438     {
13439       mp->renumber = 1;
13440       mp->custom_dev_instance = ntohl (custom_dev_instance);
13441     }
13442   mp->use_custom_mac = use_custom_mac;
13443   clib_memcpy (mp->mac_address, hwaddr, 6);
13444   if (tag)
13445     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13446   vec_free (tag);
13447
13448   S (mp);
13449   W (ret);
13450   return ret;
13451 }
13452
13453 static int
13454 api_modify_vhost_user_if (vat_main_t * vam)
13455 {
13456   unformat_input_t *i = vam->input;
13457   vl_api_modify_vhost_user_if_t *mp;
13458   u8 *file_name;
13459   u8 is_server = 0;
13460   u8 file_name_set = 0;
13461   u32 custom_dev_instance = ~0;
13462   u8 sw_if_index_set = 0;
13463   u32 sw_if_index = (u32) ~ 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 if (unformat (i, "socket %s", &file_name))
13473         {
13474           file_name_set = 1;
13475         }
13476       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13477         ;
13478       else if (unformat (i, "server"))
13479         is_server = 1;
13480       else
13481         break;
13482     }
13483
13484   if (sw_if_index_set == 0)
13485     {
13486       errmsg ("missing sw_if_index or interface name");
13487       return -99;
13488     }
13489
13490   if (file_name_set == 0)
13491     {
13492       errmsg ("missing socket file name");
13493       return -99;
13494     }
13495
13496   if (vec_len (file_name) > 255)
13497     {
13498       errmsg ("socket file name too long");
13499       return -99;
13500     }
13501   vec_add1 (file_name, 0);
13502
13503   M (MODIFY_VHOST_USER_IF, mp);
13504
13505   mp->sw_if_index = ntohl (sw_if_index);
13506   mp->is_server = is_server;
13507   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13508   vec_free (file_name);
13509   if (custom_dev_instance != ~0)
13510     {
13511       mp->renumber = 1;
13512       mp->custom_dev_instance = ntohl (custom_dev_instance);
13513     }
13514
13515   S (mp);
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static int
13521 api_delete_vhost_user_if (vat_main_t * vam)
13522 {
13523   unformat_input_t *i = vam->input;
13524   vl_api_delete_vhost_user_if_t *mp;
13525   u32 sw_if_index = ~0;
13526   u8 sw_if_index_set = 0;
13527   int ret;
13528
13529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13530     {
13531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13532         sw_if_index_set = 1;
13533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13534         sw_if_index_set = 1;
13535       else
13536         break;
13537     }
13538
13539   if (sw_if_index_set == 0)
13540     {
13541       errmsg ("missing sw_if_index or interface name");
13542       return -99;
13543     }
13544
13545
13546   M (DELETE_VHOST_USER_IF, mp);
13547
13548   mp->sw_if_index = ntohl (sw_if_index);
13549
13550   S (mp);
13551   W (ret);
13552   return ret;
13553 }
13554
13555 static void vl_api_sw_interface_vhost_user_details_t_handler
13556   (vl_api_sw_interface_vhost_user_details_t * mp)
13557 {
13558   vat_main_t *vam = &vat_main;
13559
13560   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13561          (char *) mp->interface_name,
13562          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13563          clib_net_to_host_u64 (mp->features), mp->is_server,
13564          ntohl (mp->num_regions), (char *) mp->sock_filename);
13565   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13566 }
13567
13568 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13569   (vl_api_sw_interface_vhost_user_details_t * mp)
13570 {
13571   vat_main_t *vam = &vat_main;
13572   vat_json_node_t *node = NULL;
13573
13574   if (VAT_JSON_ARRAY != vam->json_tree.type)
13575     {
13576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13577       vat_json_init_array (&vam->json_tree);
13578     }
13579   node = vat_json_array_add (&vam->json_tree);
13580
13581   vat_json_init_object (node);
13582   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13583   vat_json_object_add_string_copy (node, "interface_name",
13584                                    mp->interface_name);
13585   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13586                             ntohl (mp->virtio_net_hdr_sz));
13587   vat_json_object_add_uint (node, "features",
13588                             clib_net_to_host_u64 (mp->features));
13589   vat_json_object_add_uint (node, "is_server", mp->is_server);
13590   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13591   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13592   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13593 }
13594
13595 static int
13596 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13597 {
13598   vl_api_sw_interface_vhost_user_dump_t *mp;
13599   vl_api_control_ping_t *mp_ping;
13600   int ret;
13601   print (vam->ofp,
13602          "Interface name            idx hdr_sz features server regions filename");
13603
13604   /* Get list of vhost-user interfaces */
13605   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13606   S (mp);
13607
13608   /* Use a control ping for synchronization */
13609   MPING (CONTROL_PING, mp_ping);
13610   S (mp_ping);
13611
13612   W (ret);
13613   return ret;
13614 }
13615
13616 static int
13617 api_show_version (vat_main_t * vam)
13618 {
13619   vl_api_show_version_t *mp;
13620   int ret;
13621
13622   M (SHOW_VERSION, mp);
13623
13624   S (mp);
13625   W (ret);
13626   return ret;
13627 }
13628
13629
13630 static int
13631 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13632 {
13633   unformat_input_t *line_input = vam->input;
13634   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13635   ip4_address_t local4, remote4;
13636   ip6_address_t local6, remote6;
13637   u8 is_add = 1;
13638   u8 ipv4_set = 0, ipv6_set = 0;
13639   u8 local_set = 0;
13640   u8 remote_set = 0;
13641   u8 grp_set = 0;
13642   u32 mcast_sw_if_index = ~0;
13643   u32 encap_vrf_id = 0;
13644   u32 decap_vrf_id = 0;
13645   u8 protocol = ~0;
13646   u32 vni;
13647   u8 vni_set = 0;
13648   int ret;
13649
13650   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13651   memset (&local4, 0, sizeof local4);
13652   memset (&remote4, 0, sizeof remote4);
13653   memset (&local6, 0, sizeof local6);
13654   memset (&remote6, 0, sizeof remote6);
13655
13656   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13657     {
13658       if (unformat (line_input, "del"))
13659         is_add = 0;
13660       else if (unformat (line_input, "local %U",
13661                          unformat_ip4_address, &local4))
13662         {
13663           local_set = 1;
13664           ipv4_set = 1;
13665         }
13666       else if (unformat (line_input, "remote %U",
13667                          unformat_ip4_address, &remote4))
13668         {
13669           remote_set = 1;
13670           ipv4_set = 1;
13671         }
13672       else if (unformat (line_input, "local %U",
13673                          unformat_ip6_address, &local6))
13674         {
13675           local_set = 1;
13676           ipv6_set = 1;
13677         }
13678       else if (unformat (line_input, "remote %U",
13679                          unformat_ip6_address, &remote6))
13680         {
13681           remote_set = 1;
13682           ipv6_set = 1;
13683         }
13684       else if (unformat (line_input, "group %U %U",
13685                          unformat_ip4_address, &remote4,
13686                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13687         {
13688           grp_set = remote_set = 1;
13689           ipv4_set = 1;
13690         }
13691       else if (unformat (line_input, "group %U",
13692                          unformat_ip4_address, &remote4))
13693         {
13694           grp_set = remote_set = 1;
13695           ipv4_set = 1;
13696         }
13697       else if (unformat (line_input, "group %U %U",
13698                          unformat_ip6_address, &remote6,
13699                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13700         {
13701           grp_set = remote_set = 1;
13702           ipv6_set = 1;
13703         }
13704       else if (unformat (line_input, "group %U",
13705                          unformat_ip6_address, &remote6))
13706         {
13707           grp_set = remote_set = 1;
13708           ipv6_set = 1;
13709         }
13710       else
13711         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13712         ;
13713       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13714         ;
13715       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13716         ;
13717       else if (unformat (line_input, "vni %d", &vni))
13718         vni_set = 1;
13719       else if (unformat (line_input, "next-ip4"))
13720         protocol = 1;
13721       else if (unformat (line_input, "next-ip6"))
13722         protocol = 2;
13723       else if (unformat (line_input, "next-ethernet"))
13724         protocol = 3;
13725       else if (unformat (line_input, "next-nsh"))
13726         protocol = 4;
13727       else
13728         {
13729           errmsg ("parse error '%U'", format_unformat_error, line_input);
13730           return -99;
13731         }
13732     }
13733
13734   if (local_set == 0)
13735     {
13736       errmsg ("tunnel local address not specified");
13737       return -99;
13738     }
13739   if (remote_set == 0)
13740     {
13741       errmsg ("tunnel remote address not specified");
13742       return -99;
13743     }
13744   if (grp_set && mcast_sw_if_index == ~0)
13745     {
13746       errmsg ("tunnel nonexistent multicast device");
13747       return -99;
13748     }
13749   if (ipv4_set && ipv6_set)
13750     {
13751       errmsg ("both IPv4 and IPv6 addresses specified");
13752       return -99;
13753     }
13754
13755   if (vni_set == 0)
13756     {
13757       errmsg ("vni not specified");
13758       return -99;
13759     }
13760
13761   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13762
13763
13764   if (ipv6_set)
13765     {
13766       clib_memcpy (&mp->local, &local6, sizeof (local6));
13767       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13768     }
13769   else
13770     {
13771       clib_memcpy (&mp->local, &local4, sizeof (local4));
13772       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13773     }
13774
13775   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13776   mp->encap_vrf_id = ntohl (encap_vrf_id);
13777   mp->decap_vrf_id = ntohl (decap_vrf_id);
13778   mp->protocol = protocol;
13779   mp->vni = ntohl (vni);
13780   mp->is_add = is_add;
13781   mp->is_ipv6 = ipv6_set;
13782
13783   S (mp);
13784   W (ret);
13785   return ret;
13786 }
13787
13788 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13789   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13790 {
13791   vat_main_t *vam = &vat_main;
13792   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13793   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13794
13795   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13796          ntohl (mp->sw_if_index),
13797          format_ip46_address, &local, IP46_TYPE_ANY,
13798          format_ip46_address, &remote, IP46_TYPE_ANY,
13799          ntohl (mp->vni), mp->protocol,
13800          ntohl (mp->mcast_sw_if_index),
13801          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13802 }
13803
13804
13805 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13806   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13807 {
13808   vat_main_t *vam = &vat_main;
13809   vat_json_node_t *node = NULL;
13810   struct in_addr ip4;
13811   struct in6_addr ip6;
13812
13813   if (VAT_JSON_ARRAY != vam->json_tree.type)
13814     {
13815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13816       vat_json_init_array (&vam->json_tree);
13817     }
13818   node = vat_json_array_add (&vam->json_tree);
13819
13820   vat_json_init_object (node);
13821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13822   if (mp->is_ipv6)
13823     {
13824       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13825       vat_json_object_add_ip6 (node, "local", ip6);
13826       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13827       vat_json_object_add_ip6 (node, "remote", ip6);
13828     }
13829   else
13830     {
13831       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13832       vat_json_object_add_ip4 (node, "local", ip4);
13833       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13834       vat_json_object_add_ip4 (node, "remote", ip4);
13835     }
13836   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13837   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13838   vat_json_object_add_uint (node, "mcast_sw_if_index",
13839                             ntohl (mp->mcast_sw_if_index));
13840   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13841   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13842   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13843 }
13844
13845 static int
13846 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13847 {
13848   unformat_input_t *i = vam->input;
13849   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13850   vl_api_control_ping_t *mp_ping;
13851   u32 sw_if_index;
13852   u8 sw_if_index_set = 0;
13853   int ret;
13854
13855   /* Parse args required to build the message */
13856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13857     {
13858       if (unformat (i, "sw_if_index %d", &sw_if_index))
13859         sw_if_index_set = 1;
13860       else
13861         break;
13862     }
13863
13864   if (sw_if_index_set == 0)
13865     {
13866       sw_if_index = ~0;
13867     }
13868
13869   if (!vam->json_output)
13870     {
13871       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13872              "sw_if_index", "local", "remote", "vni",
13873              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13874     }
13875
13876   /* Get list of vxlan-tunnel interfaces */
13877   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13878
13879   mp->sw_if_index = htonl (sw_if_index);
13880
13881   S (mp);
13882
13883   /* Use a control ping for synchronization */
13884   MPING (CONTROL_PING, mp_ping);
13885   S (mp_ping);
13886
13887   W (ret);
13888   return ret;
13889 }
13890
13891 static void vl_api_l2_fib_table_details_t_handler
13892   (vl_api_l2_fib_table_details_t * mp)
13893 {
13894   vat_main_t *vam = &vat_main;
13895
13896   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13897          "       %d       %d     %d",
13898          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13899          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13900          mp->bvi_mac);
13901 }
13902
13903 static void vl_api_l2_fib_table_details_t_handler_json
13904   (vl_api_l2_fib_table_details_t * mp)
13905 {
13906   vat_main_t *vam = &vat_main;
13907   vat_json_node_t *node = NULL;
13908
13909   if (VAT_JSON_ARRAY != vam->json_tree.type)
13910     {
13911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13912       vat_json_init_array (&vam->json_tree);
13913     }
13914   node = vat_json_array_add (&vam->json_tree);
13915
13916   vat_json_init_object (node);
13917   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13918   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13919   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13920   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13921   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13922   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13923 }
13924
13925 static int
13926 api_l2_fib_table_dump (vat_main_t * vam)
13927 {
13928   unformat_input_t *i = vam->input;
13929   vl_api_l2_fib_table_dump_t *mp;
13930   vl_api_control_ping_t *mp_ping;
13931   u32 bd_id;
13932   u8 bd_id_set = 0;
13933   int ret;
13934
13935   /* Parse args required to build the message */
13936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13937     {
13938       if (unformat (i, "bd_id %d", &bd_id))
13939         bd_id_set = 1;
13940       else
13941         break;
13942     }
13943
13944   if (bd_id_set == 0)
13945     {
13946       errmsg ("missing bridge domain");
13947       return -99;
13948     }
13949
13950   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13951
13952   /* Get list of l2 fib entries */
13953   M (L2_FIB_TABLE_DUMP, mp);
13954
13955   mp->bd_id = ntohl (bd_id);
13956   S (mp);
13957
13958   /* Use a control ping for synchronization */
13959   MPING (CONTROL_PING, mp_ping);
13960   S (mp_ping);
13961
13962   W (ret);
13963   return ret;
13964 }
13965
13966
13967 static int
13968 api_interface_name_renumber (vat_main_t * vam)
13969 {
13970   unformat_input_t *line_input = vam->input;
13971   vl_api_interface_name_renumber_t *mp;
13972   u32 sw_if_index = ~0;
13973   u32 new_show_dev_instance = ~0;
13974   int ret;
13975
13976   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13977     {
13978       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13979                     &sw_if_index))
13980         ;
13981       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13982         ;
13983       else if (unformat (line_input, "new_show_dev_instance %d",
13984                          &new_show_dev_instance))
13985         ;
13986       else
13987         break;
13988     }
13989
13990   if (sw_if_index == ~0)
13991     {
13992       errmsg ("missing interface name or sw_if_index");
13993       return -99;
13994     }
13995
13996   if (new_show_dev_instance == ~0)
13997     {
13998       errmsg ("missing new_show_dev_instance");
13999       return -99;
14000     }
14001
14002   M (INTERFACE_NAME_RENUMBER, mp);
14003
14004   mp->sw_if_index = ntohl (sw_if_index);
14005   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14006
14007   S (mp);
14008   W (ret);
14009   return ret;
14010 }
14011
14012 static int
14013 api_want_ip4_arp_events (vat_main_t * vam)
14014 {
14015   unformat_input_t *line_input = vam->input;
14016   vl_api_want_ip4_arp_events_t *mp;
14017   ip4_address_t address;
14018   int address_set = 0;
14019   u32 enable_disable = 1;
14020   int ret;
14021
14022   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14023     {
14024       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14025         address_set = 1;
14026       else if (unformat (line_input, "del"))
14027         enable_disable = 0;
14028       else
14029         break;
14030     }
14031
14032   if (address_set == 0)
14033     {
14034       errmsg ("missing addresses");
14035       return -99;
14036     }
14037
14038   M (WANT_IP4_ARP_EVENTS, mp);
14039   mp->enable_disable = enable_disable;
14040   mp->pid = htonl (getpid ());
14041   mp->address = address.as_u32;
14042
14043   S (mp);
14044   W (ret);
14045   return ret;
14046 }
14047
14048 static int
14049 api_want_ip6_nd_events (vat_main_t * vam)
14050 {
14051   unformat_input_t *line_input = vam->input;
14052   vl_api_want_ip6_nd_events_t *mp;
14053   ip6_address_t address;
14054   int address_set = 0;
14055   u32 enable_disable = 1;
14056   int ret;
14057
14058   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14059     {
14060       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14061         address_set = 1;
14062       else if (unformat (line_input, "del"))
14063         enable_disable = 0;
14064       else
14065         break;
14066     }
14067
14068   if (address_set == 0)
14069     {
14070       errmsg ("missing addresses");
14071       return -99;
14072     }
14073
14074   M (WANT_IP6_ND_EVENTS, mp);
14075   mp->enable_disable = enable_disable;
14076   mp->pid = htonl (getpid ());
14077   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14078
14079   S (mp);
14080   W (ret);
14081   return ret;
14082 }
14083
14084 static int
14085 api_want_l2_macs_events (vat_main_t * vam)
14086 {
14087   unformat_input_t *line_input = vam->input;
14088   vl_api_want_l2_macs_events_t *mp;
14089   u8 enable_disable = 1;
14090   u32 scan_delay = 0;
14091   u32 max_macs_in_event = 0;
14092   u32 learn_limit = 0;
14093   int ret;
14094
14095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14096     {
14097       if (unformat (line_input, "learn-limit %d", &learn_limit))
14098         ;
14099       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14100         ;
14101       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14102         ;
14103       else if (unformat (line_input, "disable"))
14104         enable_disable = 0;
14105       else
14106         break;
14107     }
14108
14109   M (WANT_L2_MACS_EVENTS, mp);
14110   mp->enable_disable = enable_disable;
14111   mp->pid = htonl (getpid ());
14112   mp->learn_limit = htonl (learn_limit);
14113   mp->scan_delay = (u8) scan_delay;
14114   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14115   S (mp);
14116   W (ret);
14117   return ret;
14118 }
14119
14120 static int
14121 api_input_acl_set_interface (vat_main_t * vam)
14122 {
14123   unformat_input_t *i = vam->input;
14124   vl_api_input_acl_set_interface_t *mp;
14125   u32 sw_if_index;
14126   int sw_if_index_set;
14127   u32 ip4_table_index = ~0;
14128   u32 ip6_table_index = ~0;
14129   u32 l2_table_index = ~0;
14130   u8 is_add = 1;
14131   int ret;
14132
14133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14134     {
14135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14136         sw_if_index_set = 1;
14137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14138         sw_if_index_set = 1;
14139       else if (unformat (i, "del"))
14140         is_add = 0;
14141       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14142         ;
14143       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14144         ;
14145       else if (unformat (i, "l2-table %d", &l2_table_index))
14146         ;
14147       else
14148         {
14149           clib_warning ("parse error '%U'", format_unformat_error, i);
14150           return -99;
14151         }
14152     }
14153
14154   if (sw_if_index_set == 0)
14155     {
14156       errmsg ("missing interface name or sw_if_index");
14157       return -99;
14158     }
14159
14160   M (INPUT_ACL_SET_INTERFACE, mp);
14161
14162   mp->sw_if_index = ntohl (sw_if_index);
14163   mp->ip4_table_index = ntohl (ip4_table_index);
14164   mp->ip6_table_index = ntohl (ip6_table_index);
14165   mp->l2_table_index = ntohl (l2_table_index);
14166   mp->is_add = is_add;
14167
14168   S (mp);
14169   W (ret);
14170   return ret;
14171 }
14172
14173 static int
14174 api_ip_address_dump (vat_main_t * vam)
14175 {
14176   unformat_input_t *i = vam->input;
14177   vl_api_ip_address_dump_t *mp;
14178   vl_api_control_ping_t *mp_ping;
14179   u32 sw_if_index = ~0;
14180   u8 sw_if_index_set = 0;
14181   u8 ipv4_set = 0;
14182   u8 ipv6_set = 0;
14183   int ret;
14184
14185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14186     {
14187       if (unformat (i, "sw_if_index %d", &sw_if_index))
14188         sw_if_index_set = 1;
14189       else
14190         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14191         sw_if_index_set = 1;
14192       else if (unformat (i, "ipv4"))
14193         ipv4_set = 1;
14194       else if (unformat (i, "ipv6"))
14195         ipv6_set = 1;
14196       else
14197         break;
14198     }
14199
14200   if (ipv4_set && ipv6_set)
14201     {
14202       errmsg ("ipv4 and ipv6 flags cannot be both set");
14203       return -99;
14204     }
14205
14206   if ((!ipv4_set) && (!ipv6_set))
14207     {
14208       errmsg ("no ipv4 nor ipv6 flag set");
14209       return -99;
14210     }
14211
14212   if (sw_if_index_set == 0)
14213     {
14214       errmsg ("missing interface name or sw_if_index");
14215       return -99;
14216     }
14217
14218   vam->current_sw_if_index = sw_if_index;
14219   vam->is_ipv6 = ipv6_set;
14220
14221   M (IP_ADDRESS_DUMP, mp);
14222   mp->sw_if_index = ntohl (sw_if_index);
14223   mp->is_ipv6 = ipv6_set;
14224   S (mp);
14225
14226   /* Use a control ping for synchronization */
14227   MPING (CONTROL_PING, mp_ping);
14228   S (mp_ping);
14229
14230   W (ret);
14231   return ret;
14232 }
14233
14234 static int
14235 api_ip_dump (vat_main_t * vam)
14236 {
14237   vl_api_ip_dump_t *mp;
14238   vl_api_control_ping_t *mp_ping;
14239   unformat_input_t *in = vam->input;
14240   int ipv4_set = 0;
14241   int ipv6_set = 0;
14242   int is_ipv6;
14243   int i;
14244   int ret;
14245
14246   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (in, "ipv4"))
14249         ipv4_set = 1;
14250       else if (unformat (in, "ipv6"))
14251         ipv6_set = 1;
14252       else
14253         break;
14254     }
14255
14256   if (ipv4_set && ipv6_set)
14257     {
14258       errmsg ("ipv4 and ipv6 flags cannot be both set");
14259       return -99;
14260     }
14261
14262   if ((!ipv4_set) && (!ipv6_set))
14263     {
14264       errmsg ("no ipv4 nor ipv6 flag set");
14265       return -99;
14266     }
14267
14268   is_ipv6 = ipv6_set;
14269   vam->is_ipv6 = is_ipv6;
14270
14271   /* free old data */
14272   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14273     {
14274       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14275     }
14276   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14277
14278   M (IP_DUMP, mp);
14279   mp->is_ipv6 = ipv6_set;
14280   S (mp);
14281
14282   /* Use a control ping for synchronization */
14283   MPING (CONTROL_PING, mp_ping);
14284   S (mp_ping);
14285
14286   W (ret);
14287   return ret;
14288 }
14289
14290 static int
14291 api_ipsec_spd_add_del (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_ipsec_spd_add_del_t *mp;
14295   u32 spd_id = ~0;
14296   u8 is_add = 1;
14297   int ret;
14298
14299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14300     {
14301       if (unformat (i, "spd_id %d", &spd_id))
14302         ;
14303       else if (unformat (i, "del"))
14304         is_add = 0;
14305       else
14306         {
14307           clib_warning ("parse error '%U'", format_unformat_error, i);
14308           return -99;
14309         }
14310     }
14311   if (spd_id == ~0)
14312     {
14313       errmsg ("spd_id must be set");
14314       return -99;
14315     }
14316
14317   M (IPSEC_SPD_ADD_DEL, mp);
14318
14319   mp->spd_id = ntohl (spd_id);
14320   mp->is_add = is_add;
14321
14322   S (mp);
14323   W (ret);
14324   return ret;
14325 }
14326
14327 static int
14328 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14329 {
14330   unformat_input_t *i = vam->input;
14331   vl_api_ipsec_interface_add_del_spd_t *mp;
14332   u32 sw_if_index;
14333   u8 sw_if_index_set = 0;
14334   u32 spd_id = (u32) ~ 0;
14335   u8 is_add = 1;
14336   int ret;
14337
14338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (i, "del"))
14341         is_add = 0;
14342       else if (unformat (i, "spd_id %d", &spd_id))
14343         ;
14344       else
14345         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14346         sw_if_index_set = 1;
14347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14348         sw_if_index_set = 1;
14349       else
14350         {
14351           clib_warning ("parse error '%U'", format_unformat_error, i);
14352           return -99;
14353         }
14354
14355     }
14356
14357   if (spd_id == (u32) ~ 0)
14358     {
14359       errmsg ("spd_id must be set");
14360       return -99;
14361     }
14362
14363   if (sw_if_index_set == 0)
14364     {
14365       errmsg ("missing interface name or sw_if_index");
14366       return -99;
14367     }
14368
14369   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14370
14371   mp->spd_id = ntohl (spd_id);
14372   mp->sw_if_index = ntohl (sw_if_index);
14373   mp->is_add = is_add;
14374
14375   S (mp);
14376   W (ret);
14377   return ret;
14378 }
14379
14380 static int
14381 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_ipsec_spd_add_del_entry_t *mp;
14385   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14386   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14387   i32 priority = 0;
14388   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14389   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14390   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14391   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14392   int ret;
14393
14394   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14395   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14396   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14397   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14398   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14399   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14400
14401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (i, "del"))
14404         is_add = 0;
14405       if (unformat (i, "outbound"))
14406         is_outbound = 1;
14407       if (unformat (i, "inbound"))
14408         is_outbound = 0;
14409       else if (unformat (i, "spd_id %d", &spd_id))
14410         ;
14411       else if (unformat (i, "sa_id %d", &sa_id))
14412         ;
14413       else if (unformat (i, "priority %d", &priority))
14414         ;
14415       else if (unformat (i, "protocol %d", &protocol))
14416         ;
14417       else if (unformat (i, "lport_start %d", &lport_start))
14418         ;
14419       else if (unformat (i, "lport_stop %d", &lport_stop))
14420         ;
14421       else if (unformat (i, "rport_start %d", &rport_start))
14422         ;
14423       else if (unformat (i, "rport_stop %d", &rport_stop))
14424         ;
14425       else
14426         if (unformat
14427             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14428         {
14429           is_ipv6 = 0;
14430           is_ip_any = 0;
14431         }
14432       else
14433         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14434         {
14435           is_ipv6 = 0;
14436           is_ip_any = 0;
14437         }
14438       else
14439         if (unformat
14440             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14441         {
14442           is_ipv6 = 0;
14443           is_ip_any = 0;
14444         }
14445       else
14446         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14447         {
14448           is_ipv6 = 0;
14449           is_ip_any = 0;
14450         }
14451       else
14452         if (unformat
14453             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14454         {
14455           is_ipv6 = 1;
14456           is_ip_any = 0;
14457         }
14458       else
14459         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14460         {
14461           is_ipv6 = 1;
14462           is_ip_any = 0;
14463         }
14464       else
14465         if (unformat
14466             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14467         {
14468           is_ipv6 = 1;
14469           is_ip_any = 0;
14470         }
14471       else
14472         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14473         {
14474           is_ipv6 = 1;
14475           is_ip_any = 0;
14476         }
14477       else
14478         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14479         {
14480           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14481             {
14482               clib_warning ("unsupported action: 'resolve'");
14483               return -99;
14484             }
14485         }
14486       else
14487         {
14488           clib_warning ("parse error '%U'", format_unformat_error, i);
14489           return -99;
14490         }
14491
14492     }
14493
14494   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14495
14496   mp->spd_id = ntohl (spd_id);
14497   mp->priority = ntohl (priority);
14498   mp->is_outbound = is_outbound;
14499
14500   mp->is_ipv6 = is_ipv6;
14501   if (is_ipv6 || is_ip_any)
14502     {
14503       clib_memcpy (mp->remote_address_start, &raddr6_start,
14504                    sizeof (ip6_address_t));
14505       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14506                    sizeof (ip6_address_t));
14507       clib_memcpy (mp->local_address_start, &laddr6_start,
14508                    sizeof (ip6_address_t));
14509       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14510                    sizeof (ip6_address_t));
14511     }
14512   else
14513     {
14514       clib_memcpy (mp->remote_address_start, &raddr4_start,
14515                    sizeof (ip4_address_t));
14516       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14517                    sizeof (ip4_address_t));
14518       clib_memcpy (mp->local_address_start, &laddr4_start,
14519                    sizeof (ip4_address_t));
14520       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14521                    sizeof (ip4_address_t));
14522     }
14523   mp->protocol = (u8) protocol;
14524   mp->local_port_start = ntohs ((u16) lport_start);
14525   mp->local_port_stop = ntohs ((u16) lport_stop);
14526   mp->remote_port_start = ntohs ((u16) rport_start);
14527   mp->remote_port_stop = ntohs ((u16) rport_stop);
14528   mp->policy = (u8) policy;
14529   mp->sa_id = ntohl (sa_id);
14530   mp->is_add = is_add;
14531   mp->is_ip_any = is_ip_any;
14532   S (mp);
14533   W (ret);
14534   return ret;
14535 }
14536
14537 static int
14538 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14539 {
14540   unformat_input_t *i = vam->input;
14541   vl_api_ipsec_sad_add_del_entry_t *mp;
14542   u32 sad_id = 0, spi = 0;
14543   u8 *ck = 0, *ik = 0;
14544   u8 is_add = 1;
14545
14546   u8 protocol = IPSEC_PROTOCOL_AH;
14547   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14548   u32 crypto_alg = 0, integ_alg = 0;
14549   ip4_address_t tun_src4;
14550   ip4_address_t tun_dst4;
14551   ip6_address_t tun_src6;
14552   ip6_address_t tun_dst6;
14553   int ret;
14554
14555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14556     {
14557       if (unformat (i, "del"))
14558         is_add = 0;
14559       else if (unformat (i, "sad_id %d", &sad_id))
14560         ;
14561       else if (unformat (i, "spi %d", &spi))
14562         ;
14563       else if (unformat (i, "esp"))
14564         protocol = IPSEC_PROTOCOL_ESP;
14565       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14566         {
14567           is_tunnel = 1;
14568           is_tunnel_ipv6 = 0;
14569         }
14570       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14571         {
14572           is_tunnel = 1;
14573           is_tunnel_ipv6 = 0;
14574         }
14575       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14576         {
14577           is_tunnel = 1;
14578           is_tunnel_ipv6 = 1;
14579         }
14580       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14581         {
14582           is_tunnel = 1;
14583           is_tunnel_ipv6 = 1;
14584         }
14585       else
14586         if (unformat
14587             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14588         {
14589           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14590               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14591             {
14592               clib_warning ("unsupported crypto-alg: '%U'",
14593                             format_ipsec_crypto_alg, crypto_alg);
14594               return -99;
14595             }
14596         }
14597       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14598         ;
14599       else
14600         if (unformat
14601             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14602         {
14603           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14604               integ_alg >= IPSEC_INTEG_N_ALG)
14605             {
14606               clib_warning ("unsupported integ-alg: '%U'",
14607                             format_ipsec_integ_alg, integ_alg);
14608               return -99;
14609             }
14610         }
14611       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14612         ;
14613       else
14614         {
14615           clib_warning ("parse error '%U'", format_unformat_error, i);
14616           return -99;
14617         }
14618
14619     }
14620
14621   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14622
14623   mp->sad_id = ntohl (sad_id);
14624   mp->is_add = is_add;
14625   mp->protocol = protocol;
14626   mp->spi = ntohl (spi);
14627   mp->is_tunnel = is_tunnel;
14628   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14629   mp->crypto_algorithm = crypto_alg;
14630   mp->integrity_algorithm = integ_alg;
14631   mp->crypto_key_length = vec_len (ck);
14632   mp->integrity_key_length = vec_len (ik);
14633
14634   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14635     mp->crypto_key_length = sizeof (mp->crypto_key);
14636
14637   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14638     mp->integrity_key_length = sizeof (mp->integrity_key);
14639
14640   if (ck)
14641     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14642   if (ik)
14643     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14644
14645   if (is_tunnel)
14646     {
14647       if (is_tunnel_ipv6)
14648         {
14649           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14650                        sizeof (ip6_address_t));
14651           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14652                        sizeof (ip6_address_t));
14653         }
14654       else
14655         {
14656           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14657                        sizeof (ip4_address_t));
14658           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14659                        sizeof (ip4_address_t));
14660         }
14661     }
14662
14663   S (mp);
14664   W (ret);
14665   return ret;
14666 }
14667
14668 static int
14669 api_ipsec_sa_set_key (vat_main_t * vam)
14670 {
14671   unformat_input_t *i = vam->input;
14672   vl_api_ipsec_sa_set_key_t *mp;
14673   u32 sa_id;
14674   u8 *ck = 0, *ik = 0;
14675   int ret;
14676
14677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (i, "sa_id %d", &sa_id))
14680         ;
14681       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14682         ;
14683       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14684         ;
14685       else
14686         {
14687           clib_warning ("parse error '%U'", format_unformat_error, i);
14688           return -99;
14689         }
14690     }
14691
14692   M (IPSEC_SA_SET_KEY, mp);
14693
14694   mp->sa_id = ntohl (sa_id);
14695   mp->crypto_key_length = vec_len (ck);
14696   mp->integrity_key_length = vec_len (ik);
14697
14698   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14699     mp->crypto_key_length = sizeof (mp->crypto_key);
14700
14701   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14702     mp->integrity_key_length = sizeof (mp->integrity_key);
14703
14704   if (ck)
14705     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14706   if (ik)
14707     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14708
14709   S (mp);
14710   W (ret);
14711   return ret;
14712 }
14713
14714 static int
14715 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14716 {
14717   unformat_input_t *i = vam->input;
14718   vl_api_ipsec_tunnel_if_add_del_t *mp;
14719   u32 local_spi = 0, remote_spi = 0;
14720   u32 crypto_alg = 0, integ_alg = 0;
14721   u8 *lck = NULL, *rck = NULL;
14722   u8 *lik = NULL, *rik = NULL;
14723   ip4_address_t local_ip = { {0} };
14724   ip4_address_t remote_ip = { {0} };
14725   u8 is_add = 1;
14726   u8 esn = 0;
14727   u8 anti_replay = 0;
14728   int ret;
14729
14730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14731     {
14732       if (unformat (i, "del"))
14733         is_add = 0;
14734       else if (unformat (i, "esn"))
14735         esn = 1;
14736       else if (unformat (i, "anti_replay"))
14737         anti_replay = 1;
14738       else if (unformat (i, "local_spi %d", &local_spi))
14739         ;
14740       else if (unformat (i, "remote_spi %d", &remote_spi))
14741         ;
14742       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14743         ;
14744       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14745         ;
14746       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14747         ;
14748       else
14749         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14750         ;
14751       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14752         ;
14753       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14754         ;
14755       else
14756         if (unformat
14757             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14758         {
14759           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14760               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14761             {
14762               errmsg ("unsupported crypto-alg: '%U'\n",
14763                       format_ipsec_crypto_alg, crypto_alg);
14764               return -99;
14765             }
14766         }
14767       else
14768         if (unformat
14769             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14770         {
14771           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14772               integ_alg >= IPSEC_INTEG_N_ALG)
14773             {
14774               errmsg ("unsupported integ-alg: '%U'\n",
14775                       format_ipsec_integ_alg, integ_alg);
14776               return -99;
14777             }
14778         }
14779       else
14780         {
14781           errmsg ("parse error '%U'\n", format_unformat_error, i);
14782           return -99;
14783         }
14784     }
14785
14786   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14787
14788   mp->is_add = is_add;
14789   mp->esn = esn;
14790   mp->anti_replay = anti_replay;
14791
14792   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14793   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14794
14795   mp->local_spi = htonl (local_spi);
14796   mp->remote_spi = htonl (remote_spi);
14797   mp->crypto_alg = (u8) crypto_alg;
14798
14799   mp->local_crypto_key_len = 0;
14800   if (lck)
14801     {
14802       mp->local_crypto_key_len = vec_len (lck);
14803       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14804         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14805       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14806     }
14807
14808   mp->remote_crypto_key_len = 0;
14809   if (rck)
14810     {
14811       mp->remote_crypto_key_len = vec_len (rck);
14812       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14813         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14814       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14815     }
14816
14817   mp->integ_alg = (u8) integ_alg;
14818
14819   mp->local_integ_key_len = 0;
14820   if (lik)
14821     {
14822       mp->local_integ_key_len = vec_len (lik);
14823       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14824         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14825       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14826     }
14827
14828   mp->remote_integ_key_len = 0;
14829   if (rik)
14830     {
14831       mp->remote_integ_key_len = vec_len (rik);
14832       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14833         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14834       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14835     }
14836
14837   S (mp);
14838   W (ret);
14839   return ret;
14840 }
14841
14842 static void
14843 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14844 {
14845   vat_main_t *vam = &vat_main;
14846
14847   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14848          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14849          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14850          "tunnel_src_addr %U tunnel_dst_addr %U "
14851          "salt %u seq_outbound %lu last_seq_inbound %lu "
14852          "replay_window %lu total_data_size %lu\n",
14853          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14854          mp->protocol,
14855          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14856          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14857          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14858          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14859          mp->tunnel_src_addr,
14860          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14861          mp->tunnel_dst_addr,
14862          ntohl (mp->salt),
14863          clib_net_to_host_u64 (mp->seq_outbound),
14864          clib_net_to_host_u64 (mp->last_seq_inbound),
14865          clib_net_to_host_u64 (mp->replay_window),
14866          clib_net_to_host_u64 (mp->total_data_size));
14867 }
14868
14869 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14870 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14871
14872 static void vl_api_ipsec_sa_details_t_handler_json
14873   (vl_api_ipsec_sa_details_t * mp)
14874 {
14875   vat_main_t *vam = &vat_main;
14876   vat_json_node_t *node = NULL;
14877   struct in_addr src_ip4, dst_ip4;
14878   struct in6_addr src_ip6, dst_ip6;
14879
14880   if (VAT_JSON_ARRAY != vam->json_tree.type)
14881     {
14882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14883       vat_json_init_array (&vam->json_tree);
14884     }
14885   node = vat_json_array_add (&vam->json_tree);
14886
14887   vat_json_init_object (node);
14888   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14889   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14890   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14891   vat_json_object_add_uint (node, "proto", mp->protocol);
14892   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14893   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14894   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14895   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14896   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14897   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14898   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14899                              mp->crypto_key_len);
14900   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14901                              mp->integ_key_len);
14902   if (mp->is_tunnel_ip6)
14903     {
14904       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14905       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14906       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14907       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14908     }
14909   else
14910     {
14911       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14912       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14913       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14914       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14915     }
14916   vat_json_object_add_uint (node, "replay_window",
14917                             clib_net_to_host_u64 (mp->replay_window));
14918   vat_json_object_add_uint (node, "total_data_size",
14919                             clib_net_to_host_u64 (mp->total_data_size));
14920
14921 }
14922
14923 static int
14924 api_ipsec_sa_dump (vat_main_t * vam)
14925 {
14926   unformat_input_t *i = vam->input;
14927   vl_api_ipsec_sa_dump_t *mp;
14928   vl_api_control_ping_t *mp_ping;
14929   u32 sa_id = ~0;
14930   int ret;
14931
14932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14933     {
14934       if (unformat (i, "sa_id %d", &sa_id))
14935         ;
14936       else
14937         {
14938           clib_warning ("parse error '%U'", format_unformat_error, i);
14939           return -99;
14940         }
14941     }
14942
14943   M (IPSEC_SA_DUMP, mp);
14944
14945   mp->sa_id = ntohl (sa_id);
14946
14947   S (mp);
14948
14949   /* Use a control ping for synchronization */
14950   M (CONTROL_PING, mp_ping);
14951   S (mp_ping);
14952
14953   W (ret);
14954   return ret;
14955 }
14956
14957 static int
14958 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14959 {
14960   unformat_input_t *i = vam->input;
14961   vl_api_ipsec_tunnel_if_set_key_t *mp;
14962   u32 sw_if_index = ~0;
14963   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14964   u8 *key = 0;
14965   u32 alg = ~0;
14966   int ret;
14967
14968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14969     {
14970       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14971         ;
14972       else
14973         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14974         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14975       else
14976         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14977         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14978       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14979         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14980       else
14981         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14982         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14983       else if (unformat (i, "%U", unformat_hex_string, &key))
14984         ;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990     }
14991
14992   if (sw_if_index == ~0)
14993     {
14994       errmsg ("interface must be specified");
14995       return -99;
14996     }
14997
14998   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14999     {
15000       errmsg ("key type must be specified");
15001       return -99;
15002     }
15003
15004   if (alg == ~0)
15005     {
15006       errmsg ("algorithm must be specified");
15007       return -99;
15008     }
15009
15010   if (vec_len (key) == 0)
15011     {
15012       errmsg ("key must be specified");
15013       return -99;
15014     }
15015
15016   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15017
15018   mp->sw_if_index = htonl (sw_if_index);
15019   mp->alg = alg;
15020   mp->key_type = key_type;
15021   mp->key_len = vec_len (key);
15022   clib_memcpy (mp->key, key, vec_len (key));
15023
15024   S (mp);
15025   W (ret);
15026
15027   return ret;
15028 }
15029
15030 static int
15031 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15032 {
15033   unformat_input_t *i = vam->input;
15034   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15035   u32 sw_if_index = ~0;
15036   u32 sa_id = ~0;
15037   u8 is_outbound = (u8) ~ 0;
15038   int ret;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15043         ;
15044       else if (unformat (i, "sa_id %d", &sa_id))
15045         ;
15046       else if (unformat (i, "outbound"))
15047         is_outbound = 1;
15048       else if (unformat (i, "inbound"))
15049         is_outbound = 0;
15050       else
15051         {
15052           clib_warning ("parse error '%U'", format_unformat_error, i);
15053           return -99;
15054         }
15055     }
15056
15057   if (sw_if_index == ~0)
15058     {
15059       errmsg ("interface must be specified");
15060       return -99;
15061     }
15062
15063   if (sa_id == ~0)
15064     {
15065       errmsg ("SA ID must be specified");
15066       return -99;
15067     }
15068
15069   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15070
15071   mp->sw_if_index = htonl (sw_if_index);
15072   mp->sa_id = htonl (sa_id);
15073   mp->is_outbound = is_outbound;
15074
15075   S (mp);
15076   W (ret);
15077
15078   return ret;
15079 }
15080
15081 static int
15082 api_ikev2_profile_add_del (vat_main_t * vam)
15083 {
15084   unformat_input_t *i = vam->input;
15085   vl_api_ikev2_profile_add_del_t *mp;
15086   u8 is_add = 1;
15087   u8 *name = 0;
15088   int ret;
15089
15090   const char *valid_chars = "a-zA-Z0-9_";
15091
15092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15093     {
15094       if (unformat (i, "del"))
15095         is_add = 0;
15096       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15097         vec_add1 (name, 0);
15098       else
15099         {
15100           errmsg ("parse error '%U'", format_unformat_error, i);
15101           return -99;
15102         }
15103     }
15104
15105   if (!vec_len (name))
15106     {
15107       errmsg ("profile name must be specified");
15108       return -99;
15109     }
15110
15111   if (vec_len (name) > 64)
15112     {
15113       errmsg ("profile name too long");
15114       return -99;
15115     }
15116
15117   M (IKEV2_PROFILE_ADD_DEL, mp);
15118
15119   clib_memcpy (mp->name, name, vec_len (name));
15120   mp->is_add = is_add;
15121   vec_free (name);
15122
15123   S (mp);
15124   W (ret);
15125   return ret;
15126 }
15127
15128 static int
15129 api_ikev2_profile_set_auth (vat_main_t * vam)
15130 {
15131   unformat_input_t *i = vam->input;
15132   vl_api_ikev2_profile_set_auth_t *mp;
15133   u8 *name = 0;
15134   u8 *data = 0;
15135   u32 auth_method = 0;
15136   u8 is_hex = 0;
15137   int ret;
15138
15139   const char *valid_chars = "a-zA-Z0-9_";
15140
15141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15142     {
15143       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15144         vec_add1 (name, 0);
15145       else if (unformat (i, "auth_method %U",
15146                          unformat_ikev2_auth_method, &auth_method))
15147         ;
15148       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15149         is_hex = 1;
15150       else if (unformat (i, "auth_data %v", &data))
15151         ;
15152       else
15153         {
15154           errmsg ("parse error '%U'", format_unformat_error, i);
15155           return -99;
15156         }
15157     }
15158
15159   if (!vec_len (name))
15160     {
15161       errmsg ("profile name must be specified");
15162       return -99;
15163     }
15164
15165   if (vec_len (name) > 64)
15166     {
15167       errmsg ("profile name too long");
15168       return -99;
15169     }
15170
15171   if (!vec_len (data))
15172     {
15173       errmsg ("auth_data must be specified");
15174       return -99;
15175     }
15176
15177   if (!auth_method)
15178     {
15179       errmsg ("auth_method must be specified");
15180       return -99;
15181     }
15182
15183   M (IKEV2_PROFILE_SET_AUTH, mp);
15184
15185   mp->is_hex = is_hex;
15186   mp->auth_method = (u8) auth_method;
15187   mp->data_len = vec_len (data);
15188   clib_memcpy (mp->name, name, vec_len (name));
15189   clib_memcpy (mp->data, data, vec_len (data));
15190   vec_free (name);
15191   vec_free (data);
15192
15193   S (mp);
15194   W (ret);
15195   return ret;
15196 }
15197
15198 static int
15199 api_ikev2_profile_set_id (vat_main_t * vam)
15200 {
15201   unformat_input_t *i = vam->input;
15202   vl_api_ikev2_profile_set_id_t *mp;
15203   u8 *name = 0;
15204   u8 *data = 0;
15205   u8 is_local = 0;
15206   u32 id_type = 0;
15207   ip4_address_t ip4;
15208   int ret;
15209
15210   const char *valid_chars = "a-zA-Z0-9_";
15211
15212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15213     {
15214       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15215         vec_add1 (name, 0);
15216       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15217         ;
15218       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15219         {
15220           data = vec_new (u8, 4);
15221           clib_memcpy (data, ip4.as_u8, 4);
15222         }
15223       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15224         ;
15225       else if (unformat (i, "id_data %v", &data))
15226         ;
15227       else if (unformat (i, "local"))
15228         is_local = 1;
15229       else if (unformat (i, "remote"))
15230         is_local = 0;
15231       else
15232         {
15233           errmsg ("parse error '%U'", format_unformat_error, i);
15234           return -99;
15235         }
15236     }
15237
15238   if (!vec_len (name))
15239     {
15240       errmsg ("profile name must be specified");
15241       return -99;
15242     }
15243
15244   if (vec_len (name) > 64)
15245     {
15246       errmsg ("profile name too long");
15247       return -99;
15248     }
15249
15250   if (!vec_len (data))
15251     {
15252       errmsg ("id_data must be specified");
15253       return -99;
15254     }
15255
15256   if (!id_type)
15257     {
15258       errmsg ("id_type must be specified");
15259       return -99;
15260     }
15261
15262   M (IKEV2_PROFILE_SET_ID, mp);
15263
15264   mp->is_local = is_local;
15265   mp->id_type = (u8) id_type;
15266   mp->data_len = vec_len (data);
15267   clib_memcpy (mp->name, name, vec_len (name));
15268   clib_memcpy (mp->data, data, vec_len (data));
15269   vec_free (name);
15270   vec_free (data);
15271
15272   S (mp);
15273   W (ret);
15274   return ret;
15275 }
15276
15277 static int
15278 api_ikev2_profile_set_ts (vat_main_t * vam)
15279 {
15280   unformat_input_t *i = vam->input;
15281   vl_api_ikev2_profile_set_ts_t *mp;
15282   u8 *name = 0;
15283   u8 is_local = 0;
15284   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15285   ip4_address_t start_addr, end_addr;
15286
15287   const char *valid_chars = "a-zA-Z0-9_";
15288   int ret;
15289
15290   start_addr.as_u32 = 0;
15291   end_addr.as_u32 = (u32) ~ 0;
15292
15293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15294     {
15295       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15296         vec_add1 (name, 0);
15297       else if (unformat (i, "protocol %d", &proto))
15298         ;
15299       else if (unformat (i, "start_port %d", &start_port))
15300         ;
15301       else if (unformat (i, "end_port %d", &end_port))
15302         ;
15303       else
15304         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15305         ;
15306       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15307         ;
15308       else if (unformat (i, "local"))
15309         is_local = 1;
15310       else if (unformat (i, "remote"))
15311         is_local = 0;
15312       else
15313         {
15314           errmsg ("parse error '%U'", format_unformat_error, i);
15315           return -99;
15316         }
15317     }
15318
15319   if (!vec_len (name))
15320     {
15321       errmsg ("profile name must be specified");
15322       return -99;
15323     }
15324
15325   if (vec_len (name) > 64)
15326     {
15327       errmsg ("profile name too long");
15328       return -99;
15329     }
15330
15331   M (IKEV2_PROFILE_SET_TS, mp);
15332
15333   mp->is_local = is_local;
15334   mp->proto = (u8) proto;
15335   mp->start_port = (u16) start_port;
15336   mp->end_port = (u16) end_port;
15337   mp->start_addr = start_addr.as_u32;
15338   mp->end_addr = end_addr.as_u32;
15339   clib_memcpy (mp->name, name, vec_len (name));
15340   vec_free (name);
15341
15342   S (mp);
15343   W (ret);
15344   return ret;
15345 }
15346
15347 static int
15348 api_ikev2_set_local_key (vat_main_t * vam)
15349 {
15350   unformat_input_t *i = vam->input;
15351   vl_api_ikev2_set_local_key_t *mp;
15352   u8 *file = 0;
15353   int ret;
15354
15355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat (i, "file %v", &file))
15358         vec_add1 (file, 0);
15359       else
15360         {
15361           errmsg ("parse error '%U'", format_unformat_error, i);
15362           return -99;
15363         }
15364     }
15365
15366   if (!vec_len (file))
15367     {
15368       errmsg ("RSA key file must be specified");
15369       return -99;
15370     }
15371
15372   if (vec_len (file) > 256)
15373     {
15374       errmsg ("file name too long");
15375       return -99;
15376     }
15377
15378   M (IKEV2_SET_LOCAL_KEY, mp);
15379
15380   clib_memcpy (mp->key_file, file, vec_len (file));
15381   vec_free (file);
15382
15383   S (mp);
15384   W (ret);
15385   return ret;
15386 }
15387
15388 static int
15389 api_ikev2_set_responder (vat_main_t * vam)
15390 {
15391   unformat_input_t *i = vam->input;
15392   vl_api_ikev2_set_responder_t *mp;
15393   int ret;
15394   u8 *name = 0;
15395   u32 sw_if_index = ~0;
15396   ip4_address_t address;
15397
15398   const char *valid_chars = "a-zA-Z0-9_";
15399
15400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15401     {
15402       if (unformat
15403           (i, "%U interface %d address %U", unformat_token, valid_chars,
15404            &name, &sw_if_index, unformat_ip4_address, &address))
15405         vec_add1 (name, 0);
15406       else
15407         {
15408           errmsg ("parse error '%U'", format_unformat_error, i);
15409           return -99;
15410         }
15411     }
15412
15413   if (!vec_len (name))
15414     {
15415       errmsg ("profile name must be specified");
15416       return -99;
15417     }
15418
15419   if (vec_len (name) > 64)
15420     {
15421       errmsg ("profile name too long");
15422       return -99;
15423     }
15424
15425   M (IKEV2_SET_RESPONDER, mp);
15426
15427   clib_memcpy (mp->name, name, vec_len (name));
15428   vec_free (name);
15429
15430   mp->sw_if_index = sw_if_index;
15431   clib_memcpy (mp->address, &address, sizeof (address));
15432
15433   S (mp);
15434   W (ret);
15435   return ret;
15436 }
15437
15438 static int
15439 api_ikev2_set_ike_transforms (vat_main_t * vam)
15440 {
15441   unformat_input_t *i = vam->input;
15442   vl_api_ikev2_set_ike_transforms_t *mp;
15443   int ret;
15444   u8 *name = 0;
15445   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15446
15447   const char *valid_chars = "a-zA-Z0-9_";
15448
15449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15450     {
15451       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15452                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15453         vec_add1 (name, 0);
15454       else
15455         {
15456           errmsg ("parse error '%U'", format_unformat_error, i);
15457           return -99;
15458         }
15459     }
15460
15461   if (!vec_len (name))
15462     {
15463       errmsg ("profile name must be specified");
15464       return -99;
15465     }
15466
15467   if (vec_len (name) > 64)
15468     {
15469       errmsg ("profile name too long");
15470       return -99;
15471     }
15472
15473   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15474
15475   clib_memcpy (mp->name, name, vec_len (name));
15476   vec_free (name);
15477   mp->crypto_alg = crypto_alg;
15478   mp->crypto_key_size = crypto_key_size;
15479   mp->integ_alg = integ_alg;
15480   mp->dh_group = dh_group;
15481
15482   S (mp);
15483   W (ret);
15484   return ret;
15485 }
15486
15487
15488 static int
15489 api_ikev2_set_esp_transforms (vat_main_t * vam)
15490 {
15491   unformat_input_t *i = vam->input;
15492   vl_api_ikev2_set_esp_transforms_t *mp;
15493   int ret;
15494   u8 *name = 0;
15495   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15496
15497   const char *valid_chars = "a-zA-Z0-9_";
15498
15499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15500     {
15501       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15502                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15503         vec_add1 (name, 0);
15504       else
15505         {
15506           errmsg ("parse error '%U'", format_unformat_error, i);
15507           return -99;
15508         }
15509     }
15510
15511   if (!vec_len (name))
15512     {
15513       errmsg ("profile name must be specified");
15514       return -99;
15515     }
15516
15517   if (vec_len (name) > 64)
15518     {
15519       errmsg ("profile name too long");
15520       return -99;
15521     }
15522
15523   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15524
15525   clib_memcpy (mp->name, name, vec_len (name));
15526   vec_free (name);
15527   mp->crypto_alg = crypto_alg;
15528   mp->crypto_key_size = crypto_key_size;
15529   mp->integ_alg = integ_alg;
15530   mp->dh_group = dh_group;
15531
15532   S (mp);
15533   W (ret);
15534   return ret;
15535 }
15536
15537 static int
15538 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15539 {
15540   unformat_input_t *i = vam->input;
15541   vl_api_ikev2_set_sa_lifetime_t *mp;
15542   int ret;
15543   u8 *name = 0;
15544   u64 lifetime, lifetime_maxdata;
15545   u32 lifetime_jitter, handover;
15546
15547   const char *valid_chars = "a-zA-Z0-9_";
15548
15549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15552                     &lifetime, &lifetime_jitter, &handover,
15553                     &lifetime_maxdata))
15554         vec_add1 (name, 0);
15555       else
15556         {
15557           errmsg ("parse error '%U'", format_unformat_error, i);
15558           return -99;
15559         }
15560     }
15561
15562   if (!vec_len (name))
15563     {
15564       errmsg ("profile name must be specified");
15565       return -99;
15566     }
15567
15568   if (vec_len (name) > 64)
15569     {
15570       errmsg ("profile name too long");
15571       return -99;
15572     }
15573
15574   M (IKEV2_SET_SA_LIFETIME, mp);
15575
15576   clib_memcpy (mp->name, name, vec_len (name));
15577   vec_free (name);
15578   mp->lifetime = lifetime;
15579   mp->lifetime_jitter = lifetime_jitter;
15580   mp->handover = handover;
15581   mp->lifetime_maxdata = lifetime_maxdata;
15582
15583   S (mp);
15584   W (ret);
15585   return ret;
15586 }
15587
15588 static int
15589 api_ikev2_initiate_sa_init (vat_main_t * vam)
15590 {
15591   unformat_input_t *i = vam->input;
15592   vl_api_ikev2_initiate_sa_init_t *mp;
15593   int ret;
15594   u8 *name = 0;
15595
15596   const char *valid_chars = "a-zA-Z0-9_";
15597
15598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15599     {
15600       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15601         vec_add1 (name, 0);
15602       else
15603         {
15604           errmsg ("parse error '%U'", format_unformat_error, i);
15605           return -99;
15606         }
15607     }
15608
15609   if (!vec_len (name))
15610     {
15611       errmsg ("profile name must be specified");
15612       return -99;
15613     }
15614
15615   if (vec_len (name) > 64)
15616     {
15617       errmsg ("profile name too long");
15618       return -99;
15619     }
15620
15621   M (IKEV2_INITIATE_SA_INIT, mp);
15622
15623   clib_memcpy (mp->name, name, vec_len (name));
15624   vec_free (name);
15625
15626   S (mp);
15627   W (ret);
15628   return ret;
15629 }
15630
15631 static int
15632 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15633 {
15634   unformat_input_t *i = vam->input;
15635   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15636   int ret;
15637   u64 ispi;
15638
15639
15640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15641     {
15642       if (unformat (i, "%lx", &ispi))
15643         ;
15644       else
15645         {
15646           errmsg ("parse error '%U'", format_unformat_error, i);
15647           return -99;
15648         }
15649     }
15650
15651   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15652
15653   mp->ispi = ispi;
15654
15655   S (mp);
15656   W (ret);
15657   return ret;
15658 }
15659
15660 static int
15661 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15662 {
15663   unformat_input_t *i = vam->input;
15664   vl_api_ikev2_initiate_del_child_sa_t *mp;
15665   int ret;
15666   u32 ispi;
15667
15668
15669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (i, "%x", &ispi))
15672         ;
15673       else
15674         {
15675           errmsg ("parse error '%U'", format_unformat_error, i);
15676           return -99;
15677         }
15678     }
15679
15680   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15681
15682   mp->ispi = ispi;
15683
15684   S (mp);
15685   W (ret);
15686   return ret;
15687 }
15688
15689 static int
15690 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15691 {
15692   unformat_input_t *i = vam->input;
15693   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15694   int ret;
15695   u32 ispi;
15696
15697
15698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15699     {
15700       if (unformat (i, "%x", &ispi))
15701         ;
15702       else
15703         {
15704           errmsg ("parse error '%U'", format_unformat_error, i);
15705           return -99;
15706         }
15707     }
15708
15709   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15710
15711   mp->ispi = ispi;
15712
15713   S (mp);
15714   W (ret);
15715   return ret;
15716 }
15717
15718 /*
15719  * MAP
15720  */
15721 static int
15722 api_map_add_domain (vat_main_t * vam)
15723 {
15724   unformat_input_t *i = vam->input;
15725   vl_api_map_add_domain_t *mp;
15726
15727   ip4_address_t ip4_prefix;
15728   ip6_address_t ip6_prefix;
15729   ip6_address_t ip6_src;
15730   u32 num_m_args = 0;
15731   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15732     0, psid_length = 0;
15733   u8 is_translation = 0;
15734   u32 mtu = 0;
15735   u32 ip6_src_len = 128;
15736   int ret;
15737
15738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15739     {
15740       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15741                     &ip4_prefix, &ip4_prefix_len))
15742         num_m_args++;
15743       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15744                          &ip6_prefix, &ip6_prefix_len))
15745         num_m_args++;
15746       else
15747         if (unformat
15748             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15749              &ip6_src_len))
15750         num_m_args++;
15751       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15752         num_m_args++;
15753       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15754         num_m_args++;
15755       else if (unformat (i, "psid-offset %d", &psid_offset))
15756         num_m_args++;
15757       else if (unformat (i, "psid-len %d", &psid_length))
15758         num_m_args++;
15759       else if (unformat (i, "mtu %d", &mtu))
15760         num_m_args++;
15761       else if (unformat (i, "map-t"))
15762         is_translation = 1;
15763       else
15764         {
15765           clib_warning ("parse error '%U'", format_unformat_error, i);
15766           return -99;
15767         }
15768     }
15769
15770   if (num_m_args < 3)
15771     {
15772       errmsg ("mandatory argument(s) missing");
15773       return -99;
15774     }
15775
15776   /* Construct the API message */
15777   M (MAP_ADD_DOMAIN, mp);
15778
15779   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15780   mp->ip4_prefix_len = ip4_prefix_len;
15781
15782   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15783   mp->ip6_prefix_len = ip6_prefix_len;
15784
15785   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15786   mp->ip6_src_prefix_len = ip6_src_len;
15787
15788   mp->ea_bits_len = ea_bits_len;
15789   mp->psid_offset = psid_offset;
15790   mp->psid_length = psid_length;
15791   mp->is_translation = is_translation;
15792   mp->mtu = htons (mtu);
15793
15794   /* send it... */
15795   S (mp);
15796
15797   /* Wait for a reply, return good/bad news  */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 static int
15803 api_map_del_domain (vat_main_t * vam)
15804 {
15805   unformat_input_t *i = vam->input;
15806   vl_api_map_del_domain_t *mp;
15807
15808   u32 num_m_args = 0;
15809   u32 index;
15810   int ret;
15811
15812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15813     {
15814       if (unformat (i, "index %d", &index))
15815         num_m_args++;
15816       else
15817         {
15818           clib_warning ("parse error '%U'", format_unformat_error, i);
15819           return -99;
15820         }
15821     }
15822
15823   if (num_m_args != 1)
15824     {
15825       errmsg ("mandatory argument(s) missing");
15826       return -99;
15827     }
15828
15829   /* Construct the API message */
15830   M (MAP_DEL_DOMAIN, mp);
15831
15832   mp->index = ntohl (index);
15833
15834   /* send it... */
15835   S (mp);
15836
15837   /* Wait for a reply, return good/bad news  */
15838   W (ret);
15839   return ret;
15840 }
15841
15842 static int
15843 api_map_add_del_rule (vat_main_t * vam)
15844 {
15845   unformat_input_t *i = vam->input;
15846   vl_api_map_add_del_rule_t *mp;
15847   u8 is_add = 1;
15848   ip6_address_t ip6_dst;
15849   u32 num_m_args = 0, index, psid = 0;
15850   int ret;
15851
15852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15853     {
15854       if (unformat (i, "index %d", &index))
15855         num_m_args++;
15856       else if (unformat (i, "psid %d", &psid))
15857         num_m_args++;
15858       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15859         num_m_args++;
15860       else if (unformat (i, "del"))
15861         {
15862           is_add = 0;
15863         }
15864       else
15865         {
15866           clib_warning ("parse error '%U'", format_unformat_error, i);
15867           return -99;
15868         }
15869     }
15870
15871   /* Construct the API message */
15872   M (MAP_ADD_DEL_RULE, mp);
15873
15874   mp->index = ntohl (index);
15875   mp->is_add = is_add;
15876   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15877   mp->psid = ntohs (psid);
15878
15879   /* send it... */
15880   S (mp);
15881
15882   /* Wait for a reply, return good/bad news  */
15883   W (ret);
15884   return ret;
15885 }
15886
15887 static int
15888 api_map_domain_dump (vat_main_t * vam)
15889 {
15890   vl_api_map_domain_dump_t *mp;
15891   vl_api_control_ping_t *mp_ping;
15892   int ret;
15893
15894   /* Construct the API message */
15895   M (MAP_DOMAIN_DUMP, mp);
15896
15897   /* send it... */
15898   S (mp);
15899
15900   /* Use a control ping for synchronization */
15901   MPING (CONTROL_PING, mp_ping);
15902   S (mp_ping);
15903
15904   W (ret);
15905   return ret;
15906 }
15907
15908 static int
15909 api_map_rule_dump (vat_main_t * vam)
15910 {
15911   unformat_input_t *i = vam->input;
15912   vl_api_map_rule_dump_t *mp;
15913   vl_api_control_ping_t *mp_ping;
15914   u32 domain_index = ~0;
15915   int ret;
15916
15917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15918     {
15919       if (unformat (i, "index %u", &domain_index))
15920         ;
15921       else
15922         break;
15923     }
15924
15925   if (domain_index == ~0)
15926     {
15927       clib_warning ("parse error: domain index expected");
15928       return -99;
15929     }
15930
15931   /* Construct the API message */
15932   M (MAP_RULE_DUMP, mp);
15933
15934   mp->domain_index = htonl (domain_index);
15935
15936   /* send it... */
15937   S (mp);
15938
15939   /* Use a control ping for synchronization */
15940   MPING (CONTROL_PING, mp_ping);
15941   S (mp_ping);
15942
15943   W (ret);
15944   return ret;
15945 }
15946
15947 static void vl_api_map_add_domain_reply_t_handler
15948   (vl_api_map_add_domain_reply_t * mp)
15949 {
15950   vat_main_t *vam = &vat_main;
15951   i32 retval = ntohl (mp->retval);
15952
15953   if (vam->async_mode)
15954     {
15955       vam->async_errors += (retval < 0);
15956     }
15957   else
15958     {
15959       vam->retval = retval;
15960       vam->result_ready = 1;
15961     }
15962 }
15963
15964 static void vl_api_map_add_domain_reply_t_handler_json
15965   (vl_api_map_add_domain_reply_t * mp)
15966 {
15967   vat_main_t *vam = &vat_main;
15968   vat_json_node_t node;
15969
15970   vat_json_init_object (&node);
15971   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15972   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15973
15974   vat_json_print (vam->ofp, &node);
15975   vat_json_free (&node);
15976
15977   vam->retval = ntohl (mp->retval);
15978   vam->result_ready = 1;
15979 }
15980
15981 static int
15982 api_get_first_msg_id (vat_main_t * vam)
15983 {
15984   vl_api_get_first_msg_id_t *mp;
15985   unformat_input_t *i = vam->input;
15986   u8 *name;
15987   u8 name_set = 0;
15988   int ret;
15989
15990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15991     {
15992       if (unformat (i, "client %s", &name))
15993         name_set = 1;
15994       else
15995         break;
15996     }
15997
15998   if (name_set == 0)
15999     {
16000       errmsg ("missing client name");
16001       return -99;
16002     }
16003   vec_add1 (name, 0);
16004
16005   if (vec_len (name) > 63)
16006     {
16007       errmsg ("client name too long");
16008       return -99;
16009     }
16010
16011   M (GET_FIRST_MSG_ID, mp);
16012   clib_memcpy (mp->name, name, vec_len (name));
16013   S (mp);
16014   W (ret);
16015   return ret;
16016 }
16017
16018 static int
16019 api_cop_interface_enable_disable (vat_main_t * vam)
16020 {
16021   unformat_input_t *line_input = vam->input;
16022   vl_api_cop_interface_enable_disable_t *mp;
16023   u32 sw_if_index = ~0;
16024   u8 enable_disable = 1;
16025   int ret;
16026
16027   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16028     {
16029       if (unformat (line_input, "disable"))
16030         enable_disable = 0;
16031       if (unformat (line_input, "enable"))
16032         enable_disable = 1;
16033       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16034                          vam, &sw_if_index))
16035         ;
16036       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16037         ;
16038       else
16039         break;
16040     }
16041
16042   if (sw_if_index == ~0)
16043     {
16044       errmsg ("missing interface name or sw_if_index");
16045       return -99;
16046     }
16047
16048   /* Construct the API message */
16049   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16050   mp->sw_if_index = ntohl (sw_if_index);
16051   mp->enable_disable = enable_disable;
16052
16053   /* send it... */
16054   S (mp);
16055   /* Wait for the reply */
16056   W (ret);
16057   return ret;
16058 }
16059
16060 static int
16061 api_cop_whitelist_enable_disable (vat_main_t * vam)
16062 {
16063   unformat_input_t *line_input = vam->input;
16064   vl_api_cop_whitelist_enable_disable_t *mp;
16065   u32 sw_if_index = ~0;
16066   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16067   u32 fib_id = 0;
16068   int ret;
16069
16070   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16071     {
16072       if (unformat (line_input, "ip4"))
16073         ip4 = 1;
16074       else if (unformat (line_input, "ip6"))
16075         ip6 = 1;
16076       else if (unformat (line_input, "default"))
16077         default_cop = 1;
16078       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16079                          vam, &sw_if_index))
16080         ;
16081       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16082         ;
16083       else if (unformat (line_input, "fib-id %d", &fib_id))
16084         ;
16085       else
16086         break;
16087     }
16088
16089   if (sw_if_index == ~0)
16090     {
16091       errmsg ("missing interface name or sw_if_index");
16092       return -99;
16093     }
16094
16095   /* Construct the API message */
16096   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16097   mp->sw_if_index = ntohl (sw_if_index);
16098   mp->fib_id = ntohl (fib_id);
16099   mp->ip4 = ip4;
16100   mp->ip6 = ip6;
16101   mp->default_cop = default_cop;
16102
16103   /* send it... */
16104   S (mp);
16105   /* Wait for the reply */
16106   W (ret);
16107   return ret;
16108 }
16109
16110 static int
16111 api_get_node_graph (vat_main_t * vam)
16112 {
16113   vl_api_get_node_graph_t *mp;
16114   int ret;
16115
16116   M (GET_NODE_GRAPH, mp);
16117
16118   /* send it... */
16119   S (mp);
16120   /* Wait for the reply */
16121   W (ret);
16122   return ret;
16123 }
16124
16125 /* *INDENT-OFF* */
16126 /** Used for parsing LISP eids */
16127 typedef CLIB_PACKED(struct{
16128   u8 addr[16];   /**< eid address */
16129   u32 len;       /**< prefix length if IP */
16130   u8 type;      /**< type of eid */
16131 }) lisp_eid_vat_t;
16132 /* *INDENT-ON* */
16133
16134 static uword
16135 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16136 {
16137   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16138
16139   memset (a, 0, sizeof (a[0]));
16140
16141   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16142     {
16143       a->type = 0;              /* ipv4 type */
16144     }
16145   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16146     {
16147       a->type = 1;              /* ipv6 type */
16148     }
16149   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16150     {
16151       a->type = 2;              /* mac type */
16152     }
16153   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16154     {
16155       a->type = 3;              /* NSH type */
16156       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16157       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16158     }
16159   else
16160     {
16161       return 0;
16162     }
16163
16164   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16165     {
16166       return 0;
16167     }
16168
16169   return 1;
16170 }
16171
16172 static int
16173 lisp_eid_size_vat (u8 type)
16174 {
16175   switch (type)
16176     {
16177     case 0:
16178       return 4;
16179     case 1:
16180       return 16;
16181     case 2:
16182       return 6;
16183     case 3:
16184       return 5;
16185     }
16186   return 0;
16187 }
16188
16189 static void
16190 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16191 {
16192   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16193 }
16194
16195 static int
16196 api_one_add_del_locator_set (vat_main_t * vam)
16197 {
16198   unformat_input_t *input = vam->input;
16199   vl_api_one_add_del_locator_set_t *mp;
16200   u8 is_add = 1;
16201   u8 *locator_set_name = NULL;
16202   u8 locator_set_name_set = 0;
16203   vl_api_local_locator_t locator, *locators = 0;
16204   u32 sw_if_index, priority, weight;
16205   u32 data_len = 0;
16206
16207   int ret;
16208   /* Parse args required to build the message */
16209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16210     {
16211       if (unformat (input, "del"))
16212         {
16213           is_add = 0;
16214         }
16215       else if (unformat (input, "locator-set %s", &locator_set_name))
16216         {
16217           locator_set_name_set = 1;
16218         }
16219       else if (unformat (input, "sw_if_index %u p %u w %u",
16220                          &sw_if_index, &priority, &weight))
16221         {
16222           locator.sw_if_index = htonl (sw_if_index);
16223           locator.priority = priority;
16224           locator.weight = weight;
16225           vec_add1 (locators, locator);
16226         }
16227       else
16228         if (unformat
16229             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16230              &sw_if_index, &priority, &weight))
16231         {
16232           locator.sw_if_index = htonl (sw_if_index);
16233           locator.priority = priority;
16234           locator.weight = weight;
16235           vec_add1 (locators, locator);
16236         }
16237       else
16238         break;
16239     }
16240
16241   if (locator_set_name_set == 0)
16242     {
16243       errmsg ("missing locator-set name");
16244       vec_free (locators);
16245       return -99;
16246     }
16247
16248   if (vec_len (locator_set_name) > 64)
16249     {
16250       errmsg ("locator-set name too long");
16251       vec_free (locator_set_name);
16252       vec_free (locators);
16253       return -99;
16254     }
16255   vec_add1 (locator_set_name, 0);
16256
16257   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16258
16259   /* Construct the API message */
16260   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16261
16262   mp->is_add = is_add;
16263   clib_memcpy (mp->locator_set_name, locator_set_name,
16264                vec_len (locator_set_name));
16265   vec_free (locator_set_name);
16266
16267   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16268   if (locators)
16269     clib_memcpy (mp->locators, locators, data_len);
16270   vec_free (locators);
16271
16272   /* send it... */
16273   S (mp);
16274
16275   /* Wait for a reply... */
16276   W (ret);
16277   return ret;
16278 }
16279
16280 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16281
16282 static int
16283 api_one_add_del_locator (vat_main_t * vam)
16284 {
16285   unformat_input_t *input = vam->input;
16286   vl_api_one_add_del_locator_t *mp;
16287   u32 tmp_if_index = ~0;
16288   u32 sw_if_index = ~0;
16289   u8 sw_if_index_set = 0;
16290   u8 sw_if_index_if_name_set = 0;
16291   u32 priority = ~0;
16292   u8 priority_set = 0;
16293   u32 weight = ~0;
16294   u8 weight_set = 0;
16295   u8 is_add = 1;
16296   u8 *locator_set_name = NULL;
16297   u8 locator_set_name_set = 0;
16298   int ret;
16299
16300   /* Parse args required to build the message */
16301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16302     {
16303       if (unformat (input, "del"))
16304         {
16305           is_add = 0;
16306         }
16307       else if (unformat (input, "locator-set %s", &locator_set_name))
16308         {
16309           locator_set_name_set = 1;
16310         }
16311       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16312                          &tmp_if_index))
16313         {
16314           sw_if_index_if_name_set = 1;
16315           sw_if_index = tmp_if_index;
16316         }
16317       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16318         {
16319           sw_if_index_set = 1;
16320           sw_if_index = tmp_if_index;
16321         }
16322       else if (unformat (input, "p %d", &priority))
16323         {
16324           priority_set = 1;
16325         }
16326       else if (unformat (input, "w %d", &weight))
16327         {
16328           weight_set = 1;
16329         }
16330       else
16331         break;
16332     }
16333
16334   if (locator_set_name_set == 0)
16335     {
16336       errmsg ("missing locator-set name");
16337       return -99;
16338     }
16339
16340   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16341     {
16342       errmsg ("missing sw_if_index");
16343       vec_free (locator_set_name);
16344       return -99;
16345     }
16346
16347   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16348     {
16349       errmsg ("cannot use both params interface name and sw_if_index");
16350       vec_free (locator_set_name);
16351       return -99;
16352     }
16353
16354   if (priority_set == 0)
16355     {
16356       errmsg ("missing locator-set priority");
16357       vec_free (locator_set_name);
16358       return -99;
16359     }
16360
16361   if (weight_set == 0)
16362     {
16363       errmsg ("missing locator-set weight");
16364       vec_free (locator_set_name);
16365       return -99;
16366     }
16367
16368   if (vec_len (locator_set_name) > 64)
16369     {
16370       errmsg ("locator-set name too long");
16371       vec_free (locator_set_name);
16372       return -99;
16373     }
16374   vec_add1 (locator_set_name, 0);
16375
16376   /* Construct the API message */
16377   M (ONE_ADD_DEL_LOCATOR, mp);
16378
16379   mp->is_add = is_add;
16380   mp->sw_if_index = ntohl (sw_if_index);
16381   mp->priority = priority;
16382   mp->weight = weight;
16383   clib_memcpy (mp->locator_set_name, locator_set_name,
16384                vec_len (locator_set_name));
16385   vec_free (locator_set_name);
16386
16387   /* send it... */
16388   S (mp);
16389
16390   /* Wait for a reply... */
16391   W (ret);
16392   return ret;
16393 }
16394
16395 #define api_lisp_add_del_locator api_one_add_del_locator
16396
16397 uword
16398 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16399 {
16400   u32 *key_id = va_arg (*args, u32 *);
16401   u8 *s = 0;
16402
16403   if (unformat (input, "%s", &s))
16404     {
16405       if (!strcmp ((char *) s, "sha1"))
16406         key_id[0] = HMAC_SHA_1_96;
16407       else if (!strcmp ((char *) s, "sha256"))
16408         key_id[0] = HMAC_SHA_256_128;
16409       else
16410         {
16411           clib_warning ("invalid key_id: '%s'", s);
16412           key_id[0] = HMAC_NO_KEY;
16413         }
16414     }
16415   else
16416     return 0;
16417
16418   vec_free (s);
16419   return 1;
16420 }
16421
16422 static int
16423 api_one_add_del_local_eid (vat_main_t * vam)
16424 {
16425   unformat_input_t *input = vam->input;
16426   vl_api_one_add_del_local_eid_t *mp;
16427   u8 is_add = 1;
16428   u8 eid_set = 0;
16429   lisp_eid_vat_t _eid, *eid = &_eid;
16430   u8 *locator_set_name = 0;
16431   u8 locator_set_name_set = 0;
16432   u32 vni = 0;
16433   u16 key_id = 0;
16434   u8 *key = 0;
16435   int ret;
16436
16437   /* Parse args required to build the message */
16438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16439     {
16440       if (unformat (input, "del"))
16441         {
16442           is_add = 0;
16443         }
16444       else if (unformat (input, "vni %d", &vni))
16445         {
16446           ;
16447         }
16448       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16449         {
16450           eid_set = 1;
16451         }
16452       else if (unformat (input, "locator-set %s", &locator_set_name))
16453         {
16454           locator_set_name_set = 1;
16455         }
16456       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16457         ;
16458       else if (unformat (input, "secret-key %_%v%_", &key))
16459         ;
16460       else
16461         break;
16462     }
16463
16464   if (locator_set_name_set == 0)
16465     {
16466       errmsg ("missing locator-set name");
16467       return -99;
16468     }
16469
16470   if (0 == eid_set)
16471     {
16472       errmsg ("EID address not set!");
16473       vec_free (locator_set_name);
16474       return -99;
16475     }
16476
16477   if (key && (0 == key_id))
16478     {
16479       errmsg ("invalid key_id!");
16480       return -99;
16481     }
16482
16483   if (vec_len (key) > 64)
16484     {
16485       errmsg ("key too long");
16486       vec_free (key);
16487       return -99;
16488     }
16489
16490   if (vec_len (locator_set_name) > 64)
16491     {
16492       errmsg ("locator-set name too long");
16493       vec_free (locator_set_name);
16494       return -99;
16495     }
16496   vec_add1 (locator_set_name, 0);
16497
16498   /* Construct the API message */
16499   M (ONE_ADD_DEL_LOCAL_EID, mp);
16500
16501   mp->is_add = is_add;
16502   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16503   mp->eid_type = eid->type;
16504   mp->prefix_len = eid->len;
16505   mp->vni = clib_host_to_net_u32 (vni);
16506   mp->key_id = clib_host_to_net_u16 (key_id);
16507   clib_memcpy (mp->locator_set_name, locator_set_name,
16508                vec_len (locator_set_name));
16509   clib_memcpy (mp->key, key, vec_len (key));
16510
16511   vec_free (locator_set_name);
16512   vec_free (key);
16513
16514   /* send it... */
16515   S (mp);
16516
16517   /* Wait for a reply... */
16518   W (ret);
16519   return ret;
16520 }
16521
16522 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16523
16524 static int
16525 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16526 {
16527   u32 dp_table = 0, vni = 0;;
16528   unformat_input_t *input = vam->input;
16529   vl_api_gpe_add_del_fwd_entry_t *mp;
16530   u8 is_add = 1;
16531   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16532   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16533   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16534   u32 action = ~0, w;
16535   ip4_address_t rmt_rloc4, lcl_rloc4;
16536   ip6_address_t rmt_rloc6, lcl_rloc6;
16537   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16538   int ret;
16539
16540   memset (&rloc, 0, sizeof (rloc));
16541
16542   /* Parse args required to build the message */
16543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16544     {
16545       if (unformat (input, "del"))
16546         is_add = 0;
16547       else if (unformat (input, "add"))
16548         is_add = 1;
16549       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16550         {
16551           rmt_eid_set = 1;
16552         }
16553       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16554         {
16555           lcl_eid_set = 1;
16556         }
16557       else if (unformat (input, "vrf %d", &dp_table))
16558         ;
16559       else if (unformat (input, "bd %d", &dp_table))
16560         ;
16561       else if (unformat (input, "vni %d", &vni))
16562         ;
16563       else if (unformat (input, "w %d", &w))
16564         {
16565           if (!curr_rloc)
16566             {
16567               errmsg ("No RLOC configured for setting priority/weight!");
16568               return -99;
16569             }
16570           curr_rloc->weight = w;
16571         }
16572       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16573                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16574         {
16575           rloc.is_ip4 = 1;
16576
16577           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16578           rloc.weight = 0;
16579           vec_add1 (lcl_locs, rloc);
16580
16581           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16582           vec_add1 (rmt_locs, rloc);
16583           /* weight saved in rmt loc */
16584           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16585         }
16586       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16587                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16588         {
16589           rloc.is_ip4 = 0;
16590           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16591           rloc.weight = 0;
16592           vec_add1 (lcl_locs, rloc);
16593
16594           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16595           vec_add1 (rmt_locs, rloc);
16596           /* weight saved in rmt loc */
16597           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16598         }
16599       else if (unformat (input, "action %d", &action))
16600         {
16601           ;
16602         }
16603       else
16604         {
16605           clib_warning ("parse error '%U'", format_unformat_error, input);
16606           return -99;
16607         }
16608     }
16609
16610   if (!rmt_eid_set)
16611     {
16612       errmsg ("remote eid addresses not set");
16613       return -99;
16614     }
16615
16616   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16617     {
16618       errmsg ("eid types don't match");
16619       return -99;
16620     }
16621
16622   if (0 == rmt_locs && (u32) ~ 0 == action)
16623     {
16624       errmsg ("action not set for negative mapping");
16625       return -99;
16626     }
16627
16628   /* Construct the API message */
16629   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16630       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16631
16632   mp->is_add = is_add;
16633   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16634   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16635   mp->eid_type = rmt_eid->type;
16636   mp->dp_table = clib_host_to_net_u32 (dp_table);
16637   mp->vni = clib_host_to_net_u32 (vni);
16638   mp->rmt_len = rmt_eid->len;
16639   mp->lcl_len = lcl_eid->len;
16640   mp->action = action;
16641
16642   if (0 != rmt_locs && 0 != lcl_locs)
16643     {
16644       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16645       clib_memcpy (mp->locs, lcl_locs,
16646                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16647
16648       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16649       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16650                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16651     }
16652   vec_free (lcl_locs);
16653   vec_free (rmt_locs);
16654
16655   /* send it... */
16656   S (mp);
16657
16658   /* Wait for a reply... */
16659   W (ret);
16660   return ret;
16661 }
16662
16663 static int
16664 api_one_add_del_map_server (vat_main_t * vam)
16665 {
16666   unformat_input_t *input = vam->input;
16667   vl_api_one_add_del_map_server_t *mp;
16668   u8 is_add = 1;
16669   u8 ipv4_set = 0;
16670   u8 ipv6_set = 0;
16671   ip4_address_t ipv4;
16672   ip6_address_t ipv6;
16673   int ret;
16674
16675   /* Parse args required to build the message */
16676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16677     {
16678       if (unformat (input, "del"))
16679         {
16680           is_add = 0;
16681         }
16682       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16683         {
16684           ipv4_set = 1;
16685         }
16686       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16687         {
16688           ipv6_set = 1;
16689         }
16690       else
16691         break;
16692     }
16693
16694   if (ipv4_set && ipv6_set)
16695     {
16696       errmsg ("both eid v4 and v6 addresses set");
16697       return -99;
16698     }
16699
16700   if (!ipv4_set && !ipv6_set)
16701     {
16702       errmsg ("eid addresses not set");
16703       return -99;
16704     }
16705
16706   /* Construct the API message */
16707   M (ONE_ADD_DEL_MAP_SERVER, mp);
16708
16709   mp->is_add = is_add;
16710   if (ipv6_set)
16711     {
16712       mp->is_ipv6 = 1;
16713       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16714     }
16715   else
16716     {
16717       mp->is_ipv6 = 0;
16718       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16719     }
16720
16721   /* send it... */
16722   S (mp);
16723
16724   /* Wait for a reply... */
16725   W (ret);
16726   return ret;
16727 }
16728
16729 #define api_lisp_add_del_map_server api_one_add_del_map_server
16730
16731 static int
16732 api_one_add_del_map_resolver (vat_main_t * vam)
16733 {
16734   unformat_input_t *input = vam->input;
16735   vl_api_one_add_del_map_resolver_t *mp;
16736   u8 is_add = 1;
16737   u8 ipv4_set = 0;
16738   u8 ipv6_set = 0;
16739   ip4_address_t ipv4;
16740   ip6_address_t ipv6;
16741   int ret;
16742
16743   /* Parse args required to build the message */
16744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16745     {
16746       if (unformat (input, "del"))
16747         {
16748           is_add = 0;
16749         }
16750       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16751         {
16752           ipv4_set = 1;
16753         }
16754       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16755         {
16756           ipv6_set = 1;
16757         }
16758       else
16759         break;
16760     }
16761
16762   if (ipv4_set && ipv6_set)
16763     {
16764       errmsg ("both eid v4 and v6 addresses set");
16765       return -99;
16766     }
16767
16768   if (!ipv4_set && !ipv6_set)
16769     {
16770       errmsg ("eid addresses not set");
16771       return -99;
16772     }
16773
16774   /* Construct the API message */
16775   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16776
16777   mp->is_add = is_add;
16778   if (ipv6_set)
16779     {
16780       mp->is_ipv6 = 1;
16781       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16782     }
16783   else
16784     {
16785       mp->is_ipv6 = 0;
16786       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16787     }
16788
16789   /* send it... */
16790   S (mp);
16791
16792   /* Wait for a reply... */
16793   W (ret);
16794   return ret;
16795 }
16796
16797 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16798
16799 static int
16800 api_lisp_gpe_enable_disable (vat_main_t * vam)
16801 {
16802   unformat_input_t *input = vam->input;
16803   vl_api_gpe_enable_disable_t *mp;
16804   u8 is_set = 0;
16805   u8 is_en = 1;
16806   int ret;
16807
16808   /* Parse args required to build the message */
16809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16810     {
16811       if (unformat (input, "enable"))
16812         {
16813           is_set = 1;
16814           is_en = 1;
16815         }
16816       else if (unformat (input, "disable"))
16817         {
16818           is_set = 1;
16819           is_en = 0;
16820         }
16821       else
16822         break;
16823     }
16824
16825   if (is_set == 0)
16826     {
16827       errmsg ("Value not set");
16828       return -99;
16829     }
16830
16831   /* Construct the API message */
16832   M (GPE_ENABLE_DISABLE, mp);
16833
16834   mp->is_en = is_en;
16835
16836   /* send it... */
16837   S (mp);
16838
16839   /* Wait for a reply... */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 static int
16845 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16846 {
16847   unformat_input_t *input = vam->input;
16848   vl_api_one_rloc_probe_enable_disable_t *mp;
16849   u8 is_set = 0;
16850   u8 is_en = 0;
16851   int ret;
16852
16853   /* Parse args required to build the message */
16854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16855     {
16856       if (unformat (input, "enable"))
16857         {
16858           is_set = 1;
16859           is_en = 1;
16860         }
16861       else if (unformat (input, "disable"))
16862         is_set = 1;
16863       else
16864         break;
16865     }
16866
16867   if (!is_set)
16868     {
16869       errmsg ("Value not set");
16870       return -99;
16871     }
16872
16873   /* Construct the API message */
16874   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16875
16876   mp->is_enabled = is_en;
16877
16878   /* send it... */
16879   S (mp);
16880
16881   /* Wait for a reply... */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16887
16888 static int
16889 api_one_map_register_enable_disable (vat_main_t * vam)
16890 {
16891   unformat_input_t *input = vam->input;
16892   vl_api_one_map_register_enable_disable_t *mp;
16893   u8 is_set = 0;
16894   u8 is_en = 0;
16895   int ret;
16896
16897   /* Parse args required to build the message */
16898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16899     {
16900       if (unformat (input, "enable"))
16901         {
16902           is_set = 1;
16903           is_en = 1;
16904         }
16905       else if (unformat (input, "disable"))
16906         is_set = 1;
16907       else
16908         break;
16909     }
16910
16911   if (!is_set)
16912     {
16913       errmsg ("Value not set");
16914       return -99;
16915     }
16916
16917   /* Construct the API message */
16918   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16919
16920   mp->is_enabled = is_en;
16921
16922   /* send it... */
16923   S (mp);
16924
16925   /* Wait for a reply... */
16926   W (ret);
16927   return ret;
16928 }
16929
16930 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16931
16932 static int
16933 api_one_enable_disable (vat_main_t * vam)
16934 {
16935   unformat_input_t *input = vam->input;
16936   vl_api_one_enable_disable_t *mp;
16937   u8 is_set = 0;
16938   u8 is_en = 0;
16939   int ret;
16940
16941   /* Parse args required to build the message */
16942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16943     {
16944       if (unformat (input, "enable"))
16945         {
16946           is_set = 1;
16947           is_en = 1;
16948         }
16949       else if (unformat (input, "disable"))
16950         {
16951           is_set = 1;
16952         }
16953       else
16954         break;
16955     }
16956
16957   if (!is_set)
16958     {
16959       errmsg ("Value not set");
16960       return -99;
16961     }
16962
16963   /* Construct the API message */
16964   M (ONE_ENABLE_DISABLE, mp);
16965
16966   mp->is_en = is_en;
16967
16968   /* send it... */
16969   S (mp);
16970
16971   /* Wait for a reply... */
16972   W (ret);
16973   return ret;
16974 }
16975
16976 #define api_lisp_enable_disable api_one_enable_disable
16977
16978 static int
16979 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16980 {
16981   unformat_input_t *input = vam->input;
16982   vl_api_one_enable_disable_xtr_mode_t *mp;
16983   u8 is_set = 0;
16984   u8 is_en = 0;
16985   int ret;
16986
16987   /* Parse args required to build the message */
16988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16989     {
16990       if (unformat (input, "enable"))
16991         {
16992           is_set = 1;
16993           is_en = 1;
16994         }
16995       else if (unformat (input, "disable"))
16996         {
16997           is_set = 1;
16998         }
16999       else
17000         break;
17001     }
17002
17003   if (!is_set)
17004     {
17005       errmsg ("Value not set");
17006       return -99;
17007     }
17008
17009   /* Construct the API message */
17010   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17011
17012   mp->is_en = is_en;
17013
17014   /* send it... */
17015   S (mp);
17016
17017   /* Wait for a reply... */
17018   W (ret);
17019   return ret;
17020 }
17021
17022 static int
17023 api_one_show_xtr_mode (vat_main_t * vam)
17024 {
17025   vl_api_one_show_xtr_mode_t *mp;
17026   int ret;
17027
17028   /* Construct the API message */
17029   M (ONE_SHOW_XTR_MODE, mp);
17030
17031   /* send it... */
17032   S (mp);
17033
17034   /* Wait for a reply... */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 static int
17040 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17041 {
17042   unformat_input_t *input = vam->input;
17043   vl_api_one_enable_disable_pitr_mode_t *mp;
17044   u8 is_set = 0;
17045   u8 is_en = 0;
17046   int ret;
17047
17048   /* Parse args required to build the message */
17049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17050     {
17051       if (unformat (input, "enable"))
17052         {
17053           is_set = 1;
17054           is_en = 1;
17055         }
17056       else if (unformat (input, "disable"))
17057         {
17058           is_set = 1;
17059         }
17060       else
17061         break;
17062     }
17063
17064   if (!is_set)
17065     {
17066       errmsg ("Value not set");
17067       return -99;
17068     }
17069
17070   /* Construct the API message */
17071   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17072
17073   mp->is_en = is_en;
17074
17075   /* send it... */
17076   S (mp);
17077
17078   /* Wait for a reply... */
17079   W (ret);
17080   return ret;
17081 }
17082
17083 static int
17084 api_one_show_pitr_mode (vat_main_t * vam)
17085 {
17086   vl_api_one_show_pitr_mode_t *mp;
17087   int ret;
17088
17089   /* Construct the API message */
17090   M (ONE_SHOW_PITR_MODE, mp);
17091
17092   /* send it... */
17093   S (mp);
17094
17095   /* Wait for a reply... */
17096   W (ret);
17097   return ret;
17098 }
17099
17100 static int
17101 api_one_enable_disable_petr_mode (vat_main_t * vam)
17102 {
17103   unformat_input_t *input = vam->input;
17104   vl_api_one_enable_disable_petr_mode_t *mp;
17105   u8 is_set = 0;
17106   u8 is_en = 0;
17107   int ret;
17108
17109   /* Parse args required to build the message */
17110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17111     {
17112       if (unformat (input, "enable"))
17113         {
17114           is_set = 1;
17115           is_en = 1;
17116         }
17117       else if (unformat (input, "disable"))
17118         {
17119           is_set = 1;
17120         }
17121       else
17122         break;
17123     }
17124
17125   if (!is_set)
17126     {
17127       errmsg ("Value not set");
17128       return -99;
17129     }
17130
17131   /* Construct the API message */
17132   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17133
17134   mp->is_en = is_en;
17135
17136   /* send it... */
17137   S (mp);
17138
17139   /* Wait for a reply... */
17140   W (ret);
17141   return ret;
17142 }
17143
17144 static int
17145 api_one_show_petr_mode (vat_main_t * vam)
17146 {
17147   vl_api_one_show_petr_mode_t *mp;
17148   int ret;
17149
17150   /* Construct the API message */
17151   M (ONE_SHOW_PETR_MODE, mp);
17152
17153   /* send it... */
17154   S (mp);
17155
17156   /* Wait for a reply... */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static int
17162 api_show_one_map_register_state (vat_main_t * vam)
17163 {
17164   vl_api_show_one_map_register_state_t *mp;
17165   int ret;
17166
17167   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17168
17169   /* send */
17170   S (mp);
17171
17172   /* wait for reply */
17173   W (ret);
17174   return ret;
17175 }
17176
17177 #define api_show_lisp_map_register_state api_show_one_map_register_state
17178
17179 static int
17180 api_show_one_rloc_probe_state (vat_main_t * vam)
17181 {
17182   vl_api_show_one_rloc_probe_state_t *mp;
17183   int ret;
17184
17185   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17186
17187   /* send */
17188   S (mp);
17189
17190   /* wait for reply */
17191   W (ret);
17192   return ret;
17193 }
17194
17195 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17196
17197 static int
17198 api_one_add_del_ndp_entry (vat_main_t * vam)
17199 {
17200   vl_api_one_add_del_ndp_entry_t *mp;
17201   unformat_input_t *input = vam->input;
17202   u8 is_add = 1;
17203   u8 mac_set = 0;
17204   u8 bd_set = 0;
17205   u8 ip_set = 0;
17206   u8 mac[6] = { 0, };
17207   u8 ip6[16] = { 0, };
17208   u32 bd = ~0;
17209   int ret;
17210
17211   /* Parse args required to build the message */
17212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17213     {
17214       if (unformat (input, "del"))
17215         is_add = 0;
17216       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17217         mac_set = 1;
17218       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17219         ip_set = 1;
17220       else if (unformat (input, "bd %d", &bd))
17221         bd_set = 1;
17222       else
17223         {
17224           errmsg ("parse error '%U'", format_unformat_error, input);
17225           return -99;
17226         }
17227     }
17228
17229   if (!bd_set || !ip_set || (!mac_set && is_add))
17230     {
17231       errmsg ("Missing BD, IP or MAC!");
17232       return -99;
17233     }
17234
17235   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17236   mp->is_add = is_add;
17237   clib_memcpy (mp->mac, mac, 6);
17238   mp->bd = clib_host_to_net_u32 (bd);
17239   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17240
17241   /* send */
17242   S (mp);
17243
17244   /* wait for reply */
17245   W (ret);
17246   return ret;
17247 }
17248
17249 static int
17250 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17251 {
17252   vl_api_one_add_del_l2_arp_entry_t *mp;
17253   unformat_input_t *input = vam->input;
17254   u8 is_add = 1;
17255   u8 mac_set = 0;
17256   u8 bd_set = 0;
17257   u8 ip_set = 0;
17258   u8 mac[6] = { 0, };
17259   u32 ip4 = 0, 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, "del"))
17266         is_add = 0;
17267       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17268         mac_set = 1;
17269       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17270         ip_set = 1;
17271       else if (unformat (input, "bd %d", &bd))
17272         bd_set = 1;
17273       else
17274         {
17275           errmsg ("parse error '%U'", format_unformat_error, input);
17276           return -99;
17277         }
17278     }
17279
17280   if (!bd_set || !ip_set || (!mac_set && is_add))
17281     {
17282       errmsg ("Missing BD, IP or MAC!");
17283       return -99;
17284     }
17285
17286   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17287   mp->is_add = is_add;
17288   clib_memcpy (mp->mac, mac, 6);
17289   mp->bd = clib_host_to_net_u32 (bd);
17290   mp->ip4 = ip4;
17291
17292   /* send */
17293   S (mp);
17294
17295   /* wait for reply */
17296   W (ret);
17297   return ret;
17298 }
17299
17300 static int
17301 api_one_ndp_bd_get (vat_main_t * vam)
17302 {
17303   vl_api_one_ndp_bd_get_t *mp;
17304   int ret;
17305
17306   M (ONE_NDP_BD_GET, mp);
17307
17308   /* send */
17309   S (mp);
17310
17311   /* wait for reply */
17312   W (ret);
17313   return ret;
17314 }
17315
17316 static int
17317 api_one_ndp_entries_get (vat_main_t * vam)
17318 {
17319   vl_api_one_ndp_entries_get_t *mp;
17320   unformat_input_t *input = vam->input;
17321   u8 bd_set = 0;
17322   u32 bd = ~0;
17323   int ret;
17324
17325   /* Parse args required to build the message */
17326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17327     {
17328       if (unformat (input, "bd %d", &bd))
17329         bd_set = 1;
17330       else
17331         {
17332           errmsg ("parse error '%U'", format_unformat_error, input);
17333           return -99;
17334         }
17335     }
17336
17337   if (!bd_set)
17338     {
17339       errmsg ("Expected bridge domain!");
17340       return -99;
17341     }
17342
17343   M (ONE_NDP_ENTRIES_GET, mp);
17344   mp->bd = clib_host_to_net_u32 (bd);
17345
17346   /* send */
17347   S (mp);
17348
17349   /* wait for reply */
17350   W (ret);
17351   return ret;
17352 }
17353
17354 static int
17355 api_one_l2_arp_bd_get (vat_main_t * vam)
17356 {
17357   vl_api_one_l2_arp_bd_get_t *mp;
17358   int ret;
17359
17360   M (ONE_L2_ARP_BD_GET, mp);
17361
17362   /* send */
17363   S (mp);
17364
17365   /* wait for reply */
17366   W (ret);
17367   return ret;
17368 }
17369
17370 static int
17371 api_one_l2_arp_entries_get (vat_main_t * vam)
17372 {
17373   vl_api_one_l2_arp_entries_get_t *mp;
17374   unformat_input_t *input = vam->input;
17375   u8 bd_set = 0;
17376   u32 bd = ~0;
17377   int ret;
17378
17379   /* Parse args required to build the message */
17380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17381     {
17382       if (unformat (input, "bd %d", &bd))
17383         bd_set = 1;
17384       else
17385         {
17386           errmsg ("parse error '%U'", format_unformat_error, input);
17387           return -99;
17388         }
17389     }
17390
17391   if (!bd_set)
17392     {
17393       errmsg ("Expected bridge domain!");
17394       return -99;
17395     }
17396
17397   M (ONE_L2_ARP_ENTRIES_GET, mp);
17398   mp->bd = clib_host_to_net_u32 (bd);
17399
17400   /* send */
17401   S (mp);
17402
17403   /* wait for reply */
17404   W (ret);
17405   return ret;
17406 }
17407
17408 static int
17409 api_one_stats_enable_disable (vat_main_t * vam)
17410 {
17411   vl_api_one_stats_enable_disable_t *mp;
17412   unformat_input_t *input = vam->input;
17413   u8 is_set = 0;
17414   u8 is_en = 0;
17415   int ret;
17416
17417   /* Parse args required to build the message */
17418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17419     {
17420       if (unformat (input, "enable"))
17421         {
17422           is_set = 1;
17423           is_en = 1;
17424         }
17425       else if (unformat (input, "disable"))
17426         {
17427           is_set = 1;
17428         }
17429       else
17430         break;
17431     }
17432
17433   if (!is_set)
17434     {
17435       errmsg ("Value not set");
17436       return -99;
17437     }
17438
17439   M (ONE_STATS_ENABLE_DISABLE, mp);
17440   mp->is_en = is_en;
17441
17442   /* send */
17443   S (mp);
17444
17445   /* wait for reply */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 static int
17451 api_show_one_stats_enable_disable (vat_main_t * vam)
17452 {
17453   vl_api_show_one_stats_enable_disable_t *mp;
17454   int ret;
17455
17456   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17457
17458   /* send */
17459   S (mp);
17460
17461   /* wait for reply */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 static int
17467 api_show_one_map_request_mode (vat_main_t * vam)
17468 {
17469   vl_api_show_one_map_request_mode_t *mp;
17470   int ret;
17471
17472   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17473
17474   /* send */
17475   S (mp);
17476
17477   /* wait for reply */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17483
17484 static int
17485 api_one_map_request_mode (vat_main_t * vam)
17486 {
17487   unformat_input_t *input = vam->input;
17488   vl_api_one_map_request_mode_t *mp;
17489   u8 mode = 0;
17490   int ret;
17491
17492   /* Parse args required to build the message */
17493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (input, "dst-only"))
17496         mode = 0;
17497       else if (unformat (input, "src-dst"))
17498         mode = 1;
17499       else
17500         {
17501           errmsg ("parse error '%U'", format_unformat_error, input);
17502           return -99;
17503         }
17504     }
17505
17506   M (ONE_MAP_REQUEST_MODE, mp);
17507
17508   mp->mode = mode;
17509
17510   /* send */
17511   S (mp);
17512
17513   /* wait for reply */
17514   W (ret);
17515   return ret;
17516 }
17517
17518 #define api_lisp_map_request_mode api_one_map_request_mode
17519
17520 /**
17521  * Enable/disable ONE proxy ITR.
17522  *
17523  * @param vam vpp API test context
17524  * @return return code
17525  */
17526 static int
17527 api_one_pitr_set_locator_set (vat_main_t * vam)
17528 {
17529   u8 ls_name_set = 0;
17530   unformat_input_t *input = vam->input;
17531   vl_api_one_pitr_set_locator_set_t *mp;
17532   u8 is_add = 1;
17533   u8 *ls_name = 0;
17534   int ret;
17535
17536   /* Parse args required to build the message */
17537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17538     {
17539       if (unformat (input, "del"))
17540         is_add = 0;
17541       else if (unformat (input, "locator-set %s", &ls_name))
17542         ls_name_set = 1;
17543       else
17544         {
17545           errmsg ("parse error '%U'", format_unformat_error, input);
17546           return -99;
17547         }
17548     }
17549
17550   if (!ls_name_set)
17551     {
17552       errmsg ("locator-set name not set!");
17553       return -99;
17554     }
17555
17556   M (ONE_PITR_SET_LOCATOR_SET, mp);
17557
17558   mp->is_add = is_add;
17559   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17560   vec_free (ls_name);
17561
17562   /* send */
17563   S (mp);
17564
17565   /* wait for reply */
17566   W (ret);
17567   return ret;
17568 }
17569
17570 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17571
17572 static int
17573 api_one_nsh_set_locator_set (vat_main_t * vam)
17574 {
17575   u8 ls_name_set = 0;
17576   unformat_input_t *input = vam->input;
17577   vl_api_one_nsh_set_locator_set_t *mp;
17578   u8 is_add = 1;
17579   u8 *ls_name = 0;
17580   int ret;
17581
17582   /* Parse args required to build the message */
17583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17584     {
17585       if (unformat (input, "del"))
17586         is_add = 0;
17587       else if (unformat (input, "ls %s", &ls_name))
17588         ls_name_set = 1;
17589       else
17590         {
17591           errmsg ("parse error '%U'", format_unformat_error, input);
17592           return -99;
17593         }
17594     }
17595
17596   if (!ls_name_set && is_add)
17597     {
17598       errmsg ("locator-set name not set!");
17599       return -99;
17600     }
17601
17602   M (ONE_NSH_SET_LOCATOR_SET, mp);
17603
17604   mp->is_add = is_add;
17605   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17606   vec_free (ls_name);
17607
17608   /* send */
17609   S (mp);
17610
17611   /* wait for reply */
17612   W (ret);
17613   return ret;
17614 }
17615
17616 static int
17617 api_show_one_pitr (vat_main_t * vam)
17618 {
17619   vl_api_show_one_pitr_t *mp;
17620   int ret;
17621
17622   if (!vam->json_output)
17623     {
17624       print (vam->ofp, "%=20s", "lisp status:");
17625     }
17626
17627   M (SHOW_ONE_PITR, mp);
17628   /* send it... */
17629   S (mp);
17630
17631   /* Wait for a reply... */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 #define api_show_lisp_pitr api_show_one_pitr
17637
17638 static int
17639 api_one_use_petr (vat_main_t * vam)
17640 {
17641   unformat_input_t *input = vam->input;
17642   vl_api_one_use_petr_t *mp;
17643   u8 is_add = 0;
17644   ip_address_t ip;
17645   int ret;
17646
17647   memset (&ip, 0, sizeof (ip));
17648
17649   /* Parse args required to build the message */
17650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17651     {
17652       if (unformat (input, "disable"))
17653         is_add = 0;
17654       else
17655         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17656         {
17657           is_add = 1;
17658           ip_addr_version (&ip) = IP4;
17659         }
17660       else
17661         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17662         {
17663           is_add = 1;
17664           ip_addr_version (&ip) = IP6;
17665         }
17666       else
17667         {
17668           errmsg ("parse error '%U'", format_unformat_error, input);
17669           return -99;
17670         }
17671     }
17672
17673   M (ONE_USE_PETR, mp);
17674
17675   mp->is_add = is_add;
17676   if (is_add)
17677     {
17678       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17679       if (mp->is_ip4)
17680         clib_memcpy (mp->address, &ip, 4);
17681       else
17682         clib_memcpy (mp->address, &ip, 16);
17683     }
17684
17685   /* send */
17686   S (mp);
17687
17688   /* wait for reply */
17689   W (ret);
17690   return ret;
17691 }
17692
17693 #define api_lisp_use_petr api_one_use_petr
17694
17695 static int
17696 api_show_one_nsh_mapping (vat_main_t * vam)
17697 {
17698   vl_api_show_one_use_petr_t *mp;
17699   int ret;
17700
17701   if (!vam->json_output)
17702     {
17703       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17704     }
17705
17706   M (SHOW_ONE_NSH_MAPPING, mp);
17707   /* send it... */
17708   S (mp);
17709
17710   /* Wait for a reply... */
17711   W (ret);
17712   return ret;
17713 }
17714
17715 static int
17716 api_show_one_use_petr (vat_main_t * vam)
17717 {
17718   vl_api_show_one_use_petr_t *mp;
17719   int ret;
17720
17721   if (!vam->json_output)
17722     {
17723       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17724     }
17725
17726   M (SHOW_ONE_USE_PETR, mp);
17727   /* send it... */
17728   S (mp);
17729
17730   /* Wait for a reply... */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 #define api_show_lisp_use_petr api_show_one_use_petr
17736
17737 /**
17738  * Add/delete mapping between vni and vrf
17739  */
17740 static int
17741 api_one_eid_table_add_del_map (vat_main_t * vam)
17742 {
17743   unformat_input_t *input = vam->input;
17744   vl_api_one_eid_table_add_del_map_t *mp;
17745   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17746   u32 vni, vrf, bd_index;
17747   int ret;
17748
17749   /* Parse args required to build the message */
17750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17751     {
17752       if (unformat (input, "del"))
17753         is_add = 0;
17754       else if (unformat (input, "vrf %d", &vrf))
17755         vrf_set = 1;
17756       else if (unformat (input, "bd_index %d", &bd_index))
17757         bd_index_set = 1;
17758       else if (unformat (input, "vni %d", &vni))
17759         vni_set = 1;
17760       else
17761         break;
17762     }
17763
17764   if (!vni_set || (!vrf_set && !bd_index_set))
17765     {
17766       errmsg ("missing arguments!");
17767       return -99;
17768     }
17769
17770   if (vrf_set && bd_index_set)
17771     {
17772       errmsg ("error: both vrf and bd entered!");
17773       return -99;
17774     }
17775
17776   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17777
17778   mp->is_add = is_add;
17779   mp->vni = htonl (vni);
17780   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17781   mp->is_l2 = bd_index_set;
17782
17783   /* send */
17784   S (mp);
17785
17786   /* wait for reply */
17787   W (ret);
17788   return ret;
17789 }
17790
17791 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17792
17793 uword
17794 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17795 {
17796   u32 *action = va_arg (*args, u32 *);
17797   u8 *s = 0;
17798
17799   if (unformat (input, "%s", &s))
17800     {
17801       if (!strcmp ((char *) s, "no-action"))
17802         action[0] = 0;
17803       else if (!strcmp ((char *) s, "natively-forward"))
17804         action[0] = 1;
17805       else if (!strcmp ((char *) s, "send-map-request"))
17806         action[0] = 2;
17807       else if (!strcmp ((char *) s, "drop"))
17808         action[0] = 3;
17809       else
17810         {
17811           clib_warning ("invalid action: '%s'", s);
17812           action[0] = 3;
17813         }
17814     }
17815   else
17816     return 0;
17817
17818   vec_free (s);
17819   return 1;
17820 }
17821
17822 /**
17823  * Add/del remote mapping to/from ONE control plane
17824  *
17825  * @param vam vpp API test context
17826  * @return return code
17827  */
17828 static int
17829 api_one_add_del_remote_mapping (vat_main_t * vam)
17830 {
17831   unformat_input_t *input = vam->input;
17832   vl_api_one_add_del_remote_mapping_t *mp;
17833   u32 vni = 0;
17834   lisp_eid_vat_t _eid, *eid = &_eid;
17835   lisp_eid_vat_t _seid, *seid = &_seid;
17836   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17837   u32 action = ~0, p, w, data_len;
17838   ip4_address_t rloc4;
17839   ip6_address_t rloc6;
17840   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17841   int ret;
17842
17843   memset (&rloc, 0, sizeof (rloc));
17844
17845   /* Parse args required to build the message */
17846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17847     {
17848       if (unformat (input, "del-all"))
17849         {
17850           del_all = 1;
17851         }
17852       else if (unformat (input, "del"))
17853         {
17854           is_add = 0;
17855         }
17856       else if (unformat (input, "add"))
17857         {
17858           is_add = 1;
17859         }
17860       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17861         {
17862           eid_set = 1;
17863         }
17864       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17865         {
17866           seid_set = 1;
17867         }
17868       else if (unformat (input, "vni %d", &vni))
17869         {
17870           ;
17871         }
17872       else if (unformat (input, "p %d w %d", &p, &w))
17873         {
17874           if (!curr_rloc)
17875             {
17876               errmsg ("No RLOC configured for setting priority/weight!");
17877               return -99;
17878             }
17879           curr_rloc->priority = p;
17880           curr_rloc->weight = w;
17881         }
17882       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17883         {
17884           rloc.is_ip4 = 1;
17885           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17886           vec_add1 (rlocs, rloc);
17887           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17888         }
17889       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17890         {
17891           rloc.is_ip4 = 0;
17892           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17893           vec_add1 (rlocs, rloc);
17894           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17895         }
17896       else if (unformat (input, "action %U",
17897                          unformat_negative_mapping_action, &action))
17898         {
17899           ;
17900         }
17901       else
17902         {
17903           clib_warning ("parse error '%U'", format_unformat_error, input);
17904           return -99;
17905         }
17906     }
17907
17908   if (0 == eid_set)
17909     {
17910       errmsg ("missing params!");
17911       return -99;
17912     }
17913
17914   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17915     {
17916       errmsg ("no action set for negative map-reply!");
17917       return -99;
17918     }
17919
17920   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17921
17922   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17923   mp->is_add = is_add;
17924   mp->vni = htonl (vni);
17925   mp->action = (u8) action;
17926   mp->is_src_dst = seid_set;
17927   mp->eid_len = eid->len;
17928   mp->seid_len = seid->len;
17929   mp->del_all = del_all;
17930   mp->eid_type = eid->type;
17931   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17932   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17933
17934   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17935   clib_memcpy (mp->rlocs, rlocs, data_len);
17936   vec_free (rlocs);
17937
17938   /* send it... */
17939   S (mp);
17940
17941   /* Wait for a reply... */
17942   W (ret);
17943   return ret;
17944 }
17945
17946 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17947
17948 /**
17949  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17950  * forwarding entries in data-plane accordingly.
17951  *
17952  * @param vam vpp API test context
17953  * @return return code
17954  */
17955 static int
17956 api_one_add_del_adjacency (vat_main_t * vam)
17957 {
17958   unformat_input_t *input = vam->input;
17959   vl_api_one_add_del_adjacency_t *mp;
17960   u32 vni = 0;
17961   ip4_address_t leid4, reid4;
17962   ip6_address_t leid6, reid6;
17963   u8 reid_mac[6] = { 0 };
17964   u8 leid_mac[6] = { 0 };
17965   u8 reid_type, leid_type;
17966   u32 leid_len = 0, reid_len = 0, len;
17967   u8 is_add = 1;
17968   int ret;
17969
17970   leid_type = reid_type = (u8) ~ 0;
17971
17972   /* Parse args required to build the message */
17973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17974     {
17975       if (unformat (input, "del"))
17976         {
17977           is_add = 0;
17978         }
17979       else if (unformat (input, "add"))
17980         {
17981           is_add = 1;
17982         }
17983       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17984                          &reid4, &len))
17985         {
17986           reid_type = 0;        /* ipv4 */
17987           reid_len = len;
17988         }
17989       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17990                          &reid6, &len))
17991         {
17992           reid_type = 1;        /* ipv6 */
17993           reid_len = len;
17994         }
17995       else if (unformat (input, "reid %U", unformat_ethernet_address,
17996                          reid_mac))
17997         {
17998           reid_type = 2;        /* mac */
17999         }
18000       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18001                          &leid4, &len))
18002         {
18003           leid_type = 0;        /* ipv4 */
18004           leid_len = len;
18005         }
18006       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18007                          &leid6, &len))
18008         {
18009           leid_type = 1;        /* ipv6 */
18010           leid_len = len;
18011         }
18012       else if (unformat (input, "leid %U", unformat_ethernet_address,
18013                          leid_mac))
18014         {
18015           leid_type = 2;        /* mac */
18016         }
18017       else if (unformat (input, "vni %d", &vni))
18018         {
18019           ;
18020         }
18021       else
18022         {
18023           errmsg ("parse error '%U'", format_unformat_error, input);
18024           return -99;
18025         }
18026     }
18027
18028   if ((u8) ~ 0 == reid_type)
18029     {
18030       errmsg ("missing params!");
18031       return -99;
18032     }
18033
18034   if (leid_type != reid_type)
18035     {
18036       errmsg ("remote and local EIDs are of different types!");
18037       return -99;
18038     }
18039
18040   M (ONE_ADD_DEL_ADJACENCY, mp);
18041   mp->is_add = is_add;
18042   mp->vni = htonl (vni);
18043   mp->leid_len = leid_len;
18044   mp->reid_len = reid_len;
18045   mp->eid_type = reid_type;
18046
18047   switch (mp->eid_type)
18048     {
18049     case 0:
18050       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18051       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18052       break;
18053     case 1:
18054       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18055       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18056       break;
18057     case 2:
18058       clib_memcpy (mp->leid, leid_mac, 6);
18059       clib_memcpy (mp->reid, reid_mac, 6);
18060       break;
18061     default:
18062       errmsg ("unknown EID type %d!", mp->eid_type);
18063       return 0;
18064     }
18065
18066   /* send it... */
18067   S (mp);
18068
18069   /* Wait for a reply... */
18070   W (ret);
18071   return ret;
18072 }
18073
18074 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18075
18076 uword
18077 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18078 {
18079   u32 *mode = va_arg (*args, u32 *);
18080
18081   if (unformat (input, "lisp"))
18082     *mode = 0;
18083   else if (unformat (input, "vxlan"))
18084     *mode = 1;
18085   else
18086     return 0;
18087
18088   return 1;
18089 }
18090
18091 static int
18092 api_gpe_get_encap_mode (vat_main_t * vam)
18093 {
18094   vl_api_gpe_get_encap_mode_t *mp;
18095   int ret;
18096
18097   /* Construct the API message */
18098   M (GPE_GET_ENCAP_MODE, mp);
18099
18100   /* send it... */
18101   S (mp);
18102
18103   /* Wait for a reply... */
18104   W (ret);
18105   return ret;
18106 }
18107
18108 static int
18109 api_gpe_set_encap_mode (vat_main_t * vam)
18110 {
18111   unformat_input_t *input = vam->input;
18112   vl_api_gpe_set_encap_mode_t *mp;
18113   int ret;
18114   u32 mode = 0;
18115
18116   /* Parse args required to build the message */
18117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18120         ;
18121       else
18122         break;
18123     }
18124
18125   /* Construct the API message */
18126   M (GPE_SET_ENCAP_MODE, mp);
18127
18128   mp->mode = mode;
18129
18130   /* send it... */
18131   S (mp);
18132
18133   /* Wait for a reply... */
18134   W (ret);
18135   return ret;
18136 }
18137
18138 static int
18139 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18140 {
18141   unformat_input_t *input = vam->input;
18142   vl_api_gpe_add_del_iface_t *mp;
18143   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18144   u32 dp_table = 0, vni = 0;
18145   int ret;
18146
18147   /* Parse args required to build the message */
18148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18149     {
18150       if (unformat (input, "up"))
18151         {
18152           action_set = 1;
18153           is_add = 1;
18154         }
18155       else if (unformat (input, "down"))
18156         {
18157           action_set = 1;
18158           is_add = 0;
18159         }
18160       else if (unformat (input, "table_id %d", &dp_table))
18161         {
18162           dp_table_set = 1;
18163         }
18164       else if (unformat (input, "bd_id %d", &dp_table))
18165         {
18166           dp_table_set = 1;
18167           is_l2 = 1;
18168         }
18169       else if (unformat (input, "vni %d", &vni))
18170         {
18171           vni_set = 1;
18172         }
18173       else
18174         break;
18175     }
18176
18177   if (action_set == 0)
18178     {
18179       errmsg ("Action not set");
18180       return -99;
18181     }
18182   if (dp_table_set == 0 || vni_set == 0)
18183     {
18184       errmsg ("vni and dp_table must be set");
18185       return -99;
18186     }
18187
18188   /* Construct the API message */
18189   M (GPE_ADD_DEL_IFACE, mp);
18190
18191   mp->is_add = is_add;
18192   mp->dp_table = clib_host_to_net_u32 (dp_table);
18193   mp->is_l2 = is_l2;
18194   mp->vni = clib_host_to_net_u32 (vni);
18195
18196   /* send it... */
18197   S (mp);
18198
18199   /* Wait for a reply... */
18200   W (ret);
18201   return ret;
18202 }
18203
18204 static int
18205 api_one_map_register_fallback_threshold (vat_main_t * vam)
18206 {
18207   unformat_input_t *input = vam->input;
18208   vl_api_one_map_register_fallback_threshold_t *mp;
18209   u32 value = 0;
18210   u8 is_set = 0;
18211   int ret;
18212
18213   /* Parse args required to build the message */
18214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18215     {
18216       if (unformat (input, "%u", &value))
18217         is_set = 1;
18218       else
18219         {
18220           clib_warning ("parse error '%U'", format_unformat_error, input);
18221           return -99;
18222         }
18223     }
18224
18225   if (!is_set)
18226     {
18227       errmsg ("fallback threshold value is missing!");
18228       return -99;
18229     }
18230
18231   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18232   mp->value = clib_host_to_net_u32 (value);
18233
18234   /* send it... */
18235   S (mp);
18236
18237   /* Wait for a reply... */
18238   W (ret);
18239   return ret;
18240 }
18241
18242 static int
18243 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18244 {
18245   vl_api_show_one_map_register_fallback_threshold_t *mp;
18246   int ret;
18247
18248   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18249
18250   /* send it... */
18251   S (mp);
18252
18253   /* Wait for a reply... */
18254   W (ret);
18255   return ret;
18256 }
18257
18258 uword
18259 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18260 {
18261   u32 *proto = va_arg (*args, u32 *);
18262
18263   if (unformat (input, "udp"))
18264     *proto = 1;
18265   else if (unformat (input, "api"))
18266     *proto = 2;
18267   else
18268     return 0;
18269
18270   return 1;
18271 }
18272
18273 static int
18274 api_one_set_transport_protocol (vat_main_t * vam)
18275 {
18276   unformat_input_t *input = vam->input;
18277   vl_api_one_set_transport_protocol_t *mp;
18278   u8 is_set = 0;
18279   u32 protocol = 0;
18280   int ret;
18281
18282   /* Parse args required to build the message */
18283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18284     {
18285       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18286         is_set = 1;
18287       else
18288         {
18289           clib_warning ("parse error '%U'", format_unformat_error, input);
18290           return -99;
18291         }
18292     }
18293
18294   if (!is_set)
18295     {
18296       errmsg ("Transport protocol missing!");
18297       return -99;
18298     }
18299
18300   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18301   mp->protocol = (u8) protocol;
18302
18303   /* send it... */
18304   S (mp);
18305
18306   /* Wait for a reply... */
18307   W (ret);
18308   return ret;
18309 }
18310
18311 static int
18312 api_one_get_transport_protocol (vat_main_t * vam)
18313 {
18314   vl_api_one_get_transport_protocol_t *mp;
18315   int ret;
18316
18317   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18318
18319   /* send it... */
18320   S (mp);
18321
18322   /* Wait for a reply... */
18323   W (ret);
18324   return ret;
18325 }
18326
18327 static int
18328 api_one_map_register_set_ttl (vat_main_t * vam)
18329 {
18330   unformat_input_t *input = vam->input;
18331   vl_api_one_map_register_set_ttl_t *mp;
18332   u32 ttl = 0;
18333   u8 is_set = 0;
18334   int ret;
18335
18336   /* Parse args required to build the message */
18337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18338     {
18339       if (unformat (input, "%u", &ttl))
18340         is_set = 1;
18341       else
18342         {
18343           clib_warning ("parse error '%U'", format_unformat_error, input);
18344           return -99;
18345         }
18346     }
18347
18348   if (!is_set)
18349     {
18350       errmsg ("TTL value missing!");
18351       return -99;
18352     }
18353
18354   M (ONE_MAP_REGISTER_SET_TTL, mp);
18355   mp->ttl = clib_host_to_net_u32 (ttl);
18356
18357   /* send it... */
18358   S (mp);
18359
18360   /* Wait for a reply... */
18361   W (ret);
18362   return ret;
18363 }
18364
18365 static int
18366 api_show_one_map_register_ttl (vat_main_t * vam)
18367 {
18368   vl_api_show_one_map_register_ttl_t *mp;
18369   int ret;
18370
18371   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18372
18373   /* send it... */
18374   S (mp);
18375
18376   /* Wait for a reply... */
18377   W (ret);
18378   return ret;
18379 }
18380
18381 /**
18382  * Add/del map request itr rlocs from ONE control plane and updates
18383  *
18384  * @param vam vpp API test context
18385  * @return return code
18386  */
18387 static int
18388 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18389 {
18390   unformat_input_t *input = vam->input;
18391   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18392   u8 *locator_set_name = 0;
18393   u8 locator_set_name_set = 0;
18394   u8 is_add = 1;
18395   int ret;
18396
18397   /* Parse args required to build the message */
18398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18399     {
18400       if (unformat (input, "del"))
18401         {
18402           is_add = 0;
18403         }
18404       else if (unformat (input, "%_%v%_", &locator_set_name))
18405         {
18406           locator_set_name_set = 1;
18407         }
18408       else
18409         {
18410           clib_warning ("parse error '%U'", format_unformat_error, input);
18411           return -99;
18412         }
18413     }
18414
18415   if (is_add && !locator_set_name_set)
18416     {
18417       errmsg ("itr-rloc is not set!");
18418       return -99;
18419     }
18420
18421   if (is_add && vec_len (locator_set_name) > 64)
18422     {
18423       errmsg ("itr-rloc locator-set name too long");
18424       vec_free (locator_set_name);
18425       return -99;
18426     }
18427
18428   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18429   mp->is_add = is_add;
18430   if (is_add)
18431     {
18432       clib_memcpy (mp->locator_set_name, locator_set_name,
18433                    vec_len (locator_set_name));
18434     }
18435   else
18436     {
18437       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18438     }
18439   vec_free (locator_set_name);
18440
18441   /* send it... */
18442   S (mp);
18443
18444   /* Wait for a reply... */
18445   W (ret);
18446   return ret;
18447 }
18448
18449 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18450
18451 static int
18452 api_one_locator_dump (vat_main_t * vam)
18453 {
18454   unformat_input_t *input = vam->input;
18455   vl_api_one_locator_dump_t *mp;
18456   vl_api_control_ping_t *mp_ping;
18457   u8 is_index_set = 0, is_name_set = 0;
18458   u8 *ls_name = 0;
18459   u32 ls_index = ~0;
18460   int ret;
18461
18462   /* Parse args required to build the message */
18463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18464     {
18465       if (unformat (input, "ls_name %_%v%_", &ls_name))
18466         {
18467           is_name_set = 1;
18468         }
18469       else if (unformat (input, "ls_index %d", &ls_index))
18470         {
18471           is_index_set = 1;
18472         }
18473       else
18474         {
18475           errmsg ("parse error '%U'", format_unformat_error, input);
18476           return -99;
18477         }
18478     }
18479
18480   if (!is_index_set && !is_name_set)
18481     {
18482       errmsg ("error: expected one of index or name!");
18483       return -99;
18484     }
18485
18486   if (is_index_set && is_name_set)
18487     {
18488       errmsg ("error: only one param expected!");
18489       return -99;
18490     }
18491
18492   if (vec_len (ls_name) > 62)
18493     {
18494       errmsg ("error: locator set name too long!");
18495       return -99;
18496     }
18497
18498   if (!vam->json_output)
18499     {
18500       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18501     }
18502
18503   M (ONE_LOCATOR_DUMP, mp);
18504   mp->is_index_set = is_index_set;
18505
18506   if (is_index_set)
18507     mp->ls_index = clib_host_to_net_u32 (ls_index);
18508   else
18509     {
18510       vec_add1 (ls_name, 0);
18511       strncpy ((char *) mp->ls_name, (char *) ls_name,
18512                sizeof (mp->ls_name) - 1);
18513     }
18514
18515   /* send it... */
18516   S (mp);
18517
18518   /* Use a control ping for synchronization */
18519   MPING (CONTROL_PING, mp_ping);
18520   S (mp_ping);
18521
18522   /* Wait for a reply... */
18523   W (ret);
18524   return ret;
18525 }
18526
18527 #define api_lisp_locator_dump api_one_locator_dump
18528
18529 static int
18530 api_one_locator_set_dump (vat_main_t * vam)
18531 {
18532   vl_api_one_locator_set_dump_t *mp;
18533   vl_api_control_ping_t *mp_ping;
18534   unformat_input_t *input = vam->input;
18535   u8 filter = 0;
18536   int ret;
18537
18538   /* Parse args required to build the message */
18539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18540     {
18541       if (unformat (input, "local"))
18542         {
18543           filter = 1;
18544         }
18545       else if (unformat (input, "remote"))
18546         {
18547           filter = 2;
18548         }
18549       else
18550         {
18551           errmsg ("parse error '%U'", format_unformat_error, input);
18552           return -99;
18553         }
18554     }
18555
18556   if (!vam->json_output)
18557     {
18558       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18559     }
18560
18561   M (ONE_LOCATOR_SET_DUMP, mp);
18562
18563   mp->filter = filter;
18564
18565   /* send it... */
18566   S (mp);
18567
18568   /* Use a control ping for synchronization */
18569   MPING (CONTROL_PING, mp_ping);
18570   S (mp_ping);
18571
18572   /* Wait for a reply... */
18573   W (ret);
18574   return ret;
18575 }
18576
18577 #define api_lisp_locator_set_dump api_one_locator_set_dump
18578
18579 static int
18580 api_one_eid_table_map_dump (vat_main_t * vam)
18581 {
18582   u8 is_l2 = 0;
18583   u8 mode_set = 0;
18584   unformat_input_t *input = vam->input;
18585   vl_api_one_eid_table_map_dump_t *mp;
18586   vl_api_control_ping_t *mp_ping;
18587   int ret;
18588
18589   /* Parse args required to build the message */
18590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18591     {
18592       if (unformat (input, "l2"))
18593         {
18594           is_l2 = 1;
18595           mode_set = 1;
18596         }
18597       else if (unformat (input, "l3"))
18598         {
18599           is_l2 = 0;
18600           mode_set = 1;
18601         }
18602       else
18603         {
18604           errmsg ("parse error '%U'", format_unformat_error, input);
18605           return -99;
18606         }
18607     }
18608
18609   if (!mode_set)
18610     {
18611       errmsg ("expected one of 'l2' or 'l3' parameter!");
18612       return -99;
18613     }
18614
18615   if (!vam->json_output)
18616     {
18617       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18618     }
18619
18620   M (ONE_EID_TABLE_MAP_DUMP, mp);
18621   mp->is_l2 = is_l2;
18622
18623   /* send it... */
18624   S (mp);
18625
18626   /* Use a control ping for synchronization */
18627   MPING (CONTROL_PING, mp_ping);
18628   S (mp_ping);
18629
18630   /* Wait for a reply... */
18631   W (ret);
18632   return ret;
18633 }
18634
18635 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18636
18637 static int
18638 api_one_eid_table_vni_dump (vat_main_t * vam)
18639 {
18640   vl_api_one_eid_table_vni_dump_t *mp;
18641   vl_api_control_ping_t *mp_ping;
18642   int ret;
18643
18644   if (!vam->json_output)
18645     {
18646       print (vam->ofp, "VNI");
18647     }
18648
18649   M (ONE_EID_TABLE_VNI_DUMP, mp);
18650
18651   /* send it... */
18652   S (mp);
18653
18654   /* Use a control ping for synchronization */
18655   MPING (CONTROL_PING, mp_ping);
18656   S (mp_ping);
18657
18658   /* Wait for a reply... */
18659   W (ret);
18660   return ret;
18661 }
18662
18663 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18664
18665 static int
18666 api_one_eid_table_dump (vat_main_t * vam)
18667 {
18668   unformat_input_t *i = vam->input;
18669   vl_api_one_eid_table_dump_t *mp;
18670   vl_api_control_ping_t *mp_ping;
18671   struct in_addr ip4;
18672   struct in6_addr ip6;
18673   u8 mac[6];
18674   u8 eid_type = ~0, eid_set = 0;
18675   u32 prefix_length = ~0, t, vni = 0;
18676   u8 filter = 0;
18677   int ret;
18678   lisp_nsh_api_t nsh;
18679
18680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18681     {
18682       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18683         {
18684           eid_set = 1;
18685           eid_type = 0;
18686           prefix_length = t;
18687         }
18688       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18689         {
18690           eid_set = 1;
18691           eid_type = 1;
18692           prefix_length = t;
18693         }
18694       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18695         {
18696           eid_set = 1;
18697           eid_type = 2;
18698         }
18699       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18700         {
18701           eid_set = 1;
18702           eid_type = 3;
18703         }
18704       else if (unformat (i, "vni %d", &t))
18705         {
18706           vni = t;
18707         }
18708       else if (unformat (i, "local"))
18709         {
18710           filter = 1;
18711         }
18712       else if (unformat (i, "remote"))
18713         {
18714           filter = 2;
18715         }
18716       else
18717         {
18718           errmsg ("parse error '%U'", format_unformat_error, i);
18719           return -99;
18720         }
18721     }
18722
18723   if (!vam->json_output)
18724     {
18725       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18726              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18727     }
18728
18729   M (ONE_EID_TABLE_DUMP, mp);
18730
18731   mp->filter = filter;
18732   if (eid_set)
18733     {
18734       mp->eid_set = 1;
18735       mp->vni = htonl (vni);
18736       mp->eid_type = eid_type;
18737       switch (eid_type)
18738         {
18739         case 0:
18740           mp->prefix_length = prefix_length;
18741           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18742           break;
18743         case 1:
18744           mp->prefix_length = prefix_length;
18745           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18746           break;
18747         case 2:
18748           clib_memcpy (mp->eid, mac, sizeof (mac));
18749           break;
18750         case 3:
18751           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18752           break;
18753         default:
18754           errmsg ("unknown EID type %d!", eid_type);
18755           return -99;
18756         }
18757     }
18758
18759   /* send it... */
18760   S (mp);
18761
18762   /* Use a control ping for synchronization */
18763   MPING (CONTROL_PING, mp_ping);
18764   S (mp_ping);
18765
18766   /* Wait for a reply... */
18767   W (ret);
18768   return ret;
18769 }
18770
18771 #define api_lisp_eid_table_dump api_one_eid_table_dump
18772
18773 static int
18774 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18775 {
18776   unformat_input_t *i = vam->input;
18777   vl_api_gpe_fwd_entries_get_t *mp;
18778   u8 vni_set = 0;
18779   u32 vni = ~0;
18780   int ret;
18781
18782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18783     {
18784       if (unformat (i, "vni %d", &vni))
18785         {
18786           vni_set = 1;
18787         }
18788       else
18789         {
18790           errmsg ("parse error '%U'", format_unformat_error, i);
18791           return -99;
18792         }
18793     }
18794
18795   if (!vni_set)
18796     {
18797       errmsg ("vni not set!");
18798       return -99;
18799     }
18800
18801   if (!vam->json_output)
18802     {
18803       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18804              "leid", "reid");
18805     }
18806
18807   M (GPE_FWD_ENTRIES_GET, mp);
18808   mp->vni = clib_host_to_net_u32 (vni);
18809
18810   /* send it... */
18811   S (mp);
18812
18813   /* Wait for a reply... */
18814   W (ret);
18815   return ret;
18816 }
18817
18818 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18819 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18820 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18821 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18822 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18823 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18824 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18825 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18826
18827 static int
18828 api_one_adjacencies_get (vat_main_t * vam)
18829 {
18830   unformat_input_t *i = vam->input;
18831   vl_api_one_adjacencies_get_t *mp;
18832   u8 vni_set = 0;
18833   u32 vni = ~0;
18834   int ret;
18835
18836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18837     {
18838       if (unformat (i, "vni %d", &vni))
18839         {
18840           vni_set = 1;
18841         }
18842       else
18843         {
18844           errmsg ("parse error '%U'", format_unformat_error, i);
18845           return -99;
18846         }
18847     }
18848
18849   if (!vni_set)
18850     {
18851       errmsg ("vni not set!");
18852       return -99;
18853     }
18854
18855   if (!vam->json_output)
18856     {
18857       print (vam->ofp, "%s %40s", "leid", "reid");
18858     }
18859
18860   M (ONE_ADJACENCIES_GET, mp);
18861   mp->vni = clib_host_to_net_u32 (vni);
18862
18863   /* send it... */
18864   S (mp);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 #define api_lisp_adjacencies_get api_one_adjacencies_get
18872
18873 static int
18874 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18875 {
18876   unformat_input_t *i = vam->input;
18877   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18878   int ret;
18879   u8 ip_family_set = 0, is_ip4 = 1;
18880
18881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18882     {
18883       if (unformat (i, "ip4"))
18884         {
18885           ip_family_set = 1;
18886           is_ip4 = 1;
18887         }
18888       else if (unformat (i, "ip6"))
18889         {
18890           ip_family_set = 1;
18891           is_ip4 = 0;
18892         }
18893       else
18894         {
18895           errmsg ("parse error '%U'", format_unformat_error, i);
18896           return -99;
18897         }
18898     }
18899
18900   if (!ip_family_set)
18901     {
18902       errmsg ("ip family not set!");
18903       return -99;
18904     }
18905
18906   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18907   mp->is_ip4 = is_ip4;
18908
18909   /* send it... */
18910   S (mp);
18911
18912   /* Wait for a reply... */
18913   W (ret);
18914   return ret;
18915 }
18916
18917 static int
18918 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18919 {
18920   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18921   int ret;
18922
18923   if (!vam->json_output)
18924     {
18925       print (vam->ofp, "VNIs");
18926     }
18927
18928   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18929
18930   /* send it... */
18931   S (mp);
18932
18933   /* Wait for a reply... */
18934   W (ret);
18935   return ret;
18936 }
18937
18938 static int
18939 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18940 {
18941   unformat_input_t *i = vam->input;
18942   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18943   int ret = 0;
18944   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18945   struct in_addr ip4;
18946   struct in6_addr ip6;
18947   u32 table_id = 0, nh_sw_if_index = ~0;
18948
18949   memset (&ip4, 0, sizeof (ip4));
18950   memset (&ip6, 0, sizeof (ip6));
18951
18952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18953     {
18954       if (unformat (i, "del"))
18955         is_add = 0;
18956       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18957                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18958         {
18959           ip_set = 1;
18960           is_ip4 = 1;
18961         }
18962       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18963                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18964         {
18965           ip_set = 1;
18966           is_ip4 = 0;
18967         }
18968       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18969         {
18970           ip_set = 1;
18971           is_ip4 = 1;
18972           nh_sw_if_index = ~0;
18973         }
18974       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18975         {
18976           ip_set = 1;
18977           is_ip4 = 0;
18978           nh_sw_if_index = ~0;
18979         }
18980       else if (unformat (i, "table %d", &table_id))
18981         ;
18982       else
18983         {
18984           errmsg ("parse error '%U'", format_unformat_error, i);
18985           return -99;
18986         }
18987     }
18988
18989   if (!ip_set)
18990     {
18991       errmsg ("nh addr not set!");
18992       return -99;
18993     }
18994
18995   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18996   mp->is_add = is_add;
18997   mp->table_id = clib_host_to_net_u32 (table_id);
18998   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18999   mp->is_ip4 = is_ip4;
19000   if (is_ip4)
19001     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19002   else
19003     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19004
19005   /* send it... */
19006   S (mp);
19007
19008   /* Wait for a reply... */
19009   W (ret);
19010   return ret;
19011 }
19012
19013 static int
19014 api_one_map_server_dump (vat_main_t * vam)
19015 {
19016   vl_api_one_map_server_dump_t *mp;
19017   vl_api_control_ping_t *mp_ping;
19018   int ret;
19019
19020   if (!vam->json_output)
19021     {
19022       print (vam->ofp, "%=20s", "Map server");
19023     }
19024
19025   M (ONE_MAP_SERVER_DUMP, mp);
19026   /* send it... */
19027   S (mp);
19028
19029   /* Use a control ping for synchronization */
19030   MPING (CONTROL_PING, mp_ping);
19031   S (mp_ping);
19032
19033   /* Wait for a reply... */
19034   W (ret);
19035   return ret;
19036 }
19037
19038 #define api_lisp_map_server_dump api_one_map_server_dump
19039
19040 static int
19041 api_one_map_resolver_dump (vat_main_t * vam)
19042 {
19043   vl_api_one_map_resolver_dump_t *mp;
19044   vl_api_control_ping_t *mp_ping;
19045   int ret;
19046
19047   if (!vam->json_output)
19048     {
19049       print (vam->ofp, "%=20s", "Map resolver");
19050     }
19051
19052   M (ONE_MAP_RESOLVER_DUMP, mp);
19053   /* send it... */
19054   S (mp);
19055
19056   /* Use a control ping for synchronization */
19057   MPING (CONTROL_PING, mp_ping);
19058   S (mp_ping);
19059
19060   /* Wait for a reply... */
19061   W (ret);
19062   return ret;
19063 }
19064
19065 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19066
19067 static int
19068 api_one_stats_flush (vat_main_t * vam)
19069 {
19070   vl_api_one_stats_flush_t *mp;
19071   int ret = 0;
19072
19073   M (ONE_STATS_FLUSH, mp);
19074   S (mp);
19075   W (ret);
19076   return ret;
19077 }
19078
19079 static int
19080 api_one_stats_dump (vat_main_t * vam)
19081 {
19082   vl_api_one_stats_dump_t *mp;
19083   vl_api_control_ping_t *mp_ping;
19084   int ret;
19085
19086   M (ONE_STATS_DUMP, mp);
19087   /* send it... */
19088   S (mp);
19089
19090   /* Use a control ping for synchronization */
19091   MPING (CONTROL_PING, mp_ping);
19092   S (mp_ping);
19093
19094   /* Wait for a reply... */
19095   W (ret);
19096   return ret;
19097 }
19098
19099 static int
19100 api_show_one_status (vat_main_t * vam)
19101 {
19102   vl_api_show_one_status_t *mp;
19103   int ret;
19104
19105   if (!vam->json_output)
19106     {
19107       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19108     }
19109
19110   M (SHOW_ONE_STATUS, mp);
19111   /* send it... */
19112   S (mp);
19113   /* Wait for a reply... */
19114   W (ret);
19115   return ret;
19116 }
19117
19118 #define api_show_lisp_status api_show_one_status
19119
19120 static int
19121 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19122 {
19123   vl_api_gpe_fwd_entry_path_dump_t *mp;
19124   vl_api_control_ping_t *mp_ping;
19125   unformat_input_t *i = vam->input;
19126   u32 fwd_entry_index = ~0;
19127   int ret;
19128
19129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19130     {
19131       if (unformat (i, "index %d", &fwd_entry_index))
19132         ;
19133       else
19134         break;
19135     }
19136
19137   if (~0 == fwd_entry_index)
19138     {
19139       errmsg ("no index specified!");
19140       return -99;
19141     }
19142
19143   if (!vam->json_output)
19144     {
19145       print (vam->ofp, "first line");
19146     }
19147
19148   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19149
19150   /* send it... */
19151   S (mp);
19152   /* Use a control ping for synchronization */
19153   MPING (CONTROL_PING, mp_ping);
19154   S (mp_ping);
19155
19156   /* Wait for a reply... */
19157   W (ret);
19158   return ret;
19159 }
19160
19161 static int
19162 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19163 {
19164   vl_api_one_get_map_request_itr_rlocs_t *mp;
19165   int ret;
19166
19167   if (!vam->json_output)
19168     {
19169       print (vam->ofp, "%=20s", "itr-rlocs:");
19170     }
19171
19172   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19173   /* send it... */
19174   S (mp);
19175   /* Wait for a reply... */
19176   W (ret);
19177   return ret;
19178 }
19179
19180 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19181
19182 static int
19183 api_af_packet_create (vat_main_t * vam)
19184 {
19185   unformat_input_t *i = vam->input;
19186   vl_api_af_packet_create_t *mp;
19187   u8 *host_if_name = 0;
19188   u8 hw_addr[6];
19189   u8 random_hw_addr = 1;
19190   int ret;
19191
19192   memset (hw_addr, 0, sizeof (hw_addr));
19193
19194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19195     {
19196       if (unformat (i, "name %s", &host_if_name))
19197         vec_add1 (host_if_name, 0);
19198       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19199         random_hw_addr = 0;
19200       else
19201         break;
19202     }
19203
19204   if (!vec_len (host_if_name))
19205     {
19206       errmsg ("host-interface name must be specified");
19207       return -99;
19208     }
19209
19210   if (vec_len (host_if_name) > 64)
19211     {
19212       errmsg ("host-interface name too long");
19213       return -99;
19214     }
19215
19216   M (AF_PACKET_CREATE, mp);
19217
19218   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19219   clib_memcpy (mp->hw_addr, hw_addr, 6);
19220   mp->use_random_hw_addr = random_hw_addr;
19221   vec_free (host_if_name);
19222
19223   S (mp);
19224
19225   /* *INDENT-OFF* */
19226   W2 (ret,
19227       ({
19228         if (ret == 0)
19229           fprintf (vam->ofp ? vam->ofp : stderr,
19230                    " new sw_if_index = %d\n", vam->sw_if_index);
19231       }));
19232   /* *INDENT-ON* */
19233   return ret;
19234 }
19235
19236 static int
19237 api_af_packet_delete (vat_main_t * vam)
19238 {
19239   unformat_input_t *i = vam->input;
19240   vl_api_af_packet_delete_t *mp;
19241   u8 *host_if_name = 0;
19242   int ret;
19243
19244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19245     {
19246       if (unformat (i, "name %s", &host_if_name))
19247         vec_add1 (host_if_name, 0);
19248       else
19249         break;
19250     }
19251
19252   if (!vec_len (host_if_name))
19253     {
19254       errmsg ("host-interface name must be specified");
19255       return -99;
19256     }
19257
19258   if (vec_len (host_if_name) > 64)
19259     {
19260       errmsg ("host-interface name too long");
19261       return -99;
19262     }
19263
19264   M (AF_PACKET_DELETE, mp);
19265
19266   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19267   vec_free (host_if_name);
19268
19269   S (mp);
19270   W (ret);
19271   return ret;
19272 }
19273
19274 static int
19275 api_policer_add_del (vat_main_t * vam)
19276 {
19277   unformat_input_t *i = vam->input;
19278   vl_api_policer_add_del_t *mp;
19279   u8 is_add = 1;
19280   u8 *name = 0;
19281   u32 cir = 0;
19282   u32 eir = 0;
19283   u64 cb = 0;
19284   u64 eb = 0;
19285   u8 rate_type = 0;
19286   u8 round_type = 0;
19287   u8 type = 0;
19288   u8 color_aware = 0;
19289   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19290   int ret;
19291
19292   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19293   conform_action.dscp = 0;
19294   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19295   exceed_action.dscp = 0;
19296   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19297   violate_action.dscp = 0;
19298
19299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19300     {
19301       if (unformat (i, "del"))
19302         is_add = 0;
19303       else if (unformat (i, "name %s", &name))
19304         vec_add1 (name, 0);
19305       else if (unformat (i, "cir %u", &cir))
19306         ;
19307       else if (unformat (i, "eir %u", &eir))
19308         ;
19309       else if (unformat (i, "cb %u", &cb))
19310         ;
19311       else if (unformat (i, "eb %u", &eb))
19312         ;
19313       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19314                          &rate_type))
19315         ;
19316       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19317                          &round_type))
19318         ;
19319       else if (unformat (i, "type %U", unformat_policer_type, &type))
19320         ;
19321       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19322                          &conform_action))
19323         ;
19324       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19325                          &exceed_action))
19326         ;
19327       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19328                          &violate_action))
19329         ;
19330       else if (unformat (i, "color-aware"))
19331         color_aware = 1;
19332       else
19333         break;
19334     }
19335
19336   if (!vec_len (name))
19337     {
19338       errmsg ("policer name must be specified");
19339       return -99;
19340     }
19341
19342   if (vec_len (name) > 64)
19343     {
19344       errmsg ("policer name too long");
19345       return -99;
19346     }
19347
19348   M (POLICER_ADD_DEL, mp);
19349
19350   clib_memcpy (mp->name, name, vec_len (name));
19351   vec_free (name);
19352   mp->is_add = is_add;
19353   mp->cir = ntohl (cir);
19354   mp->eir = ntohl (eir);
19355   mp->cb = clib_net_to_host_u64 (cb);
19356   mp->eb = clib_net_to_host_u64 (eb);
19357   mp->rate_type = rate_type;
19358   mp->round_type = round_type;
19359   mp->type = type;
19360   mp->conform_action_type = conform_action.action_type;
19361   mp->conform_dscp = conform_action.dscp;
19362   mp->exceed_action_type = exceed_action.action_type;
19363   mp->exceed_dscp = exceed_action.dscp;
19364   mp->violate_action_type = violate_action.action_type;
19365   mp->violate_dscp = violate_action.dscp;
19366   mp->color_aware = color_aware;
19367
19368   S (mp);
19369   W (ret);
19370   return ret;
19371 }
19372
19373 static int
19374 api_policer_dump (vat_main_t * vam)
19375 {
19376   unformat_input_t *i = vam->input;
19377   vl_api_policer_dump_t *mp;
19378   vl_api_control_ping_t *mp_ping;
19379   u8 *match_name = 0;
19380   u8 match_name_valid = 0;
19381   int ret;
19382
19383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19384     {
19385       if (unformat (i, "name %s", &match_name))
19386         {
19387           vec_add1 (match_name, 0);
19388           match_name_valid = 1;
19389         }
19390       else
19391         break;
19392     }
19393
19394   M (POLICER_DUMP, mp);
19395   mp->match_name_valid = match_name_valid;
19396   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19397   vec_free (match_name);
19398   /* send it... */
19399   S (mp);
19400
19401   /* Use a control ping for synchronization */
19402   MPING (CONTROL_PING, mp_ping);
19403   S (mp_ping);
19404
19405   /* Wait for a reply... */
19406   W (ret);
19407   return ret;
19408 }
19409
19410 static int
19411 api_policer_classify_set_interface (vat_main_t * vam)
19412 {
19413   unformat_input_t *i = vam->input;
19414   vl_api_policer_classify_set_interface_t *mp;
19415   u32 sw_if_index;
19416   int sw_if_index_set;
19417   u32 ip4_table_index = ~0;
19418   u32 ip6_table_index = ~0;
19419   u32 l2_table_index = ~0;
19420   u8 is_add = 1;
19421   int ret;
19422
19423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19424     {
19425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19426         sw_if_index_set = 1;
19427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19428         sw_if_index_set = 1;
19429       else if (unformat (i, "del"))
19430         is_add = 0;
19431       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19432         ;
19433       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19434         ;
19435       else if (unformat (i, "l2-table %d", &l2_table_index))
19436         ;
19437       else
19438         {
19439           clib_warning ("parse error '%U'", format_unformat_error, i);
19440           return -99;
19441         }
19442     }
19443
19444   if (sw_if_index_set == 0)
19445     {
19446       errmsg ("missing interface name or sw_if_index");
19447       return -99;
19448     }
19449
19450   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19451
19452   mp->sw_if_index = ntohl (sw_if_index);
19453   mp->ip4_table_index = ntohl (ip4_table_index);
19454   mp->ip6_table_index = ntohl (ip6_table_index);
19455   mp->l2_table_index = ntohl (l2_table_index);
19456   mp->is_add = is_add;
19457
19458   S (mp);
19459   W (ret);
19460   return ret;
19461 }
19462
19463 static int
19464 api_policer_classify_dump (vat_main_t * vam)
19465 {
19466   unformat_input_t *i = vam->input;
19467   vl_api_policer_classify_dump_t *mp;
19468   vl_api_control_ping_t *mp_ping;
19469   u8 type = POLICER_CLASSIFY_N_TABLES;
19470   int ret;
19471
19472   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19473     ;
19474   else
19475     {
19476       errmsg ("classify table type must be specified");
19477       return -99;
19478     }
19479
19480   if (!vam->json_output)
19481     {
19482       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19483     }
19484
19485   M (POLICER_CLASSIFY_DUMP, mp);
19486   mp->type = type;
19487   /* send it... */
19488   S (mp);
19489
19490   /* Use a control ping for synchronization */
19491   MPING (CONTROL_PING, mp_ping);
19492   S (mp_ping);
19493
19494   /* Wait for a reply... */
19495   W (ret);
19496   return ret;
19497 }
19498
19499 static int
19500 api_netmap_create (vat_main_t * vam)
19501 {
19502   unformat_input_t *i = vam->input;
19503   vl_api_netmap_create_t *mp;
19504   u8 *if_name = 0;
19505   u8 hw_addr[6];
19506   u8 random_hw_addr = 1;
19507   u8 is_pipe = 0;
19508   u8 is_master = 0;
19509   int ret;
19510
19511   memset (hw_addr, 0, sizeof (hw_addr));
19512
19513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19514     {
19515       if (unformat (i, "name %s", &if_name))
19516         vec_add1 (if_name, 0);
19517       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19518         random_hw_addr = 0;
19519       else if (unformat (i, "pipe"))
19520         is_pipe = 1;
19521       else if (unformat (i, "master"))
19522         is_master = 1;
19523       else if (unformat (i, "slave"))
19524         is_master = 0;
19525       else
19526         break;
19527     }
19528
19529   if (!vec_len (if_name))
19530     {
19531       errmsg ("interface name must be specified");
19532       return -99;
19533     }
19534
19535   if (vec_len (if_name) > 64)
19536     {
19537       errmsg ("interface name too long");
19538       return -99;
19539     }
19540
19541   M (NETMAP_CREATE, mp);
19542
19543   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19544   clib_memcpy (mp->hw_addr, hw_addr, 6);
19545   mp->use_random_hw_addr = random_hw_addr;
19546   mp->is_pipe = is_pipe;
19547   mp->is_master = is_master;
19548   vec_free (if_name);
19549
19550   S (mp);
19551   W (ret);
19552   return ret;
19553 }
19554
19555 static int
19556 api_netmap_delete (vat_main_t * vam)
19557 {
19558   unformat_input_t *i = vam->input;
19559   vl_api_netmap_delete_t *mp;
19560   u8 *if_name = 0;
19561   int ret;
19562
19563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19564     {
19565       if (unformat (i, "name %s", &if_name))
19566         vec_add1 (if_name, 0);
19567       else
19568         break;
19569     }
19570
19571   if (!vec_len (if_name))
19572     {
19573       errmsg ("interface name must be specified");
19574       return -99;
19575     }
19576
19577   if (vec_len (if_name) > 64)
19578     {
19579       errmsg ("interface name too long");
19580       return -99;
19581     }
19582
19583   M (NETMAP_DELETE, mp);
19584
19585   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19586   vec_free (if_name);
19587
19588   S (mp);
19589   W (ret);
19590   return ret;
19591 }
19592
19593 static void
19594 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19595 {
19596   if (fp->afi == IP46_TYPE_IP6)
19597     print (vam->ofp,
19598            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19599            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19600            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19601            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19602            format_ip6_address, fp->next_hop);
19603   else if (fp->afi == IP46_TYPE_IP4)
19604     print (vam->ofp,
19605            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19606            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19607            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19608            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19609            format_ip4_address, fp->next_hop);
19610 }
19611
19612 static void
19613 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19614                                  vl_api_fib_path2_t * fp)
19615 {
19616   struct in_addr ip4;
19617   struct in6_addr ip6;
19618
19619   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19620   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19621   vat_json_object_add_uint (node, "is_local", fp->is_local);
19622   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19623   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19624   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19625   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19626   if (fp->afi == IP46_TYPE_IP4)
19627     {
19628       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19629       vat_json_object_add_ip4 (node, "next_hop", ip4);
19630     }
19631   else if (fp->afi == IP46_TYPE_IP6)
19632     {
19633       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19634       vat_json_object_add_ip6 (node, "next_hop", ip6);
19635     }
19636 }
19637
19638 static void
19639 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19640 {
19641   vat_main_t *vam = &vat_main;
19642   int count = ntohl (mp->mt_count);
19643   vl_api_fib_path2_t *fp;
19644   i32 i;
19645
19646   print (vam->ofp, "[%d]: sw_if_index %d via:",
19647          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19648   fp = mp->mt_paths;
19649   for (i = 0; i < count; i++)
19650     {
19651       vl_api_mpls_fib_path_print (vam, fp);
19652       fp++;
19653     }
19654
19655   print (vam->ofp, "");
19656 }
19657
19658 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19659 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19660
19661 static void
19662 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19663 {
19664   vat_main_t *vam = &vat_main;
19665   vat_json_node_t *node = NULL;
19666   int count = ntohl (mp->mt_count);
19667   vl_api_fib_path2_t *fp;
19668   i32 i;
19669
19670   if (VAT_JSON_ARRAY != vam->json_tree.type)
19671     {
19672       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19673       vat_json_init_array (&vam->json_tree);
19674     }
19675   node = vat_json_array_add (&vam->json_tree);
19676
19677   vat_json_init_object (node);
19678   vat_json_object_add_uint (node, "tunnel_index",
19679                             ntohl (mp->mt_tunnel_index));
19680   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19681
19682   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19683
19684   fp = mp->mt_paths;
19685   for (i = 0; i < count; i++)
19686     {
19687       vl_api_mpls_fib_path_json_print (node, fp);
19688       fp++;
19689     }
19690 }
19691
19692 static int
19693 api_mpls_tunnel_dump (vat_main_t * vam)
19694 {
19695   vl_api_mpls_tunnel_dump_t *mp;
19696   vl_api_control_ping_t *mp_ping;
19697   i32 index = -1;
19698   int ret;
19699
19700   /* Parse args required to build the message */
19701   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19702     {
19703       if (!unformat (vam->input, "tunnel_index %d", &index))
19704         {
19705           index = -1;
19706           break;
19707         }
19708     }
19709
19710   print (vam->ofp, "  tunnel_index %d", index);
19711
19712   M (MPLS_TUNNEL_DUMP, mp);
19713   mp->tunnel_index = htonl (index);
19714   S (mp);
19715
19716   /* Use a control ping for synchronization */
19717   MPING (CONTROL_PING, mp_ping);
19718   S (mp_ping);
19719
19720   W (ret);
19721   return ret;
19722 }
19723
19724 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19725 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19726
19727
19728 static void
19729 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19730 {
19731   vat_main_t *vam = &vat_main;
19732   int count = ntohl (mp->count);
19733   vl_api_fib_path2_t *fp;
19734   int i;
19735
19736   print (vam->ofp,
19737          "table-id %d, label %u, ess_bit %u",
19738          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19739   fp = mp->path;
19740   for (i = 0; i < count; i++)
19741     {
19742       vl_api_mpls_fib_path_print (vam, fp);
19743       fp++;
19744     }
19745 }
19746
19747 static void vl_api_mpls_fib_details_t_handler_json
19748   (vl_api_mpls_fib_details_t * mp)
19749 {
19750   vat_main_t *vam = &vat_main;
19751   int count = ntohl (mp->count);
19752   vat_json_node_t *node = NULL;
19753   vl_api_fib_path2_t *fp;
19754   int i;
19755
19756   if (VAT_JSON_ARRAY != vam->json_tree.type)
19757     {
19758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19759       vat_json_init_array (&vam->json_tree);
19760     }
19761   node = vat_json_array_add (&vam->json_tree);
19762
19763   vat_json_init_object (node);
19764   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19765   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19766   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19767   vat_json_object_add_uint (node, "path_count", count);
19768   fp = mp->path;
19769   for (i = 0; i < count; i++)
19770     {
19771       vl_api_mpls_fib_path_json_print (node, fp);
19772       fp++;
19773     }
19774 }
19775
19776 static int
19777 api_mpls_fib_dump (vat_main_t * vam)
19778 {
19779   vl_api_mpls_fib_dump_t *mp;
19780   vl_api_control_ping_t *mp_ping;
19781   int ret;
19782
19783   M (MPLS_FIB_DUMP, mp);
19784   S (mp);
19785
19786   /* Use a control ping for synchronization */
19787   MPING (CONTROL_PING, mp_ping);
19788   S (mp_ping);
19789
19790   W (ret);
19791   return ret;
19792 }
19793
19794 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19795 #define vl_api_ip_fib_details_t_print vl_noop_handler
19796
19797 static void
19798 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19799 {
19800   vat_main_t *vam = &vat_main;
19801   int count = ntohl (mp->count);
19802   vl_api_fib_path_t *fp;
19803   int i;
19804
19805   print (vam->ofp,
19806          "table-id %d, prefix %U/%d",
19807          ntohl (mp->table_id), format_ip4_address, mp->address,
19808          mp->address_length);
19809   fp = mp->path;
19810   for (i = 0; i < count; i++)
19811     {
19812       if (fp->afi == IP46_TYPE_IP6)
19813         print (vam->ofp,
19814                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19815                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19816                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19817                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19818                format_ip6_address, fp->next_hop);
19819       else if (fp->afi == IP46_TYPE_IP4)
19820         print (vam->ofp,
19821                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19822                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19823                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19824                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19825                format_ip4_address, fp->next_hop);
19826       fp++;
19827     }
19828 }
19829
19830 static void vl_api_ip_fib_details_t_handler_json
19831   (vl_api_ip_fib_details_t * mp)
19832 {
19833   vat_main_t *vam = &vat_main;
19834   int count = ntohl (mp->count);
19835   vat_json_node_t *node = NULL;
19836   struct in_addr ip4;
19837   struct in6_addr ip6;
19838   vl_api_fib_path_t *fp;
19839   int i;
19840
19841   if (VAT_JSON_ARRAY != vam->json_tree.type)
19842     {
19843       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19844       vat_json_init_array (&vam->json_tree);
19845     }
19846   node = vat_json_array_add (&vam->json_tree);
19847
19848   vat_json_init_object (node);
19849   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19850   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19851   vat_json_object_add_ip4 (node, "prefix", ip4);
19852   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19853   vat_json_object_add_uint (node, "path_count", count);
19854   fp = mp->path;
19855   for (i = 0; i < count; i++)
19856     {
19857       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19858       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19859       vat_json_object_add_uint (node, "is_local", fp->is_local);
19860       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19861       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19862       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19863       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19864       if (fp->afi == IP46_TYPE_IP4)
19865         {
19866           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19867           vat_json_object_add_ip4 (node, "next_hop", ip4);
19868         }
19869       else if (fp->afi == IP46_TYPE_IP6)
19870         {
19871           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19872           vat_json_object_add_ip6 (node, "next_hop", ip6);
19873         }
19874     }
19875 }
19876
19877 static int
19878 api_ip_fib_dump (vat_main_t * vam)
19879 {
19880   vl_api_ip_fib_dump_t *mp;
19881   vl_api_control_ping_t *mp_ping;
19882   int ret;
19883
19884   M (IP_FIB_DUMP, mp);
19885   S (mp);
19886
19887   /* Use a control ping for synchronization */
19888   MPING (CONTROL_PING, mp_ping);
19889   S (mp_ping);
19890
19891   W (ret);
19892   return ret;
19893 }
19894
19895 static int
19896 api_ip_mfib_dump (vat_main_t * vam)
19897 {
19898   vl_api_ip_mfib_dump_t *mp;
19899   vl_api_control_ping_t *mp_ping;
19900   int ret;
19901
19902   M (IP_MFIB_DUMP, mp);
19903   S (mp);
19904
19905   /* Use a control ping for synchronization */
19906   MPING (CONTROL_PING, mp_ping);
19907   S (mp_ping);
19908
19909   W (ret);
19910   return ret;
19911 }
19912
19913 static void vl_api_ip_neighbor_details_t_handler
19914   (vl_api_ip_neighbor_details_t * mp)
19915 {
19916   vat_main_t *vam = &vat_main;
19917
19918   print (vam->ofp, "%c %U %U",
19919          (mp->is_static) ? 'S' : 'D',
19920          format_ethernet_address, &mp->mac_address,
19921          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19922          &mp->ip_address);
19923 }
19924
19925 static void vl_api_ip_neighbor_details_t_handler_json
19926   (vl_api_ip_neighbor_details_t * mp)
19927 {
19928
19929   vat_main_t *vam = &vat_main;
19930   vat_json_node_t *node;
19931   struct in_addr ip4;
19932   struct in6_addr ip6;
19933
19934   if (VAT_JSON_ARRAY != vam->json_tree.type)
19935     {
19936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19937       vat_json_init_array (&vam->json_tree);
19938     }
19939   node = vat_json_array_add (&vam->json_tree);
19940
19941   vat_json_init_object (node);
19942   vat_json_object_add_string_copy (node, "flag",
19943                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19944                                    "dynamic");
19945
19946   vat_json_object_add_string_copy (node, "link_layer",
19947                                    format (0, "%U", format_ethernet_address,
19948                                            &mp->mac_address));
19949
19950   if (mp->is_ipv6)
19951     {
19952       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19953       vat_json_object_add_ip6 (node, "ip_address", ip6);
19954     }
19955   else
19956     {
19957       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19958       vat_json_object_add_ip4 (node, "ip_address", ip4);
19959     }
19960 }
19961
19962 static int
19963 api_ip_neighbor_dump (vat_main_t * vam)
19964 {
19965   unformat_input_t *i = vam->input;
19966   vl_api_ip_neighbor_dump_t *mp;
19967   vl_api_control_ping_t *mp_ping;
19968   u8 is_ipv6 = 0;
19969   u32 sw_if_index = ~0;
19970   int ret;
19971
19972   /* Parse args required to build the message */
19973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19974     {
19975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19976         ;
19977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19978         ;
19979       else if (unformat (i, "ip6"))
19980         is_ipv6 = 1;
19981       else
19982         break;
19983     }
19984
19985   if (sw_if_index == ~0)
19986     {
19987       errmsg ("missing interface name or sw_if_index");
19988       return -99;
19989     }
19990
19991   M (IP_NEIGHBOR_DUMP, mp);
19992   mp->is_ipv6 = (u8) is_ipv6;
19993   mp->sw_if_index = ntohl (sw_if_index);
19994   S (mp);
19995
19996   /* Use a control ping for synchronization */
19997   MPING (CONTROL_PING, mp_ping);
19998   S (mp_ping);
19999
20000   W (ret);
20001   return ret;
20002 }
20003
20004 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20005 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20006
20007 static void
20008 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20009 {
20010   vat_main_t *vam = &vat_main;
20011   int count = ntohl (mp->count);
20012   vl_api_fib_path_t *fp;
20013   int i;
20014
20015   print (vam->ofp,
20016          "table-id %d, prefix %U/%d",
20017          ntohl (mp->table_id), format_ip6_address, mp->address,
20018          mp->address_length);
20019   fp = mp->path;
20020   for (i = 0; i < count; i++)
20021     {
20022       if (fp->afi == IP46_TYPE_IP6)
20023         print (vam->ofp,
20024                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20025                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20026                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20027                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20028                format_ip6_address, fp->next_hop);
20029       else if (fp->afi == IP46_TYPE_IP4)
20030         print (vam->ofp,
20031                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20032                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20033                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20034                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20035                format_ip4_address, fp->next_hop);
20036       fp++;
20037     }
20038 }
20039
20040 static void vl_api_ip6_fib_details_t_handler_json
20041   (vl_api_ip6_fib_details_t * mp)
20042 {
20043   vat_main_t *vam = &vat_main;
20044   int count = ntohl (mp->count);
20045   vat_json_node_t *node = NULL;
20046   struct in_addr ip4;
20047   struct in6_addr ip6;
20048   vl_api_fib_path_t *fp;
20049   int i;
20050
20051   if (VAT_JSON_ARRAY != vam->json_tree.type)
20052     {
20053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20054       vat_json_init_array (&vam->json_tree);
20055     }
20056   node = vat_json_array_add (&vam->json_tree);
20057
20058   vat_json_init_object (node);
20059   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20060   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20061   vat_json_object_add_ip6 (node, "prefix", ip6);
20062   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20063   vat_json_object_add_uint (node, "path_count", count);
20064   fp = mp->path;
20065   for (i = 0; i < count; i++)
20066     {
20067       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20068       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20069       vat_json_object_add_uint (node, "is_local", fp->is_local);
20070       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20071       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20072       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20073       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20074       if (fp->afi == IP46_TYPE_IP4)
20075         {
20076           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20077           vat_json_object_add_ip4 (node, "next_hop", ip4);
20078         }
20079       else if (fp->afi == IP46_TYPE_IP6)
20080         {
20081           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20082           vat_json_object_add_ip6 (node, "next_hop", ip6);
20083         }
20084     }
20085 }
20086
20087 static int
20088 api_ip6_fib_dump (vat_main_t * vam)
20089 {
20090   vl_api_ip6_fib_dump_t *mp;
20091   vl_api_control_ping_t *mp_ping;
20092   int ret;
20093
20094   M (IP6_FIB_DUMP, mp);
20095   S (mp);
20096
20097   /* Use a control ping for synchronization */
20098   MPING (CONTROL_PING, mp_ping);
20099   S (mp_ping);
20100
20101   W (ret);
20102   return ret;
20103 }
20104
20105 static int
20106 api_ip6_mfib_dump (vat_main_t * vam)
20107 {
20108   vl_api_ip6_mfib_dump_t *mp;
20109   vl_api_control_ping_t *mp_ping;
20110   int ret;
20111
20112   M (IP6_MFIB_DUMP, mp);
20113   S (mp);
20114
20115   /* Use a control ping for synchronization */
20116   MPING (CONTROL_PING, mp_ping);
20117   S (mp_ping);
20118
20119   W (ret);
20120   return ret;
20121 }
20122
20123 int
20124 api_classify_table_ids (vat_main_t * vam)
20125 {
20126   vl_api_classify_table_ids_t *mp;
20127   int ret;
20128
20129   /* Construct the API message */
20130   M (CLASSIFY_TABLE_IDS, mp);
20131   mp->context = 0;
20132
20133   S (mp);
20134   W (ret);
20135   return ret;
20136 }
20137
20138 int
20139 api_classify_table_by_interface (vat_main_t * vam)
20140 {
20141   unformat_input_t *input = vam->input;
20142   vl_api_classify_table_by_interface_t *mp;
20143
20144   u32 sw_if_index = ~0;
20145   int ret;
20146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20147     {
20148       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20149         ;
20150       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20151         ;
20152       else
20153         break;
20154     }
20155   if (sw_if_index == ~0)
20156     {
20157       errmsg ("missing interface name or sw_if_index");
20158       return -99;
20159     }
20160
20161   /* Construct the API message */
20162   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20163   mp->context = 0;
20164   mp->sw_if_index = ntohl (sw_if_index);
20165
20166   S (mp);
20167   W (ret);
20168   return ret;
20169 }
20170
20171 int
20172 api_classify_table_info (vat_main_t * vam)
20173 {
20174   unformat_input_t *input = vam->input;
20175   vl_api_classify_table_info_t *mp;
20176
20177   u32 table_id = ~0;
20178   int ret;
20179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20180     {
20181       if (unformat (input, "table_id %d", &table_id))
20182         ;
20183       else
20184         break;
20185     }
20186   if (table_id == ~0)
20187     {
20188       errmsg ("missing table id");
20189       return -99;
20190     }
20191
20192   /* Construct the API message */
20193   M (CLASSIFY_TABLE_INFO, mp);
20194   mp->context = 0;
20195   mp->table_id = ntohl (table_id);
20196
20197   S (mp);
20198   W (ret);
20199   return ret;
20200 }
20201
20202 int
20203 api_classify_session_dump (vat_main_t * vam)
20204 {
20205   unformat_input_t *input = vam->input;
20206   vl_api_classify_session_dump_t *mp;
20207   vl_api_control_ping_t *mp_ping;
20208
20209   u32 table_id = ~0;
20210   int ret;
20211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20212     {
20213       if (unformat (input, "table_id %d", &table_id))
20214         ;
20215       else
20216         break;
20217     }
20218   if (table_id == ~0)
20219     {
20220       errmsg ("missing table id");
20221       return -99;
20222     }
20223
20224   /* Construct the API message */
20225   M (CLASSIFY_SESSION_DUMP, mp);
20226   mp->context = 0;
20227   mp->table_id = ntohl (table_id);
20228   S (mp);
20229
20230   /* Use a control ping for synchronization */
20231   MPING (CONTROL_PING, mp_ping);
20232   S (mp_ping);
20233
20234   W (ret);
20235   return ret;
20236 }
20237
20238 static void
20239 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20240 {
20241   vat_main_t *vam = &vat_main;
20242
20243   print (vam->ofp, "collector_address %U, collector_port %d, "
20244          "src_address %U, vrf_id %d, path_mtu %u, "
20245          "template_interval %u, udp_checksum %d",
20246          format_ip4_address, mp->collector_address,
20247          ntohs (mp->collector_port),
20248          format_ip4_address, mp->src_address,
20249          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20250          ntohl (mp->template_interval), mp->udp_checksum);
20251
20252   vam->retval = 0;
20253   vam->result_ready = 1;
20254 }
20255
20256 static void
20257   vl_api_ipfix_exporter_details_t_handler_json
20258   (vl_api_ipfix_exporter_details_t * mp)
20259 {
20260   vat_main_t *vam = &vat_main;
20261   vat_json_node_t node;
20262   struct in_addr collector_address;
20263   struct in_addr src_address;
20264
20265   vat_json_init_object (&node);
20266   clib_memcpy (&collector_address, &mp->collector_address,
20267                sizeof (collector_address));
20268   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20269   vat_json_object_add_uint (&node, "collector_port",
20270                             ntohs (mp->collector_port));
20271   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20272   vat_json_object_add_ip4 (&node, "src_address", src_address);
20273   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20274   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20275   vat_json_object_add_uint (&node, "template_interval",
20276                             ntohl (mp->template_interval));
20277   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20278
20279   vat_json_print (vam->ofp, &node);
20280   vat_json_free (&node);
20281   vam->retval = 0;
20282   vam->result_ready = 1;
20283 }
20284
20285 int
20286 api_ipfix_exporter_dump (vat_main_t * vam)
20287 {
20288   vl_api_ipfix_exporter_dump_t *mp;
20289   int ret;
20290
20291   /* Construct the API message */
20292   M (IPFIX_EXPORTER_DUMP, mp);
20293   mp->context = 0;
20294
20295   S (mp);
20296   W (ret);
20297   return ret;
20298 }
20299
20300 static int
20301 api_ipfix_classify_stream_dump (vat_main_t * vam)
20302 {
20303   vl_api_ipfix_classify_stream_dump_t *mp;
20304   int ret;
20305
20306   /* Construct the API message */
20307   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20308   mp->context = 0;
20309
20310   S (mp);
20311   W (ret);
20312   return ret;
20313   /* NOTREACHED */
20314   return 0;
20315 }
20316
20317 static void
20318   vl_api_ipfix_classify_stream_details_t_handler
20319   (vl_api_ipfix_classify_stream_details_t * mp)
20320 {
20321   vat_main_t *vam = &vat_main;
20322   print (vam->ofp, "domain_id %d, src_port %d",
20323          ntohl (mp->domain_id), ntohs (mp->src_port));
20324   vam->retval = 0;
20325   vam->result_ready = 1;
20326 }
20327
20328 static void
20329   vl_api_ipfix_classify_stream_details_t_handler_json
20330   (vl_api_ipfix_classify_stream_details_t * mp)
20331 {
20332   vat_main_t *vam = &vat_main;
20333   vat_json_node_t node;
20334
20335   vat_json_init_object (&node);
20336   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20337   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20338
20339   vat_json_print (vam->ofp, &node);
20340   vat_json_free (&node);
20341   vam->retval = 0;
20342   vam->result_ready = 1;
20343 }
20344
20345 static int
20346 api_ipfix_classify_table_dump (vat_main_t * vam)
20347 {
20348   vl_api_ipfix_classify_table_dump_t *mp;
20349   vl_api_control_ping_t *mp_ping;
20350   int ret;
20351
20352   if (!vam->json_output)
20353     {
20354       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20355              "transport_protocol");
20356     }
20357
20358   /* Construct the API message */
20359   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20360
20361   /* send it... */
20362   S (mp);
20363
20364   /* Use a control ping for synchronization */
20365   MPING (CONTROL_PING, mp_ping);
20366   S (mp_ping);
20367
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static void
20373   vl_api_ipfix_classify_table_details_t_handler
20374   (vl_api_ipfix_classify_table_details_t * mp)
20375 {
20376   vat_main_t *vam = &vat_main;
20377   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20378          mp->transport_protocol);
20379 }
20380
20381 static void
20382   vl_api_ipfix_classify_table_details_t_handler_json
20383   (vl_api_ipfix_classify_table_details_t * mp)
20384 {
20385   vat_json_node_t *node = NULL;
20386   vat_main_t *vam = &vat_main;
20387
20388   if (VAT_JSON_ARRAY != vam->json_tree.type)
20389     {
20390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20391       vat_json_init_array (&vam->json_tree);
20392     }
20393
20394   node = vat_json_array_add (&vam->json_tree);
20395   vat_json_init_object (node);
20396
20397   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20398   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20399   vat_json_object_add_uint (node, "transport_protocol",
20400                             mp->transport_protocol);
20401 }
20402
20403 static int
20404 api_sw_interface_span_enable_disable (vat_main_t * vam)
20405 {
20406   unformat_input_t *i = vam->input;
20407   vl_api_sw_interface_span_enable_disable_t *mp;
20408   u32 src_sw_if_index = ~0;
20409   u32 dst_sw_if_index = ~0;
20410   u8 state = 3;
20411   int ret;
20412   u8 is_l2 = 0;
20413
20414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20415     {
20416       if (unformat
20417           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20418         ;
20419       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20420         ;
20421       else
20422         if (unformat
20423             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20424         ;
20425       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20426         ;
20427       else if (unformat (i, "disable"))
20428         state = 0;
20429       else if (unformat (i, "rx"))
20430         state = 1;
20431       else if (unformat (i, "tx"))
20432         state = 2;
20433       else if (unformat (i, "both"))
20434         state = 3;
20435       else if (unformat (i, "l2"))
20436         is_l2 = 1;
20437       else
20438         break;
20439     }
20440
20441   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20442
20443   mp->sw_if_index_from = htonl (src_sw_if_index);
20444   mp->sw_if_index_to = htonl (dst_sw_if_index);
20445   mp->state = state;
20446   mp->is_l2 = is_l2;
20447
20448   S (mp);
20449   W (ret);
20450   return ret;
20451 }
20452
20453 static void
20454 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20455                                             * mp)
20456 {
20457   vat_main_t *vam = &vat_main;
20458   u8 *sw_if_from_name = 0;
20459   u8 *sw_if_to_name = 0;
20460   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20461   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20462   char *states[] = { "none", "rx", "tx", "both" };
20463   hash_pair_t *p;
20464
20465   /* *INDENT-OFF* */
20466   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20467   ({
20468     if ((u32) p->value[0] == sw_if_index_from)
20469       {
20470         sw_if_from_name = (u8 *)(p->key);
20471         if (sw_if_to_name)
20472           break;
20473       }
20474     if ((u32) p->value[0] == sw_if_index_to)
20475       {
20476         sw_if_to_name = (u8 *)(p->key);
20477         if (sw_if_from_name)
20478           break;
20479       }
20480   }));
20481   /* *INDENT-ON* */
20482   print (vam->ofp, "%20s => %20s (%s)",
20483          sw_if_from_name, sw_if_to_name, states[mp->state]);
20484 }
20485
20486 static void
20487   vl_api_sw_interface_span_details_t_handler_json
20488   (vl_api_sw_interface_span_details_t * mp)
20489 {
20490   vat_main_t *vam = &vat_main;
20491   vat_json_node_t *node = NULL;
20492   u8 *sw_if_from_name = 0;
20493   u8 *sw_if_to_name = 0;
20494   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20495   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20496   hash_pair_t *p;
20497
20498   /* *INDENT-OFF* */
20499   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20500   ({
20501     if ((u32) p->value[0] == sw_if_index_from)
20502       {
20503         sw_if_from_name = (u8 *)(p->key);
20504         if (sw_if_to_name)
20505           break;
20506       }
20507     if ((u32) p->value[0] == sw_if_index_to)
20508       {
20509         sw_if_to_name = (u8 *)(p->key);
20510         if (sw_if_from_name)
20511           break;
20512       }
20513   }));
20514   /* *INDENT-ON* */
20515
20516   if (VAT_JSON_ARRAY != vam->json_tree.type)
20517     {
20518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20519       vat_json_init_array (&vam->json_tree);
20520     }
20521   node = vat_json_array_add (&vam->json_tree);
20522
20523   vat_json_init_object (node);
20524   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20525   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20526   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20527   if (0 != sw_if_to_name)
20528     {
20529       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20530     }
20531   vat_json_object_add_uint (node, "state", mp->state);
20532 }
20533
20534 static int
20535 api_sw_interface_span_dump (vat_main_t * vam)
20536 {
20537   unformat_input_t *input = vam->input;
20538   vl_api_sw_interface_span_dump_t *mp;
20539   vl_api_control_ping_t *mp_ping;
20540   u8 is_l2 = 0;
20541   int ret;
20542
20543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (input, "l2"))
20546         is_l2 = 1;
20547       else
20548         break;
20549     }
20550
20551   M (SW_INTERFACE_SPAN_DUMP, mp);
20552   mp->is_l2 = is_l2;
20553   S (mp);
20554
20555   /* Use a control ping for synchronization */
20556   MPING (CONTROL_PING, mp_ping);
20557   S (mp_ping);
20558
20559   W (ret);
20560   return ret;
20561 }
20562
20563 int
20564 api_pg_create_interface (vat_main_t * vam)
20565 {
20566   unformat_input_t *input = vam->input;
20567   vl_api_pg_create_interface_t *mp;
20568
20569   u32 if_id = ~0;
20570   int ret;
20571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20572     {
20573       if (unformat (input, "if_id %d", &if_id))
20574         ;
20575       else
20576         break;
20577     }
20578   if (if_id == ~0)
20579     {
20580       errmsg ("missing pg interface index");
20581       return -99;
20582     }
20583
20584   /* Construct the API message */
20585   M (PG_CREATE_INTERFACE, mp);
20586   mp->context = 0;
20587   mp->interface_id = ntohl (if_id);
20588
20589   S (mp);
20590   W (ret);
20591   return ret;
20592 }
20593
20594 int
20595 api_pg_capture (vat_main_t * vam)
20596 {
20597   unformat_input_t *input = vam->input;
20598   vl_api_pg_capture_t *mp;
20599
20600   u32 if_id = ~0;
20601   u8 enable = 1;
20602   u32 count = 1;
20603   u8 pcap_file_set = 0;
20604   u8 *pcap_file = 0;
20605   int ret;
20606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20607     {
20608       if (unformat (input, "if_id %d", &if_id))
20609         ;
20610       else if (unformat (input, "pcap %s", &pcap_file))
20611         pcap_file_set = 1;
20612       else if (unformat (input, "count %d", &count))
20613         ;
20614       else if (unformat (input, "disable"))
20615         enable = 0;
20616       else
20617         break;
20618     }
20619   if (if_id == ~0)
20620     {
20621       errmsg ("missing pg interface index");
20622       return -99;
20623     }
20624   if (pcap_file_set > 0)
20625     {
20626       if (vec_len (pcap_file) > 255)
20627         {
20628           errmsg ("pcap file name is too long");
20629           return -99;
20630         }
20631     }
20632
20633   u32 name_len = vec_len (pcap_file);
20634   /* Construct the API message */
20635   M (PG_CAPTURE, mp);
20636   mp->context = 0;
20637   mp->interface_id = ntohl (if_id);
20638   mp->is_enabled = enable;
20639   mp->count = ntohl (count);
20640   mp->pcap_name_length = ntohl (name_len);
20641   if (pcap_file_set != 0)
20642     {
20643       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20644     }
20645   vec_free (pcap_file);
20646
20647   S (mp);
20648   W (ret);
20649   return ret;
20650 }
20651
20652 int
20653 api_pg_enable_disable (vat_main_t * vam)
20654 {
20655   unformat_input_t *input = vam->input;
20656   vl_api_pg_enable_disable_t *mp;
20657
20658   u8 enable = 1;
20659   u8 stream_name_set = 0;
20660   u8 *stream_name = 0;
20661   int ret;
20662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20663     {
20664       if (unformat (input, "stream %s", &stream_name))
20665         stream_name_set = 1;
20666       else if (unformat (input, "disable"))
20667         enable = 0;
20668       else
20669         break;
20670     }
20671
20672   if (stream_name_set > 0)
20673     {
20674       if (vec_len (stream_name) > 255)
20675         {
20676           errmsg ("stream name too long");
20677           return -99;
20678         }
20679     }
20680
20681   u32 name_len = vec_len (stream_name);
20682   /* Construct the API message */
20683   M (PG_ENABLE_DISABLE, mp);
20684   mp->context = 0;
20685   mp->is_enabled = enable;
20686   if (stream_name_set != 0)
20687     {
20688       mp->stream_name_length = ntohl (name_len);
20689       clib_memcpy (mp->stream_name, stream_name, name_len);
20690     }
20691   vec_free (stream_name);
20692
20693   S (mp);
20694   W (ret);
20695   return ret;
20696 }
20697
20698 int
20699 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20700 {
20701   unformat_input_t *input = vam->input;
20702   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20703
20704   u16 *low_ports = 0;
20705   u16 *high_ports = 0;
20706   u16 this_low;
20707   u16 this_hi;
20708   ip4_address_t ip4_addr;
20709   ip6_address_t ip6_addr;
20710   u32 length;
20711   u32 tmp, tmp2;
20712   u8 prefix_set = 0;
20713   u32 vrf_id = ~0;
20714   u8 is_add = 1;
20715   u8 is_ipv6 = 0;
20716   int ret;
20717
20718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20719     {
20720       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20721         {
20722           prefix_set = 1;
20723         }
20724       else
20725         if (unformat
20726             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20727         {
20728           prefix_set = 1;
20729           is_ipv6 = 1;
20730         }
20731       else if (unformat (input, "vrf %d", &vrf_id))
20732         ;
20733       else if (unformat (input, "del"))
20734         is_add = 0;
20735       else if (unformat (input, "port %d", &tmp))
20736         {
20737           if (tmp == 0 || tmp > 65535)
20738             {
20739               errmsg ("port %d out of range", tmp);
20740               return -99;
20741             }
20742           this_low = tmp;
20743           this_hi = this_low + 1;
20744           vec_add1 (low_ports, this_low);
20745           vec_add1 (high_ports, this_hi);
20746         }
20747       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20748         {
20749           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20750             {
20751               errmsg ("incorrect range parameters");
20752               return -99;
20753             }
20754           this_low = tmp;
20755           /* Note: in debug CLI +1 is added to high before
20756              passing to real fn that does "the work"
20757              (ip_source_and_port_range_check_add_del).
20758              This fn is a wrapper around the binary API fn a
20759              control plane will call, which expects this increment
20760              to have occurred. Hence letting the binary API control
20761              plane fn do the increment for consistency between VAT
20762              and other control planes.
20763            */
20764           this_hi = tmp2;
20765           vec_add1 (low_ports, this_low);
20766           vec_add1 (high_ports, this_hi);
20767         }
20768       else
20769         break;
20770     }
20771
20772   if (prefix_set == 0)
20773     {
20774       errmsg ("<address>/<mask> not specified");
20775       return -99;
20776     }
20777
20778   if (vrf_id == ~0)
20779     {
20780       errmsg ("VRF ID required, not specified");
20781       return -99;
20782     }
20783
20784   if (vrf_id == 0)
20785     {
20786       errmsg
20787         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20788       return -99;
20789     }
20790
20791   if (vec_len (low_ports) == 0)
20792     {
20793       errmsg ("At least one port or port range required");
20794       return -99;
20795     }
20796
20797   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20798
20799   mp->is_add = is_add;
20800
20801   if (is_ipv6)
20802     {
20803       mp->is_ipv6 = 1;
20804       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20805     }
20806   else
20807     {
20808       mp->is_ipv6 = 0;
20809       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20810     }
20811
20812   mp->mask_length = length;
20813   mp->number_of_ranges = vec_len (low_ports);
20814
20815   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20816   vec_free (low_ports);
20817
20818   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20819   vec_free (high_ports);
20820
20821   mp->vrf_id = ntohl (vrf_id);
20822
20823   S (mp);
20824   W (ret);
20825   return ret;
20826 }
20827
20828 int
20829 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20830 {
20831   unformat_input_t *input = vam->input;
20832   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20833   u32 sw_if_index = ~0;
20834   int vrf_set = 0;
20835   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20836   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20837   u8 is_add = 1;
20838   int ret;
20839
20840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20841     {
20842       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20843         ;
20844       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20845         ;
20846       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20847         vrf_set = 1;
20848       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20849         vrf_set = 1;
20850       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20851         vrf_set = 1;
20852       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20853         vrf_set = 1;
20854       else if (unformat (input, "del"))
20855         is_add = 0;
20856       else
20857         break;
20858     }
20859
20860   if (sw_if_index == ~0)
20861     {
20862       errmsg ("Interface required but not specified");
20863       return -99;
20864     }
20865
20866   if (vrf_set == 0)
20867     {
20868       errmsg ("VRF ID required but not specified");
20869       return -99;
20870     }
20871
20872   if (tcp_out_vrf_id == 0
20873       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20874     {
20875       errmsg
20876         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20877       return -99;
20878     }
20879
20880   /* Construct the API message */
20881   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20882
20883   mp->sw_if_index = ntohl (sw_if_index);
20884   mp->is_add = is_add;
20885   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20886   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20887   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20888   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20889
20890   /* send it... */
20891   S (mp);
20892
20893   /* Wait for a reply... */
20894   W (ret);
20895   return ret;
20896 }
20897
20898 static int
20899 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20900 {
20901   unformat_input_t *i = vam->input;
20902   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20903   u32 local_sa_id = 0;
20904   u32 remote_sa_id = 0;
20905   ip4_address_t src_address;
20906   ip4_address_t dst_address;
20907   u8 is_add = 1;
20908   int ret;
20909
20910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20911     {
20912       if (unformat (i, "local_sa %d", &local_sa_id))
20913         ;
20914       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20915         ;
20916       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20917         ;
20918       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20919         ;
20920       else if (unformat (i, "del"))
20921         is_add = 0;
20922       else
20923         {
20924           clib_warning ("parse error '%U'", format_unformat_error, i);
20925           return -99;
20926         }
20927     }
20928
20929   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20930
20931   mp->local_sa_id = ntohl (local_sa_id);
20932   mp->remote_sa_id = ntohl (remote_sa_id);
20933   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20934   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20935   mp->is_add = is_add;
20936
20937   S (mp);
20938   W (ret);
20939   return ret;
20940 }
20941
20942 static int
20943 api_punt (vat_main_t * vam)
20944 {
20945   unformat_input_t *i = vam->input;
20946   vl_api_punt_t *mp;
20947   u32 ipv = ~0;
20948   u32 protocol = ~0;
20949   u32 port = ~0;
20950   int is_add = 1;
20951   int ret;
20952
20953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20954     {
20955       if (unformat (i, "ip %d", &ipv))
20956         ;
20957       else if (unformat (i, "protocol %d", &protocol))
20958         ;
20959       else if (unformat (i, "port %d", &port))
20960         ;
20961       else if (unformat (i, "del"))
20962         is_add = 0;
20963       else
20964         {
20965           clib_warning ("parse error '%U'", format_unformat_error, i);
20966           return -99;
20967         }
20968     }
20969
20970   M (PUNT, mp);
20971
20972   mp->is_add = (u8) is_add;
20973   mp->ipv = (u8) ipv;
20974   mp->l4_protocol = (u8) protocol;
20975   mp->l4_port = htons ((u16) port);
20976
20977   S (mp);
20978   W (ret);
20979   return ret;
20980 }
20981
20982 static void vl_api_ipsec_gre_tunnel_details_t_handler
20983   (vl_api_ipsec_gre_tunnel_details_t * mp)
20984 {
20985   vat_main_t *vam = &vat_main;
20986
20987   print (vam->ofp, "%11d%15U%15U%14d%14d",
20988          ntohl (mp->sw_if_index),
20989          format_ip4_address, &mp->src_address,
20990          format_ip4_address, &mp->dst_address,
20991          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20992 }
20993
20994 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20995   (vl_api_ipsec_gre_tunnel_details_t * mp)
20996 {
20997   vat_main_t *vam = &vat_main;
20998   vat_json_node_t *node = NULL;
20999   struct in_addr ip4;
21000
21001   if (VAT_JSON_ARRAY != vam->json_tree.type)
21002     {
21003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21004       vat_json_init_array (&vam->json_tree);
21005     }
21006   node = vat_json_array_add (&vam->json_tree);
21007
21008   vat_json_init_object (node);
21009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21010   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21011   vat_json_object_add_ip4 (node, "src_address", ip4);
21012   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21013   vat_json_object_add_ip4 (node, "dst_address", ip4);
21014   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21015   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21016 }
21017
21018 static int
21019 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21020 {
21021   unformat_input_t *i = vam->input;
21022   vl_api_ipsec_gre_tunnel_dump_t *mp;
21023   vl_api_control_ping_t *mp_ping;
21024   u32 sw_if_index;
21025   u8 sw_if_index_set = 0;
21026   int ret;
21027
21028   /* Parse args required to build the message */
21029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21030     {
21031       if (unformat (i, "sw_if_index %d", &sw_if_index))
21032         sw_if_index_set = 1;
21033       else
21034         break;
21035     }
21036
21037   if (sw_if_index_set == 0)
21038     {
21039       sw_if_index = ~0;
21040     }
21041
21042   if (!vam->json_output)
21043     {
21044       print (vam->ofp, "%11s%15s%15s%14s%14s",
21045              "sw_if_index", "src_address", "dst_address",
21046              "local_sa_id", "remote_sa_id");
21047     }
21048
21049   /* Get list of gre-tunnel interfaces */
21050   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21051
21052   mp->sw_if_index = htonl (sw_if_index);
21053
21054   S (mp);
21055
21056   /* Use a control ping for synchronization */
21057   MPING (CONTROL_PING, mp_ping);
21058   S (mp_ping);
21059
21060   W (ret);
21061   return ret;
21062 }
21063
21064 static int
21065 api_delete_subif (vat_main_t * vam)
21066 {
21067   unformat_input_t *i = vam->input;
21068   vl_api_delete_subif_t *mp;
21069   u32 sw_if_index = ~0;
21070   int ret;
21071
21072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21073     {
21074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21075         ;
21076       if (unformat (i, "sw_if_index %d", &sw_if_index))
21077         ;
21078       else
21079         break;
21080     }
21081
21082   if (sw_if_index == ~0)
21083     {
21084       errmsg ("missing sw_if_index");
21085       return -99;
21086     }
21087
21088   /* Construct the API message */
21089   M (DELETE_SUBIF, mp);
21090   mp->sw_if_index = ntohl (sw_if_index);
21091
21092   S (mp);
21093   W (ret);
21094   return ret;
21095 }
21096
21097 #define foreach_pbb_vtr_op      \
21098 _("disable",  L2_VTR_DISABLED)  \
21099 _("pop",  L2_VTR_POP_2)         \
21100 _("push",  L2_VTR_PUSH_2)
21101
21102 static int
21103 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21104 {
21105   unformat_input_t *i = vam->input;
21106   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21107   u32 sw_if_index = ~0, vtr_op = ~0;
21108   u16 outer_tag = ~0;
21109   u8 dmac[6], smac[6];
21110   u8 dmac_set = 0, smac_set = 0;
21111   u16 vlanid = 0;
21112   u32 sid = ~0;
21113   u32 tmp;
21114   int ret;
21115
21116   /* Shut up coverity */
21117   memset (dmac, 0, sizeof (dmac));
21118   memset (smac, 0, sizeof (smac));
21119
21120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21121     {
21122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21123         ;
21124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21125         ;
21126       else if (unformat (i, "vtr_op %d", &vtr_op))
21127         ;
21128 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21129       foreach_pbb_vtr_op
21130 #undef _
21131         else if (unformat (i, "translate_pbb_stag"))
21132         {
21133           if (unformat (i, "%d", &tmp))
21134             {
21135               vtr_op = L2_VTR_TRANSLATE_2_1;
21136               outer_tag = tmp;
21137             }
21138           else
21139             {
21140               errmsg
21141                 ("translate_pbb_stag operation requires outer tag definition");
21142               return -99;
21143             }
21144         }
21145       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21146         dmac_set++;
21147       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21148         smac_set++;
21149       else if (unformat (i, "sid %d", &sid))
21150         ;
21151       else if (unformat (i, "vlanid %d", &tmp))
21152         vlanid = tmp;
21153       else
21154         {
21155           clib_warning ("parse error '%U'", format_unformat_error, i);
21156           return -99;
21157         }
21158     }
21159
21160   if ((sw_if_index == ~0) || (vtr_op == ~0))
21161     {
21162       errmsg ("missing sw_if_index or vtr operation");
21163       return -99;
21164     }
21165   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21166       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21167     {
21168       errmsg
21169         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21170       return -99;
21171     }
21172
21173   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21174   mp->sw_if_index = ntohl (sw_if_index);
21175   mp->vtr_op = ntohl (vtr_op);
21176   mp->outer_tag = ntohs (outer_tag);
21177   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21178   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21179   mp->b_vlanid = ntohs (vlanid);
21180   mp->i_sid = ntohl (sid);
21181
21182   S (mp);
21183   W (ret);
21184   return ret;
21185 }
21186
21187 static int
21188 api_flow_classify_set_interface (vat_main_t * vam)
21189 {
21190   unformat_input_t *i = vam->input;
21191   vl_api_flow_classify_set_interface_t *mp;
21192   u32 sw_if_index;
21193   int sw_if_index_set;
21194   u32 ip4_table_index = ~0;
21195   u32 ip6_table_index = ~0;
21196   u8 is_add = 1;
21197   int ret;
21198
21199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21200     {
21201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21202         sw_if_index_set = 1;
21203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21204         sw_if_index_set = 1;
21205       else if (unformat (i, "del"))
21206         is_add = 0;
21207       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21208         ;
21209       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21210         ;
21211       else
21212         {
21213           clib_warning ("parse error '%U'", format_unformat_error, i);
21214           return -99;
21215         }
21216     }
21217
21218   if (sw_if_index_set == 0)
21219     {
21220       errmsg ("missing interface name or sw_if_index");
21221       return -99;
21222     }
21223
21224   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21225
21226   mp->sw_if_index = ntohl (sw_if_index);
21227   mp->ip4_table_index = ntohl (ip4_table_index);
21228   mp->ip6_table_index = ntohl (ip6_table_index);
21229   mp->is_add = is_add;
21230
21231   S (mp);
21232   W (ret);
21233   return ret;
21234 }
21235
21236 static int
21237 api_flow_classify_dump (vat_main_t * vam)
21238 {
21239   unformat_input_t *i = vam->input;
21240   vl_api_flow_classify_dump_t *mp;
21241   vl_api_control_ping_t *mp_ping;
21242   u8 type = FLOW_CLASSIFY_N_TABLES;
21243   int ret;
21244
21245   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21246     ;
21247   else
21248     {
21249       errmsg ("classify table type must be specified");
21250       return -99;
21251     }
21252
21253   if (!vam->json_output)
21254     {
21255       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21256     }
21257
21258   M (FLOW_CLASSIFY_DUMP, mp);
21259   mp->type = type;
21260   /* send it... */
21261   S (mp);
21262
21263   /* Use a control ping for synchronization */
21264   MPING (CONTROL_PING, mp_ping);
21265   S (mp_ping);
21266
21267   /* Wait for a reply... */
21268   W (ret);
21269   return ret;
21270 }
21271
21272 static int
21273 api_feature_enable_disable (vat_main_t * vam)
21274 {
21275   unformat_input_t *i = vam->input;
21276   vl_api_feature_enable_disable_t *mp;
21277   u8 *arc_name = 0;
21278   u8 *feature_name = 0;
21279   u32 sw_if_index = ~0;
21280   u8 enable = 1;
21281   int ret;
21282
21283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21284     {
21285       if (unformat (i, "arc_name %s", &arc_name))
21286         ;
21287       else if (unformat (i, "feature_name %s", &feature_name))
21288         ;
21289       else
21290         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21291         ;
21292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21293         ;
21294       else if (unformat (i, "disable"))
21295         enable = 0;
21296       else
21297         break;
21298     }
21299
21300   if (arc_name == 0)
21301     {
21302       errmsg ("missing arc name");
21303       return -99;
21304     }
21305   if (vec_len (arc_name) > 63)
21306     {
21307       errmsg ("arc name too long");
21308     }
21309
21310   if (feature_name == 0)
21311     {
21312       errmsg ("missing feature name");
21313       return -99;
21314     }
21315   if (vec_len (feature_name) > 63)
21316     {
21317       errmsg ("feature name too long");
21318     }
21319
21320   if (sw_if_index == ~0)
21321     {
21322       errmsg ("missing interface name or sw_if_index");
21323       return -99;
21324     }
21325
21326   /* Construct the API message */
21327   M (FEATURE_ENABLE_DISABLE, mp);
21328   mp->sw_if_index = ntohl (sw_if_index);
21329   mp->enable = enable;
21330   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21331   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21332   vec_free (arc_name);
21333   vec_free (feature_name);
21334
21335   S (mp);
21336   W (ret);
21337   return ret;
21338 }
21339
21340 static int
21341 api_sw_interface_tag_add_del (vat_main_t * vam)
21342 {
21343   unformat_input_t *i = vam->input;
21344   vl_api_sw_interface_tag_add_del_t *mp;
21345   u32 sw_if_index = ~0;
21346   u8 *tag = 0;
21347   u8 enable = 1;
21348   int ret;
21349
21350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21351     {
21352       if (unformat (i, "tag %s", &tag))
21353         ;
21354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21355         ;
21356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21357         ;
21358       else if (unformat (i, "del"))
21359         enable = 0;
21360       else
21361         break;
21362     }
21363
21364   if (sw_if_index == ~0)
21365     {
21366       errmsg ("missing interface name or sw_if_index");
21367       return -99;
21368     }
21369
21370   if (enable && (tag == 0))
21371     {
21372       errmsg ("no tag specified");
21373       return -99;
21374     }
21375
21376   /* Construct the API message */
21377   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21378   mp->sw_if_index = ntohl (sw_if_index);
21379   mp->is_add = enable;
21380   if (enable)
21381     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21382   vec_free (tag);
21383
21384   S (mp);
21385   W (ret);
21386   return ret;
21387 }
21388
21389 static void vl_api_l2_xconnect_details_t_handler
21390   (vl_api_l2_xconnect_details_t * mp)
21391 {
21392   vat_main_t *vam = &vat_main;
21393
21394   print (vam->ofp, "%15d%15d",
21395          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21396 }
21397
21398 static void vl_api_l2_xconnect_details_t_handler_json
21399   (vl_api_l2_xconnect_details_t * mp)
21400 {
21401   vat_main_t *vam = &vat_main;
21402   vat_json_node_t *node = NULL;
21403
21404   if (VAT_JSON_ARRAY != vam->json_tree.type)
21405     {
21406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21407       vat_json_init_array (&vam->json_tree);
21408     }
21409   node = vat_json_array_add (&vam->json_tree);
21410
21411   vat_json_init_object (node);
21412   vat_json_object_add_uint (node, "rx_sw_if_index",
21413                             ntohl (mp->rx_sw_if_index));
21414   vat_json_object_add_uint (node, "tx_sw_if_index",
21415                             ntohl (mp->tx_sw_if_index));
21416 }
21417
21418 static int
21419 api_l2_xconnect_dump (vat_main_t * vam)
21420 {
21421   vl_api_l2_xconnect_dump_t *mp;
21422   vl_api_control_ping_t *mp_ping;
21423   int ret;
21424
21425   if (!vam->json_output)
21426     {
21427       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21428     }
21429
21430   M (L2_XCONNECT_DUMP, mp);
21431
21432   S (mp);
21433
21434   /* Use a control ping for synchronization */
21435   MPING (CONTROL_PING, mp_ping);
21436   S (mp_ping);
21437
21438   W (ret);
21439   return ret;
21440 }
21441
21442 static int
21443 api_sw_interface_set_mtu (vat_main_t * vam)
21444 {
21445   unformat_input_t *i = vam->input;
21446   vl_api_sw_interface_set_mtu_t *mp;
21447   u32 sw_if_index = ~0;
21448   u32 mtu = 0;
21449   int ret;
21450
21451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21452     {
21453       if (unformat (i, "mtu %d", &mtu))
21454         ;
21455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21456         ;
21457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21458         ;
21459       else
21460         break;
21461     }
21462
21463   if (sw_if_index == ~0)
21464     {
21465       errmsg ("missing interface name or sw_if_index");
21466       return -99;
21467     }
21468
21469   if (mtu == 0)
21470     {
21471       errmsg ("no mtu specified");
21472       return -99;
21473     }
21474
21475   /* Construct the API message */
21476   M (SW_INTERFACE_SET_MTU, mp);
21477   mp->sw_if_index = ntohl (sw_if_index);
21478   mp->mtu = ntohs ((u16) mtu);
21479
21480   S (mp);
21481   W (ret);
21482   return ret;
21483 }
21484
21485 static int
21486 api_p2p_ethernet_add (vat_main_t * vam)
21487 {
21488   unformat_input_t *i = vam->input;
21489   vl_api_p2p_ethernet_add_t *mp;
21490   u32 parent_if_index = ~0;
21491   u32 sub_id = ~0;
21492   u8 remote_mac[6];
21493   u8 mac_set = 0;
21494   int ret;
21495
21496   memset (remote_mac, 0, sizeof (remote_mac));
21497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21498     {
21499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21500         ;
21501       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21502         ;
21503       else
21504         if (unformat
21505             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21506         mac_set++;
21507       else if (unformat (i, "sub_id %d", &sub_id))
21508         ;
21509       else
21510         {
21511           clib_warning ("parse error '%U'", format_unformat_error, i);
21512           return -99;
21513         }
21514     }
21515
21516   if (parent_if_index == ~0)
21517     {
21518       errmsg ("missing interface name or sw_if_index");
21519       return -99;
21520     }
21521   if (mac_set == 0)
21522     {
21523       errmsg ("missing remote mac address");
21524       return -99;
21525     }
21526   if (sub_id == ~0)
21527     {
21528       errmsg ("missing sub-interface id");
21529       return -99;
21530     }
21531
21532   M (P2P_ETHERNET_ADD, mp);
21533   mp->parent_if_index = ntohl (parent_if_index);
21534   mp->subif_id = ntohl (sub_id);
21535   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21536
21537   S (mp);
21538   W (ret);
21539   return ret;
21540 }
21541
21542 static int
21543 api_p2p_ethernet_del (vat_main_t * vam)
21544 {
21545   unformat_input_t *i = vam->input;
21546   vl_api_p2p_ethernet_del_t *mp;
21547   u32 parent_if_index = ~0;
21548   u8 remote_mac[6];
21549   u8 mac_set = 0;
21550   int ret;
21551
21552   memset (remote_mac, 0, sizeof (remote_mac));
21553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21554     {
21555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21556         ;
21557       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21558         ;
21559       else
21560         if (unformat
21561             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21562         mac_set++;
21563       else
21564         {
21565           clib_warning ("parse error '%U'", format_unformat_error, i);
21566           return -99;
21567         }
21568     }
21569
21570   if (parent_if_index == ~0)
21571     {
21572       errmsg ("missing interface name or sw_if_index");
21573       return -99;
21574     }
21575   if (mac_set == 0)
21576     {
21577       errmsg ("missing remote mac address");
21578       return -99;
21579     }
21580
21581   M (P2P_ETHERNET_DEL, mp);
21582   mp->parent_if_index = ntohl (parent_if_index);
21583   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21584
21585   S (mp);
21586   W (ret);
21587   return ret;
21588 }
21589
21590 static int
21591 api_lldp_config (vat_main_t * vam)
21592 {
21593   unformat_input_t *i = vam->input;
21594   vl_api_lldp_config_t *mp;
21595   int tx_hold = 0;
21596   int tx_interval = 0;
21597   u8 *sys_name = NULL;
21598   int ret;
21599
21600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21601     {
21602       if (unformat (i, "system-name %s", &sys_name))
21603         ;
21604       else if (unformat (i, "tx-hold %d", &tx_hold))
21605         ;
21606       else if (unformat (i, "tx-interval %d", &tx_interval))
21607         ;
21608       else
21609         {
21610           clib_warning ("parse error '%U'", format_unformat_error, i);
21611           return -99;
21612         }
21613     }
21614
21615   vec_add1 (sys_name, 0);
21616
21617   M (LLDP_CONFIG, mp);
21618   mp->tx_hold = htonl (tx_hold);
21619   mp->tx_interval = htonl (tx_interval);
21620   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21621   vec_free (sys_name);
21622
21623   S (mp);
21624   W (ret);
21625   return ret;
21626 }
21627
21628 static int
21629 api_sw_interface_set_lldp (vat_main_t * vam)
21630 {
21631   unformat_input_t *i = vam->input;
21632   vl_api_sw_interface_set_lldp_t *mp;
21633   u32 sw_if_index = ~0;
21634   u32 enable = 1;
21635   u8 *port_desc = NULL, *mgmt_oid = NULL;
21636   ip4_address_t ip4_addr;
21637   ip6_address_t ip6_addr;
21638   int ret;
21639
21640   memset (&ip4_addr, 0, sizeof (ip4_addr));
21641   memset (&ip6_addr, 0, sizeof (ip6_addr));
21642
21643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21644     {
21645       if (unformat (i, "disable"))
21646         enable = 0;
21647       else
21648         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21649         ;
21650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21651         ;
21652       else if (unformat (i, "port-desc %s", &port_desc))
21653         ;
21654       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21655         ;
21656       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21657         ;
21658       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21659         ;
21660       else
21661         break;
21662     }
21663
21664   if (sw_if_index == ~0)
21665     {
21666       errmsg ("missing interface name or sw_if_index");
21667       return -99;
21668     }
21669
21670   /* Construct the API message */
21671   vec_add1 (port_desc, 0);
21672   vec_add1 (mgmt_oid, 0);
21673   M (SW_INTERFACE_SET_LLDP, mp);
21674   mp->sw_if_index = ntohl (sw_if_index);
21675   mp->enable = enable;
21676   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21677   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21678   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21679   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21680   vec_free (port_desc);
21681   vec_free (mgmt_oid);
21682
21683   S (mp);
21684   W (ret);
21685   return ret;
21686 }
21687
21688 static int
21689 api_tcp_configure_src_addresses (vat_main_t * vam)
21690 {
21691   vl_api_tcp_configure_src_addresses_t *mp;
21692   unformat_input_t *i = vam->input;
21693   ip4_address_t v4first, v4last;
21694   ip6_address_t v6first, v6last;
21695   u8 range_set = 0;
21696   u32 vrf_id = 0;
21697   int ret;
21698
21699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21700     {
21701       if (unformat (i, "%U - %U",
21702                     unformat_ip4_address, &v4first,
21703                     unformat_ip4_address, &v4last))
21704         {
21705           if (range_set)
21706             {
21707               errmsg ("one range per message (range already set)");
21708               return -99;
21709             }
21710           range_set = 1;
21711         }
21712       else if (unformat (i, "%U - %U",
21713                          unformat_ip6_address, &v6first,
21714                          unformat_ip6_address, &v6last))
21715         {
21716           if (range_set)
21717             {
21718               errmsg ("one range per message (range already set)");
21719               return -99;
21720             }
21721           range_set = 2;
21722         }
21723       else if (unformat (i, "vrf %d", &vrf_id))
21724         ;
21725       else
21726         break;
21727     }
21728
21729   if (range_set == 0)
21730     {
21731       errmsg ("address range not set");
21732       return -99;
21733     }
21734
21735   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21736   mp->vrf_id = ntohl (vrf_id);
21737   /* ipv6? */
21738   if (range_set == 2)
21739     {
21740       mp->is_ipv6 = 1;
21741       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21742       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21743     }
21744   else
21745     {
21746       mp->is_ipv6 = 0;
21747       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21748       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21749     }
21750   S (mp);
21751   W (ret);
21752   return ret;
21753 }
21754
21755 static void vl_api_app_namespace_add_del_reply_t_handler
21756   (vl_api_app_namespace_add_del_reply_t * mp)
21757 {
21758   vat_main_t *vam = &vat_main;
21759   i32 retval = ntohl (mp->retval);
21760   if (vam->async_mode)
21761     {
21762       vam->async_errors += (retval < 0);
21763     }
21764   else
21765     {
21766       vam->retval = retval;
21767       if (retval == 0)
21768         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21769       vam->result_ready = 1;
21770     }
21771 }
21772
21773 static void vl_api_app_namespace_add_del_reply_t_handler_json
21774   (vl_api_app_namespace_add_del_reply_t * mp)
21775 {
21776   vat_main_t *vam = &vat_main;
21777   vat_json_node_t node;
21778
21779   vat_json_init_object (&node);
21780   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21781   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21782
21783   vat_json_print (vam->ofp, &node);
21784   vat_json_free (&node);
21785
21786   vam->retval = ntohl (mp->retval);
21787   vam->result_ready = 1;
21788 }
21789
21790 static int
21791 api_app_namespace_add_del (vat_main_t * vam)
21792 {
21793   vl_api_app_namespace_add_del_t *mp;
21794   unformat_input_t *i = vam->input;
21795   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21796   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21797   u64 secret;
21798   int ret;
21799
21800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21801     {
21802       if (unformat (i, "id %_%v%_", &ns_id))
21803         ;
21804       else if (unformat (i, "secret %lu", &secret))
21805         secret_set = 1;
21806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21807         sw_if_index_set = 1;
21808       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21809         ;
21810       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21811         ;
21812       else
21813         break;
21814     }
21815   if (!ns_id || !secret_set || !sw_if_index_set)
21816     {
21817       errmsg ("namespace id, secret and sw_if_index must be set");
21818       return -99;
21819     }
21820   if (vec_len (ns_id) > 64)
21821     {
21822       errmsg ("namespace id too long");
21823       return -99;
21824     }
21825   M (APP_NAMESPACE_ADD_DEL, mp);
21826
21827   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21828   mp->namespace_id_len = vec_len (ns_id);
21829   mp->secret = clib_host_to_net_u64 (secret);
21830   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21831   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21832   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21833   vec_free (ns_id);
21834   S (mp);
21835   W (ret);
21836   return ret;
21837 }
21838
21839 static int
21840 api_memfd_segment_create (vat_main_t * vam)
21841 {
21842 #if VPP_API_TEST_BUILTIN == 0
21843   unformat_input_t *i = vam->input;
21844   vl_api_memfd_segment_create_t *mp;
21845   u64 size = 64 << 20;
21846   int ret;
21847
21848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21849     {
21850       if (unformat (i, "size %U", unformat_memory_size, &size))
21851         ;
21852       else
21853         break;
21854     }
21855
21856   M (MEMFD_SEGMENT_CREATE, mp);
21857   mp->requested_size = size;
21858   S (mp);
21859   W (ret);
21860   return ret;
21861
21862 #else
21863   errmsg ("memfd_segment_create (builtin) not supported");
21864   return -99;
21865 #endif
21866 }
21867
21868 static int
21869 api_dns_enable_disable (vat_main_t * vam)
21870 {
21871   unformat_input_t *line_input = vam->input;
21872   vl_api_dns_enable_disable_t *mp;
21873   u8 enable_disable = 1;
21874   int ret;
21875
21876   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21877     {
21878       if (unformat (line_input, "disable"))
21879         enable_disable = 0;
21880       if (unformat (line_input, "enable"))
21881         enable_disable = 1;
21882       else
21883         break;
21884     }
21885
21886   /* Construct the API message */
21887   M (DNS_ENABLE_DISABLE, mp);
21888   mp->enable = enable_disable;
21889
21890   /* send it... */
21891   S (mp);
21892   /* Wait for the reply */
21893   W (ret);
21894   return ret;
21895 }
21896
21897 static int
21898 api_dns_resolve_name (vat_main_t * vam)
21899 {
21900   unformat_input_t *line_input = vam->input;
21901   vl_api_dns_resolve_name_t *mp;
21902   u8 *name = 0;
21903   int ret;
21904
21905   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21906     {
21907       if (unformat (line_input, "%s", &name))
21908         ;
21909       else
21910         break;
21911     }
21912
21913   if (vec_len (name) > 127)
21914     {
21915       errmsg ("name too long");
21916       return -99;
21917     }
21918
21919   /* Construct the API message */
21920   M (DNS_RESOLVE_NAME, mp);
21921   memcpy (mp->name, name, vec_len (name));
21922   vec_free (name);
21923
21924   /* send it... */
21925   S (mp);
21926   /* Wait for the reply */
21927   W (ret);
21928   return ret;
21929 }
21930
21931 static int
21932 api_dns_resolve_ip (vat_main_t * vam)
21933 {
21934   unformat_input_t *line_input = vam->input;
21935   vl_api_dns_resolve_ip_t *mp;
21936   int is_ip6 = -1;
21937   ip4_address_t addr4;
21938   ip6_address_t addr6;
21939   int ret;
21940
21941   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21942     {
21943       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21944         is_ip6 = 1;
21945       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21946         is_ip6 = 0;
21947       else
21948         break;
21949     }
21950
21951   if (is_ip6 == -1)
21952     {
21953       errmsg ("missing address");
21954       return -99;
21955     }
21956
21957   /* Construct the API message */
21958   M (DNS_RESOLVE_IP, mp);
21959   mp->is_ip6 = is_ip6;
21960   if (is_ip6)
21961     memcpy (mp->address, &addr6, sizeof (addr6));
21962   else
21963     memcpy (mp->address, &addr4, sizeof (addr4));
21964
21965   /* send it... */
21966   S (mp);
21967   /* Wait for the reply */
21968   W (ret);
21969   return ret;
21970 }
21971
21972 static int
21973 api_dns_name_server_add_del (vat_main_t * vam)
21974 {
21975   unformat_input_t *i = vam->input;
21976   vl_api_dns_name_server_add_del_t *mp;
21977   u8 is_add = 1;
21978   ip6_address_t ip6_server;
21979   ip4_address_t ip4_server;
21980   int ip6_set = 0;
21981   int ip4_set = 0;
21982   int ret = 0;
21983
21984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21985     {
21986       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21987         ip6_set = 1;
21988       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21989         ip4_set = 1;
21990       else if (unformat (i, "del"))
21991         is_add = 0;
21992       else
21993         {
21994           clib_warning ("parse error '%U'", format_unformat_error, i);
21995           return -99;
21996         }
21997     }
21998
21999   if (ip4_set && ip6_set)
22000     {
22001       errmsg ("Only one server address allowed per message");
22002       return -99;
22003     }
22004   if ((ip4_set + ip6_set) == 0)
22005     {
22006       errmsg ("Server address required");
22007       return -99;
22008     }
22009
22010   /* Construct the API message */
22011   M (DNS_NAME_SERVER_ADD_DEL, mp);
22012
22013   if (ip6_set)
22014     {
22015       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22016       mp->is_ip6 = 1;
22017     }
22018   else
22019     {
22020       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22021       mp->is_ip6 = 0;
22022     }
22023
22024   mp->is_add = is_add;
22025
22026   /* send it... */
22027   S (mp);
22028
22029   /* Wait for a reply, return good/bad news  */
22030   W (ret);
22031   return ret;
22032 }
22033
22034 static void
22035 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22036 {
22037   vat_main_t *vam = &vat_main;
22038
22039   if (mp->is_ip4)
22040     {
22041       print (vam->ofp,
22042              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22043              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22044              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22045              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22046              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22047              clib_net_to_host_u32 (mp->action_index), mp->tag);
22048     }
22049   else
22050     {
22051       print (vam->ofp,
22052              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22053              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22054              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22055              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22056              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22057              clib_net_to_host_u32 (mp->action_index), mp->tag);
22058     }
22059 }
22060
22061 static void
22062 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22063                                              mp)
22064 {
22065   vat_main_t *vam = &vat_main;
22066   vat_json_node_t *node = NULL;
22067   struct in6_addr ip6;
22068   struct in_addr ip4;
22069
22070   if (VAT_JSON_ARRAY != vam->json_tree.type)
22071     {
22072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22073       vat_json_init_array (&vam->json_tree);
22074     }
22075   node = vat_json_array_add (&vam->json_tree);
22076   vat_json_init_object (node);
22077
22078   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22079   vat_json_object_add_uint (node, "appns_index",
22080                             clib_net_to_host_u32 (mp->appns_index));
22081   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22082   vat_json_object_add_uint (node, "scope", mp->scope);
22083   vat_json_object_add_uint (node, "action_index",
22084                             clib_net_to_host_u32 (mp->action_index));
22085   vat_json_object_add_uint (node, "lcl_port",
22086                             clib_net_to_host_u16 (mp->lcl_port));
22087   vat_json_object_add_uint (node, "rmt_port",
22088                             clib_net_to_host_u16 (mp->rmt_port));
22089   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22090   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22091   vat_json_object_add_string_copy (node, "tag", mp->tag);
22092   if (mp->is_ip4)
22093     {
22094       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22095       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22096       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22097       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22098     }
22099   else
22100     {
22101       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22102       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22103       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22104       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22105     }
22106 }
22107
22108 static int
22109 api_session_rule_add_del (vat_main_t * vam)
22110 {
22111   vl_api_session_rule_add_del_t *mp;
22112   unformat_input_t *i = vam->input;
22113   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22114   u32 appns_index = 0, scope = 0;
22115   ip4_address_t lcl_ip4, rmt_ip4;
22116   ip6_address_t lcl_ip6, rmt_ip6;
22117   u8 is_ip4 = 1, conn_set = 0;
22118   u8 is_add = 1, *tag = 0;
22119   int ret;
22120
22121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22122     {
22123       if (unformat (i, "del"))
22124         is_add = 0;
22125       else if (unformat (i, "add"))
22126         ;
22127       else if (unformat (i, "proto tcp"))
22128         proto = 0;
22129       else if (unformat (i, "proto udp"))
22130         proto = 1;
22131       else if (unformat (i, "appns %d", &appns_index))
22132         ;
22133       else if (unformat (i, "scope %d", &scope))
22134         ;
22135       else if (unformat (i, "tag %_%v%_", &tag))
22136         ;
22137       else
22138         if (unformat
22139             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22140              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22141              &rmt_port))
22142         {
22143           is_ip4 = 1;
22144           conn_set = 1;
22145         }
22146       else
22147         if (unformat
22148             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22149              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22150              &rmt_port))
22151         {
22152           is_ip4 = 0;
22153           conn_set = 1;
22154         }
22155       else if (unformat (i, "action %d", &action))
22156         ;
22157       else
22158         break;
22159     }
22160   if (proto == ~0 || !conn_set || action == ~0)
22161     {
22162       errmsg ("transport proto, connection and action must be set");
22163       return -99;
22164     }
22165
22166   if (scope > 3)
22167     {
22168       errmsg ("scope should be 0-3");
22169       return -99;
22170     }
22171
22172   M (SESSION_RULE_ADD_DEL, mp);
22173
22174   mp->is_ip4 = is_ip4;
22175   mp->transport_proto = proto;
22176   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22177   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22178   mp->lcl_plen = lcl_plen;
22179   mp->rmt_plen = rmt_plen;
22180   mp->action_index = clib_host_to_net_u32 (action);
22181   mp->appns_index = clib_host_to_net_u32 (appns_index);
22182   mp->scope = scope;
22183   mp->is_add = is_add;
22184   if (is_ip4)
22185     {
22186       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22187       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22188     }
22189   else
22190     {
22191       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22192       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22193     }
22194   if (tag)
22195     {
22196       clib_memcpy (mp->tag, tag, vec_len (tag));
22197       vec_free (tag);
22198     }
22199
22200   S (mp);
22201   W (ret);
22202   return ret;
22203 }
22204
22205 static int
22206 api_session_rules_dump (vat_main_t * vam)
22207 {
22208   vl_api_session_rules_dump_t *mp;
22209   vl_api_control_ping_t *mp_ping;
22210   int ret;
22211
22212   if (!vam->json_output)
22213     {
22214       print (vam->ofp, "%=20s", "Session Rules");
22215     }
22216
22217   M (SESSION_RULES_DUMP, mp);
22218   /* send it... */
22219   S (mp);
22220
22221   /* Use a control ping for synchronization */
22222   MPING (CONTROL_PING, mp_ping);
22223   S (mp_ping);
22224
22225   /* Wait for a reply... */
22226   W (ret);
22227   return ret;
22228 }
22229
22230 static int
22231 api_ip_container_proxy_add_del (vat_main_t * vam)
22232 {
22233   vl_api_ip_container_proxy_add_del_t *mp;
22234   unformat_input_t *i = vam->input;
22235   u32 plen = ~0, sw_if_index = ~0;
22236   ip4_address_t ip4;
22237   ip6_address_t ip6;
22238   u8 is_ip4 = 1;
22239   u8 is_add = 1;
22240   int ret;
22241
22242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22243     {
22244       if (unformat (i, "del"))
22245         is_add = 0;
22246       else if (unformat (i, "add"))
22247         ;
22248       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22249         {
22250           is_ip4 = 1;
22251           plen = 32;
22252         }
22253       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22254         {
22255           is_ip4 = 0;
22256           plen = 128;
22257         }
22258       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22259         ;
22260       else
22261         break;
22262     }
22263   if (sw_if_index == ~0 || plen == ~0)
22264     {
22265       errmsg ("address and sw_if_index must be set");
22266       return -99;
22267     }
22268
22269   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22270
22271   mp->is_ip4 = is_ip4;
22272   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22273   mp->plen = plen;
22274   mp->is_add = is_add;
22275   if (is_ip4)
22276     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22277   else
22278     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22279
22280   S (mp);
22281   W (ret);
22282   return ret;
22283 }
22284
22285 static int
22286 q_or_quit (vat_main_t * vam)
22287 {
22288 #if VPP_API_TEST_BUILTIN == 0
22289   longjmp (vam->jump_buf, 1);
22290 #endif
22291   return 0;                     /* not so much */
22292 }
22293
22294 static int
22295 q (vat_main_t * vam)
22296 {
22297   return q_or_quit (vam);
22298 }
22299
22300 static int
22301 quit (vat_main_t * vam)
22302 {
22303   return q_or_quit (vam);
22304 }
22305
22306 static int
22307 comment (vat_main_t * vam)
22308 {
22309   return 0;
22310 }
22311
22312 static int
22313 cmd_cmp (void *a1, void *a2)
22314 {
22315   u8 **c1 = a1;
22316   u8 **c2 = a2;
22317
22318   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22319 }
22320
22321 static int
22322 help (vat_main_t * vam)
22323 {
22324   u8 **cmds = 0;
22325   u8 *name = 0;
22326   hash_pair_t *p;
22327   unformat_input_t *i = vam->input;
22328   int j;
22329
22330   if (unformat (i, "%s", &name))
22331     {
22332       uword *hs;
22333
22334       vec_add1 (name, 0);
22335
22336       hs = hash_get_mem (vam->help_by_name, name);
22337       if (hs)
22338         print (vam->ofp, "usage: %s %s", name, hs[0]);
22339       else
22340         print (vam->ofp, "No such msg / command '%s'", name);
22341       vec_free (name);
22342       return 0;
22343     }
22344
22345   print (vam->ofp, "Help is available for the following:");
22346
22347     /* *INDENT-OFF* */
22348     hash_foreach_pair (p, vam->function_by_name,
22349     ({
22350       vec_add1 (cmds, (u8 *)(p->key));
22351     }));
22352     /* *INDENT-ON* */
22353
22354   vec_sort_with_function (cmds, cmd_cmp);
22355
22356   for (j = 0; j < vec_len (cmds); j++)
22357     print (vam->ofp, "%s", cmds[j]);
22358
22359   vec_free (cmds);
22360   return 0;
22361 }
22362
22363 static int
22364 set (vat_main_t * vam)
22365 {
22366   u8 *name = 0, *value = 0;
22367   unformat_input_t *i = vam->input;
22368
22369   if (unformat (i, "%s", &name))
22370     {
22371       /* The input buffer is a vector, not a string. */
22372       value = vec_dup (i->buffer);
22373       vec_delete (value, i->index, 0);
22374       /* Almost certainly has a trailing newline */
22375       if (value[vec_len (value) - 1] == '\n')
22376         value[vec_len (value) - 1] = 0;
22377       /* Make sure it's a proper string, one way or the other */
22378       vec_add1 (value, 0);
22379       (void) clib_macro_set_value (&vam->macro_main,
22380                                    (char *) name, (char *) value);
22381     }
22382   else
22383     errmsg ("usage: set <name> <value>");
22384
22385   vec_free (name);
22386   vec_free (value);
22387   return 0;
22388 }
22389
22390 static int
22391 unset (vat_main_t * vam)
22392 {
22393   u8 *name = 0;
22394
22395   if (unformat (vam->input, "%s", &name))
22396     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22397       errmsg ("unset: %s wasn't set", name);
22398   vec_free (name);
22399   return 0;
22400 }
22401
22402 typedef struct
22403 {
22404   u8 *name;
22405   u8 *value;
22406 } macro_sort_t;
22407
22408
22409 static int
22410 macro_sort_cmp (void *a1, void *a2)
22411 {
22412   macro_sort_t *s1 = a1;
22413   macro_sort_t *s2 = a2;
22414
22415   return strcmp ((char *) (s1->name), (char *) (s2->name));
22416 }
22417
22418 static int
22419 dump_macro_table (vat_main_t * vam)
22420 {
22421   macro_sort_t *sort_me = 0, *sm;
22422   int i;
22423   hash_pair_t *p;
22424
22425     /* *INDENT-OFF* */
22426     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22427     ({
22428       vec_add2 (sort_me, sm, 1);
22429       sm->name = (u8 *)(p->key);
22430       sm->value = (u8 *) (p->value[0]);
22431     }));
22432     /* *INDENT-ON* */
22433
22434   vec_sort_with_function (sort_me, macro_sort_cmp);
22435
22436   if (vec_len (sort_me))
22437     print (vam->ofp, "%-15s%s", "Name", "Value");
22438   else
22439     print (vam->ofp, "The macro table is empty...");
22440
22441   for (i = 0; i < vec_len (sort_me); i++)
22442     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22443   return 0;
22444 }
22445
22446 static int
22447 dump_node_table (vat_main_t * vam)
22448 {
22449   int i, j;
22450   vlib_node_t *node, *next_node;
22451
22452   if (vec_len (vam->graph_nodes) == 0)
22453     {
22454       print (vam->ofp, "Node table empty, issue get_node_graph...");
22455       return 0;
22456     }
22457
22458   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22459     {
22460       node = vam->graph_nodes[i];
22461       print (vam->ofp, "[%d] %s", i, node->name);
22462       for (j = 0; j < vec_len (node->next_nodes); j++)
22463         {
22464           if (node->next_nodes[j] != ~0)
22465             {
22466               next_node = vam->graph_nodes[node->next_nodes[j]];
22467               print (vam->ofp, "  [%d] %s", j, next_node->name);
22468             }
22469         }
22470     }
22471   return 0;
22472 }
22473
22474 static int
22475 value_sort_cmp (void *a1, void *a2)
22476 {
22477   name_sort_t *n1 = a1;
22478   name_sort_t *n2 = a2;
22479
22480   if (n1->value < n2->value)
22481     return -1;
22482   if (n1->value > n2->value)
22483     return 1;
22484   return 0;
22485 }
22486
22487
22488 static int
22489 dump_msg_api_table (vat_main_t * vam)
22490 {
22491   api_main_t *am = &api_main;
22492   name_sort_t *nses = 0, *ns;
22493   hash_pair_t *hp;
22494   int i;
22495
22496   /* *INDENT-OFF* */
22497   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22498   ({
22499     vec_add2 (nses, ns, 1);
22500     ns->name = (u8 *)(hp->key);
22501     ns->value = (u32) hp->value[0];
22502   }));
22503   /* *INDENT-ON* */
22504
22505   vec_sort_with_function (nses, value_sort_cmp);
22506
22507   for (i = 0; i < vec_len (nses); i++)
22508     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22509   vec_free (nses);
22510   return 0;
22511 }
22512
22513 static int
22514 get_msg_id (vat_main_t * vam)
22515 {
22516   u8 *name_and_crc;
22517   u32 message_index;
22518
22519   if (unformat (vam->input, "%s", &name_and_crc))
22520     {
22521       message_index = vl_api_get_msg_index (name_and_crc);
22522       if (message_index == ~0)
22523         {
22524           print (vam->ofp, " '%s' not found", name_and_crc);
22525           return 0;
22526         }
22527       print (vam->ofp, " '%s' has message index %d",
22528              name_and_crc, message_index);
22529       return 0;
22530     }
22531   errmsg ("name_and_crc required...");
22532   return 0;
22533 }
22534
22535 static int
22536 search_node_table (vat_main_t * vam)
22537 {
22538   unformat_input_t *line_input = vam->input;
22539   u8 *node_to_find;
22540   int j;
22541   vlib_node_t *node, *next_node;
22542   uword *p;
22543
22544   if (vam->graph_node_index_by_name == 0)
22545     {
22546       print (vam->ofp, "Node table empty, issue get_node_graph...");
22547       return 0;
22548     }
22549
22550   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22551     {
22552       if (unformat (line_input, "%s", &node_to_find))
22553         {
22554           vec_add1 (node_to_find, 0);
22555           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22556           if (p == 0)
22557             {
22558               print (vam->ofp, "%s not found...", node_to_find);
22559               goto out;
22560             }
22561           node = vam->graph_nodes[p[0]];
22562           print (vam->ofp, "[%d] %s", p[0], node->name);
22563           for (j = 0; j < vec_len (node->next_nodes); j++)
22564             {
22565               if (node->next_nodes[j] != ~0)
22566                 {
22567                   next_node = vam->graph_nodes[node->next_nodes[j]];
22568                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22569                 }
22570             }
22571         }
22572
22573       else
22574         {
22575           clib_warning ("parse error '%U'", format_unformat_error,
22576                         line_input);
22577           return -99;
22578         }
22579
22580     out:
22581       vec_free (node_to_find);
22582
22583     }
22584
22585   return 0;
22586 }
22587
22588
22589 static int
22590 script (vat_main_t * vam)
22591 {
22592 #if (VPP_API_TEST_BUILTIN==0)
22593   u8 *s = 0;
22594   char *save_current_file;
22595   unformat_input_t save_input;
22596   jmp_buf save_jump_buf;
22597   u32 save_line_number;
22598
22599   FILE *new_fp, *save_ifp;
22600
22601   if (unformat (vam->input, "%s", &s))
22602     {
22603       new_fp = fopen ((char *) s, "r");
22604       if (new_fp == 0)
22605         {
22606           errmsg ("Couldn't open script file %s", s);
22607           vec_free (s);
22608           return -99;
22609         }
22610     }
22611   else
22612     {
22613       errmsg ("Missing script name");
22614       return -99;
22615     }
22616
22617   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22618   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22619   save_ifp = vam->ifp;
22620   save_line_number = vam->input_line_number;
22621   save_current_file = (char *) vam->current_file;
22622
22623   vam->input_line_number = 0;
22624   vam->ifp = new_fp;
22625   vam->current_file = s;
22626   do_one_file (vam);
22627
22628   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22629   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22630   vam->ifp = save_ifp;
22631   vam->input_line_number = save_line_number;
22632   vam->current_file = (u8 *) save_current_file;
22633   vec_free (s);
22634
22635   return 0;
22636 #else
22637   clib_warning ("use the exec command...");
22638   return -99;
22639 #endif
22640 }
22641
22642 static int
22643 echo (vat_main_t * vam)
22644 {
22645   print (vam->ofp, "%v", vam->input->buffer);
22646   return 0;
22647 }
22648
22649 /* List of API message constructors, CLI names map to api_xxx */
22650 #define foreach_vpe_api_msg                                             \
22651 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22652 _(sw_interface_dump,"")                                                 \
22653 _(sw_interface_set_flags,                                               \
22654   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22655 _(sw_interface_add_del_address,                                         \
22656   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22657 _(sw_interface_set_rx_mode,                                             \
22658   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22659 _(sw_interface_set_table,                                               \
22660   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22661 _(sw_interface_set_mpls_enable,                                         \
22662   "<intfc> | sw_if_index [disable | dis]")                              \
22663 _(sw_interface_set_vpath,                                               \
22664   "<intfc> | sw_if_index <id> enable | disable")                        \
22665 _(sw_interface_set_vxlan_bypass,                                        \
22666   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22667 _(sw_interface_set_geneve_bypass,                                       \
22668   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22669 _(sw_interface_set_l2_xconnect,                                         \
22670   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22671   "enable | disable")                                                   \
22672 _(sw_interface_set_l2_bridge,                                           \
22673   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22674   "[shg <split-horizon-group>] [bvi]\n"                                 \
22675   "enable | disable")                                                   \
22676 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22677 _(bridge_domain_add_del,                                                \
22678   "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") \
22679 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22680 _(l2fib_add_del,                                                        \
22681   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22682 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22683 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22684 _(l2_flags,                                                             \
22685   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22686 _(bridge_flags,                                                         \
22687   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22688 _(tap_connect,                                                          \
22689   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22690 _(tap_modify,                                                           \
22691   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22692 _(tap_delete,                                                           \
22693   "<vpp-if-name> | sw_if_index <id>")                                   \
22694 _(sw_interface_tap_dump, "")                                            \
22695 _(tap_create_v2,                                                        \
22696   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22697 _(tap_delete_v2,                                                        \
22698   "<vpp-if-name> | sw_if_index <id>")                                   \
22699 _(sw_interface_tap_v2_dump, "")                                         \
22700 _(ip_table_add_del,                                                     \
22701   "table-id <n> [ipv6]\n")                                              \
22702 _(ip_add_del_route,                                                     \
22703   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22704   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22705   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22706   "[multipath] [count <n>]")                                            \
22707 _(ip_mroute_add_del,                                                    \
22708   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22709   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22710 _(mpls_table_add_del,                                                   \
22711   "table-id <n>\n")                                                     \
22712 _(mpls_route_add_del,                                                   \
22713   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22714   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22715   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22716   "[multipath] [count <n>]")                                            \
22717 _(mpls_ip_bind_unbind,                                                  \
22718   "<label> <addr/len>")                                                 \
22719 _(mpls_tunnel_add_del,                                                  \
22720   " via <addr> [table-id <n>]\n"                                        \
22721   "sw_if_index <id>] [l2]  [del]")                                      \
22722 _(bier_table_add_del,                                                   \
22723   "<label> <sub-domain> <set> <bsl> [del]")                             \
22724 _(bier_route_add_del,                                                   \
22725   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22726   "[<intfc> | sw_if_index <id>]"                                        \
22727   "[weight <n>] [del] [multipath]")                                     \
22728 _(proxy_arp_add_del,                                                    \
22729   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22730 _(proxy_arp_intfc_enable_disable,                                       \
22731   "<intfc> | sw_if_index <id> enable | disable")                        \
22732 _(sw_interface_set_unnumbered,                                          \
22733   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22734 _(ip_neighbor_add_del,                                                  \
22735   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22736   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22737 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22738 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22739   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22740   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22741   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22742 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22743 _(reset_fib, "vrf <n> [ipv6]")                                          \
22744 _(dhcp_proxy_config,                                                    \
22745   "svr <v46-address> src <v46-address>\n"                               \
22746    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22747 _(dhcp_proxy_set_vss,                                                   \
22748   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22749 _(dhcp_proxy_dump, "ip6")                                               \
22750 _(dhcp_client_config,                                                   \
22751   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22752 _(set_ip_flow_hash,                                                     \
22753   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22754 _(sw_interface_ip6_enable_disable,                                      \
22755   "<intfc> | sw_if_index <id> enable | disable")                        \
22756 _(sw_interface_ip6_set_link_local_address,                              \
22757   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22758 _(ip6nd_proxy_add_del,                                                  \
22759   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22760 _(ip6nd_proxy_dump, "")                                                 \
22761 _(sw_interface_ip6nd_ra_prefix,                                         \
22762   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22763   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22764   "[nolink] [isno]")                                                    \
22765 _(sw_interface_ip6nd_ra_config,                                         \
22766   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22767   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22768   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22769 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22770 _(l2_patch_add_del,                                                     \
22771   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22772   "enable | disable")                                                   \
22773 _(sr_localsid_add_del,                                                  \
22774   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22775   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22776 _(classify_add_del_table,                                               \
22777   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22778   " [del] [del-chain] mask <mask-value>\n"                              \
22779   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22780   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22781 _(classify_add_del_session,                                             \
22782   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22783   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22784   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22785   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22786 _(classify_set_interface_ip_table,                                      \
22787   "<intfc> | sw_if_index <nn> table <nn>")                              \
22788 _(classify_set_interface_l2_tables,                                     \
22789   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22790   "  [other-table <nn>]")                                               \
22791 _(get_node_index, "node <node-name")                                    \
22792 _(add_node_next, "node <node-name> next <next-node-name>")              \
22793 _(l2tpv3_create_tunnel,                                                 \
22794   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22795   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22796   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22797 _(l2tpv3_set_tunnel_cookies,                                            \
22798   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22799   "[new_remote_cookie <nn>]\n")                                         \
22800 _(l2tpv3_interface_enable_disable,                                      \
22801   "<intfc> | sw_if_index <nn> enable | disable")                        \
22802 _(l2tpv3_set_lookup_key,                                                \
22803   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22804 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22805 _(vxlan_add_del_tunnel,                                                 \
22806   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22807   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22808   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22809 _(geneve_add_del_tunnel,                                                \
22810   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22811   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22812   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22813 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22814 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22815 _(gre_add_del_tunnel,                                                   \
22816   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22817 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22818 _(l2_fib_clear_table, "")                                               \
22819 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22820 _(l2_interface_vlan_tag_rewrite,                                        \
22821   "<intfc> | sw_if_index <nn> \n"                                       \
22822   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22823   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22824 _(create_vhost_user_if,                                                 \
22825         "socket <filename> [server] [renumber <dev_instance>] "         \
22826         "[mac <mac_address>]")                                          \
22827 _(modify_vhost_user_if,                                                 \
22828         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22829         "[server] [renumber <dev_instance>]")                           \
22830 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22831 _(sw_interface_vhost_user_dump, "")                                     \
22832 _(show_version, "")                                                     \
22833 _(vxlan_gpe_add_del_tunnel,                                             \
22834   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22835   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22836   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22837   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22838 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22839 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22840 _(interface_name_renumber,                                              \
22841   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22842 _(input_acl_set_interface,                                              \
22843   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22844   "  [l2-table <nn>] [del]")                                            \
22845 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22846 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22847 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22848 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22849 _(ip_dump, "ipv4 | ipv6")                                               \
22850 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22851 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22852   "  spid_id <n> ")                                                     \
22853 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22854   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22855   "  integ_alg <alg> integ_key <hex>")                                  \
22856 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22857   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22858   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22859   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22860 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22861 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22862   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22863   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22864   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22865 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22866 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22867   "  <alg> <hex>\n")                                                    \
22868 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22869 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22870 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22871   "(auth_data 0x<data> | auth_data <data>)")                            \
22872 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22873   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22874 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22875   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22876   "(local|remote)")                                                     \
22877 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22878 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22879 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22880 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22881 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22882 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22883 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22884 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22885 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22886 _(delete_loopback,"sw_if_index <nn>")                                   \
22887 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22888 _(map_add_domain,                                                       \
22889   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22890   "ip6-src <ip6addr> "                                                  \
22891   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22892 _(map_del_domain, "index <n>")                                          \
22893 _(map_add_del_rule,                                                     \
22894   "index <n> psid <n> dst <ip6addr> [del]")                             \
22895 _(map_domain_dump, "")                                                  \
22896 _(map_rule_dump, "index <map-domain>")                                  \
22897 _(want_interface_events,  "enable|disable")                             \
22898 _(want_stats,"enable|disable")                                          \
22899 _(get_first_msg_id, "client <name>")                                    \
22900 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22901 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22902   "fib-id <nn> [ip4][ip6][default]")                                    \
22903 _(get_node_graph, " ")                                                  \
22904 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22905 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22906 _(ioam_disable, "")                                                     \
22907 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22908                             " sw_if_index <sw_if_index> p <priority> "  \
22909                             "w <weight>] [del]")                        \
22910 _(one_add_del_locator, "locator-set <locator_name> "                    \
22911                         "iface <intf> | sw_if_index <sw_if_index> "     \
22912                         "p <priority> w <weight> [del]")                \
22913 _(one_add_del_local_eid,"vni <vni> eid "                                \
22914                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22915                          "locator-set <locator_name> [del]"             \
22916                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22917 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22918 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22919 _(one_enable_disable, "enable|disable")                                 \
22920 _(one_map_register_enable_disable, "enable|disable")                    \
22921 _(one_map_register_fallback_threshold, "<value>")                       \
22922 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22923 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22924                                "[seid <seid>] "                         \
22925                                "rloc <locator> p <prio> "               \
22926                                "w <weight> [rloc <loc> ... ] "          \
22927                                "action <action> [del-all]")             \
22928 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22929                           "<local-eid>")                                \
22930 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22931 _(one_use_petr, "ip-address> | disable")                                \
22932 _(one_map_request_mode, "src-dst|dst-only")                             \
22933 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22934 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22935 _(one_locator_set_dump, "[local | remote]")                             \
22936 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22937 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22938                        "[local] | [remote]")                            \
22939 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22940 _(one_ndp_bd_get, "")                                                   \
22941 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22942 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22943 _(one_l2_arp_bd_get, "")                                                \
22944 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22945 _(one_stats_enable_disable, "enable|disalbe")                           \
22946 _(show_one_stats_enable_disable, "")                                    \
22947 _(one_eid_table_vni_dump, "")                                           \
22948 _(one_eid_table_map_dump, "l2|l3")                                      \
22949 _(one_map_resolver_dump, "")                                            \
22950 _(one_map_server_dump, "")                                              \
22951 _(one_adjacencies_get, "vni <vni>")                                     \
22952 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22953 _(show_one_rloc_probe_state, "")                                        \
22954 _(show_one_map_register_state, "")                                      \
22955 _(show_one_status, "")                                                  \
22956 _(one_stats_dump, "")                                                   \
22957 _(one_stats_flush, "")                                                  \
22958 _(one_get_map_request_itr_rlocs, "")                                    \
22959 _(one_map_register_set_ttl, "<ttl>")                                    \
22960 _(one_set_transport_protocol, "udp|api")                                \
22961 _(one_get_transport_protocol, "")                                       \
22962 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22963 _(one_show_xtr_mode, "")                                                \
22964 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22965 _(one_show_pitr_mode, "")                                               \
22966 _(one_enable_disable_petr_mode, "enable|disable")                       \
22967 _(one_show_petr_mode, "")                                               \
22968 _(show_one_nsh_mapping, "")                                             \
22969 _(show_one_pitr, "")                                                    \
22970 _(show_one_use_petr, "")                                                \
22971 _(show_one_map_request_mode, "")                                        \
22972 _(show_one_map_register_ttl, "")                                        \
22973 _(show_one_map_register_fallback_threshold, "")                         \
22974 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22975                             " sw_if_index <sw_if_index> p <priority> "  \
22976                             "w <weight>] [del]")                        \
22977 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22978                         "iface <intf> | sw_if_index <sw_if_index> "     \
22979                         "p <priority> w <weight> [del]")                \
22980 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22981                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22982                          "locator-set <locator_name> [del]"             \
22983                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22984 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22985 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22986 _(lisp_enable_disable, "enable|disable")                                \
22987 _(lisp_map_register_enable_disable, "enable|disable")                   \
22988 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22989 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22990                                "[seid <seid>] "                         \
22991                                "rloc <locator> p <prio> "               \
22992                                "w <weight> [rloc <loc> ... ] "          \
22993                                "action <action> [del-all]")             \
22994 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22995                           "<local-eid>")                                \
22996 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22997 _(lisp_use_petr, "<ip-address> | disable")                              \
22998 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22999 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23000 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23001 _(lisp_locator_set_dump, "[local | remote]")                            \
23002 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23003 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23004                        "[local] | [remote]")                            \
23005 _(lisp_eid_table_vni_dump, "")                                          \
23006 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23007 _(lisp_map_resolver_dump, "")                                           \
23008 _(lisp_map_server_dump, "")                                             \
23009 _(lisp_adjacencies_get, "vni <vni>")                                    \
23010 _(gpe_fwd_entry_vnis_get, "")                                           \
23011 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23012 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23013                                 "[table <table-id>]")                   \
23014 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23015 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23016 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23017 _(gpe_get_encap_mode, "")                                               \
23018 _(lisp_gpe_add_del_iface, "up|down")                                    \
23019 _(lisp_gpe_enable_disable, "enable|disable")                            \
23020 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23021   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23022 _(show_lisp_rloc_probe_state, "")                                       \
23023 _(show_lisp_map_register_state, "")                                     \
23024 _(show_lisp_status, "")                                                 \
23025 _(lisp_get_map_request_itr_rlocs, "")                                   \
23026 _(show_lisp_pitr, "")                                                   \
23027 _(show_lisp_use_petr, "")                                               \
23028 _(show_lisp_map_request_mode, "")                                       \
23029 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23030 _(af_packet_delete, "name <host interface name>")                       \
23031 _(policer_add_del, "name <policer name> <params> [del]")                \
23032 _(policer_dump, "[name <policer name>]")                                \
23033 _(policer_classify_set_interface,                                       \
23034   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23035   "  [l2-table <nn>] [del]")                                            \
23036 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23037 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23038     "[master|slave]")                                                   \
23039 _(netmap_delete, "name <interface name>")                               \
23040 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23041 _(mpls_fib_dump, "")                                                    \
23042 _(classify_table_ids, "")                                               \
23043 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23044 _(classify_table_info, "table_id <nn>")                                 \
23045 _(classify_session_dump, "table_id <nn>")                               \
23046 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23047     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23048     "[template_interval <nn>] [udp_checksum]")                          \
23049 _(ipfix_exporter_dump, "")                                              \
23050 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23051 _(ipfix_classify_stream_dump, "")                                       \
23052 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23053 _(ipfix_classify_table_dump, "")                                        \
23054 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23055 _(sw_interface_span_dump, "[l2]")                                           \
23056 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23057 _(pg_create_interface, "if_id <nn>")                                    \
23058 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23059 _(pg_enable_disable, "[stream <id>] disable")                           \
23060 _(ip_source_and_port_range_check_add_del,                               \
23061   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23062 _(ip_source_and_port_range_check_interface_add_del,                     \
23063   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23064   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23065 _(ipsec_gre_add_del_tunnel,                                             \
23066   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23067 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23068 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23069 _(l2_interface_pbb_tag_rewrite,                                         \
23070   "<intfc> | sw_if_index <nn> \n"                                       \
23071   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23072   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23073 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23074 _(flow_classify_set_interface,                                          \
23075   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23076 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23077 _(ip_fib_dump, "")                                                      \
23078 _(ip_mfib_dump, "")                                                     \
23079 _(ip6_fib_dump, "")                                                     \
23080 _(ip6_mfib_dump, "")                                                    \
23081 _(feature_enable_disable, "arc_name <arc_name> "                        \
23082   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23083 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23084 "[disable]")                                                            \
23085 _(l2_xconnect_dump, "")                                                 \
23086 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23087 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23088 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23089 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23090 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23091 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23092 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23093   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23094 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23095 _(memfd_segment_create,"size <nnn>")                                    \
23096 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23097 _(dns_enable_disable, "[enable][disable]")                              \
23098 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23099 _(dns_resolve_name, "<hostname>")                                       \
23100 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23101 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23102 _(dns_resolve_name, "<hostname>")                                       \
23103 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23104   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23105 _(session_rules_dump, "")                                               \
23106 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23107
23108 /* List of command functions, CLI names map directly to functions */
23109 #define foreach_cli_function                                    \
23110 _(comment, "usage: comment <ignore-rest-of-line>")              \
23111 _(dump_interface_table, "usage: dump_interface_table")          \
23112 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23113 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23114 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23115 _(dump_stats_table, "usage: dump_stats_table")                  \
23116 _(dump_macro_table, "usage: dump_macro_table ")                 \
23117 _(dump_node_table, "usage: dump_node_table")                    \
23118 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23119 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23120 _(echo, "usage: echo <message>")                                \
23121 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23122 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23123 _(help, "usage: help")                                          \
23124 _(q, "usage: quit")                                             \
23125 _(quit, "usage: quit")                                          \
23126 _(search_node_table, "usage: search_node_table <name>...")      \
23127 _(set, "usage: set <variable-name> <value>")                    \
23128 _(script, "usage: script <file-name>")                          \
23129 _(unset, "usage: unset <variable-name>")
23130 #define _(N,n)                                  \
23131     static void vl_api_##n##_t_handler_uni      \
23132     (vl_api_##n##_t * mp)                       \
23133     {                                           \
23134         vat_main_t * vam = &vat_main;           \
23135         if (vam->json_output) {                 \
23136             vl_api_##n##_t_handler_json(mp);    \
23137         } else {                                \
23138             vl_api_##n##_t_handler(mp);         \
23139         }                                       \
23140     }
23141 foreach_vpe_api_reply_msg;
23142 #if VPP_API_TEST_BUILTIN == 0
23143 foreach_standalone_reply_msg;
23144 #endif
23145 #undef _
23146
23147 void
23148 vat_api_hookup (vat_main_t * vam)
23149 {
23150 #define _(N,n)                                                  \
23151     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23152                            vl_api_##n##_t_handler_uni,          \
23153                            vl_noop_handler,                     \
23154                            vl_api_##n##_t_endian,               \
23155                            vl_api_##n##_t_print,                \
23156                            sizeof(vl_api_##n##_t), 1);
23157   foreach_vpe_api_reply_msg;
23158 #if VPP_API_TEST_BUILTIN == 0
23159   foreach_standalone_reply_msg;
23160 #endif
23161 #undef _
23162
23163 #if (VPP_API_TEST_BUILTIN==0)
23164   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23165
23166   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23167
23168   vam->function_by_name = hash_create_string (0, sizeof (uword));
23169
23170   vam->help_by_name = hash_create_string (0, sizeof (uword));
23171 #endif
23172
23173   /* API messages we can send */
23174 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23175   foreach_vpe_api_msg;
23176 #undef _
23177
23178   /* Help strings */
23179 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23180   foreach_vpe_api_msg;
23181 #undef _
23182
23183   /* CLI functions */
23184 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23185   foreach_cli_function;
23186 #undef _
23187
23188   /* Help strings */
23189 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23190   foreach_cli_function;
23191 #undef _
23192 }
23193
23194 #if VPP_API_TEST_BUILTIN
23195 static clib_error_t *
23196 vat_api_hookup_shim (vlib_main_t * vm)
23197 {
23198   vat_api_hookup (&vat_main);
23199   return 0;
23200 }
23201
23202 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23203 #endif
23204
23205 /*
23206  * fd.io coding-style-patch-verification: ON
23207  *
23208  * Local Variables:
23209  * eval: (c-set-style "gnu")
23210  * End:
23211  */