tap_v2: multiple improvements
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   return vl_socket_client_connect
92     (&vam->socket_client_main, (char *) vam->socket_name,
93      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 void
103 vl_socket_client_read_reply (socket_client_main_t * scm)
104 {
105 };
106 #endif
107
108
109 f64
110 vat_time_now (vat_main_t * vam)
111 {
112 #if VPP_API_TEST_BUILTIN
113   return vlib_time_now (vam->vlib_main);
114 #else
115   return clib_time_now (&vam->clib_time);
116 #endif
117 }
118
119 void
120 errmsg (char *fmt, ...)
121 {
122   vat_main_t *vam = &vat_main;
123   va_list va;
124   u8 *s;
125
126   va_start (va, fmt);
127   s = va_format (0, fmt, &va);
128   va_end (va);
129
130   vec_add1 (s, 0);
131
132 #if VPP_API_TEST_BUILTIN
133   vlib_cli_output (vam->vlib_main, (char *) s);
134 #else
135   {
136     if (vam->ifp != stdin)
137       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
138                vam->input_line_number);
139     fformat (vam->ofp, (char *) s);
140     fflush (vam->ofp);
141   }
142 #endif
143
144   vec_free (s);
145 }
146
147 #if VPP_API_TEST_BUILTIN == 0
148 static uword
149 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
150 {
151   vat_main_t *vam = va_arg (*args, vat_main_t *);
152   u32 *result = va_arg (*args, u32 *);
153   u8 *if_name;
154   uword *p;
155
156   if (!unformat (input, "%s", &if_name))
157     return 0;
158
159   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
160   if (p == 0)
161     return 0;
162   *result = p[0];
163   return 1;
164 }
165
166 /* Parse an IP4 address %d.%d.%d.%d. */
167 uword
168 unformat_ip4_address (unformat_input_t * input, va_list * args)
169 {
170   u8 *result = va_arg (*args, u8 *);
171   unsigned a[4];
172
173   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
174     return 0;
175
176   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
177     return 0;
178
179   result[0] = a[0];
180   result[1] = a[1];
181   result[2] = a[2];
182   result[3] = a[3];
183
184   return 1;
185 }
186
187 uword
188 unformat_ethernet_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   u32 i, a[6];
192
193   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
194                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
195     return 0;
196
197   /* Check range. */
198   for (i = 0; i < 6; i++)
199     if (a[i] >= (1 << 8))
200       return 0;
201
202   for (i = 0; i < 6; i++)
203     result[i] = a[i];
204
205   return 1;
206 }
207
208 /* Returns ethernet type as an int in host byte order. */
209 uword
210 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
211                                         va_list * args)
212 {
213   u16 *result = va_arg (*args, u16 *);
214   int type;
215
216   /* Numeric type. */
217   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
218     {
219       if (type >= (1 << 16))
220         return 0;
221       *result = type;
222       return 1;
223     }
224   return 0;
225 }
226
227 /* Parse an IP6 address. */
228 uword
229 unformat_ip6_address (unformat_input_t * input, va_list * args)
230 {
231   ip6_address_t *result = va_arg (*args, ip6_address_t *);
232   u16 hex_quads[8];
233   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
234   uword c, n_colon, double_colon_index;
235
236   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
237   double_colon_index = ARRAY_LEN (hex_quads);
238   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
239     {
240       hex_digit = 16;
241       if (c >= '0' && c <= '9')
242         hex_digit = c - '0';
243       else if (c >= 'a' && c <= 'f')
244         hex_digit = c + 10 - 'a';
245       else if (c >= 'A' && c <= 'F')
246         hex_digit = c + 10 - 'A';
247       else if (c == ':' && n_colon < 2)
248         n_colon++;
249       else
250         {
251           unformat_put_input (input);
252           break;
253         }
254
255       /* Too many hex quads. */
256       if (n_hex_quads >= ARRAY_LEN (hex_quads))
257         return 0;
258
259       if (hex_digit < 16)
260         {
261           hex_quad = (hex_quad << 4) | hex_digit;
262
263           /* Hex quad must fit in 16 bits. */
264           if (n_hex_digits >= 4)
265             return 0;
266
267           n_colon = 0;
268           n_hex_digits++;
269         }
270
271       /* Save position of :: */
272       if (n_colon == 2)
273         {
274           /* More than one :: ? */
275           if (double_colon_index < ARRAY_LEN (hex_quads))
276             return 0;
277           double_colon_index = n_hex_quads;
278         }
279
280       if (n_colon > 0 && n_hex_digits > 0)
281         {
282           hex_quads[n_hex_quads++] = hex_quad;
283           hex_quad = 0;
284           n_hex_digits = 0;
285         }
286     }
287
288   if (n_hex_digits > 0)
289     hex_quads[n_hex_quads++] = hex_quad;
290
291   {
292     word i;
293
294     /* Expand :: to appropriate number of zero hex quads. */
295     if (double_colon_index < ARRAY_LEN (hex_quads))
296       {
297         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
298
299         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
300           hex_quads[n_zero + i] = hex_quads[i];
301
302         for (i = 0; i < n_zero; i++)
303           hex_quads[double_colon_index + i] = 0;
304
305         n_hex_quads = ARRAY_LEN (hex_quads);
306       }
307
308     /* Too few hex quads given. */
309     if (n_hex_quads < ARRAY_LEN (hex_quads))
310       return 0;
311
312     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
313       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
314
315     return 1;
316   }
317 }
318
319 uword
320 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
321 {
322   u32 *r = va_arg (*args, u32 *);
323
324   if (0);
325 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
326   foreach_ipsec_policy_action
327 #undef _
328     else
329     return 0;
330   return 1;
331 }
332
333 uword
334 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
340   foreach_ipsec_crypto_alg
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 u8 *
348 format_ipsec_crypto_alg (u8 * s, va_list * args)
349 {
350   u32 i = va_arg (*args, u32);
351   u8 *t = 0;
352
353   switch (i)
354     {
355 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
356       foreach_ipsec_crypto_alg
357 #undef _
358     default:
359       return format (s, "unknown");
360     }
361   return format (s, "%s", t);
362 }
363
364 uword
365 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
371   foreach_ipsec_integ_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_integ_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_integ_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
402   foreach_ikev2_auth_method
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
416   foreach_ikev2_id_type
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422 #else /* VPP_API_TEST_BUILTIN == 1 */
423 static uword
424 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
425 {
426   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
427   vnet_main_t *vnm = vnet_get_main ();
428   u32 *result = va_arg (*args, u32 *);
429   u32 sw_if_index;
430
431   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
432     return 0;
433
434   *result = sw_if_index;
435   return 1;
436 }
437 #endif /* VPP_API_TEST_BUILTIN */
438
439 static uword
440 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
441 {
442   u8 *r = va_arg (*args, u8 *);
443
444   if (unformat (input, "kbps"))
445     *r = SSE2_QOS_RATE_KBPS;
446   else if (unformat (input, "pps"))
447     *r = SSE2_QOS_RATE_PPS;
448   else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_round_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "closest"))
459     *r = SSE2_QOS_ROUND_TO_CLOSEST;
460   else if (unformat (input, "up"))
461     *r = SSE2_QOS_ROUND_TO_UP;
462   else if (unformat (input, "down"))
463     *r = SSE2_QOS_ROUND_TO_DOWN;
464   else
465     return 0;
466   return 1;
467 }
468
469 static uword
470 unformat_policer_type (unformat_input_t * input, va_list * args)
471 {
472   u8 *r = va_arg (*args, u8 *);
473
474   if (unformat (input, "1r2c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R2C;
476   else if (unformat (input, "1r3c"))
477     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
478   else if (unformat (input, "2r3c-2698"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
480   else if (unformat (input, "2r3c-4115"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
482   else if (unformat (input, "2r3c-mef5cf1"))
483     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_dscp (unformat_input_t * input, va_list * va)
491 {
492   u8 *r = va_arg (*va, u8 *);
493
494   if (0);
495 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
496   foreach_vnet_dscp
497 #undef _
498     else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_action_type (unformat_input_t * input, va_list * va)
505 {
506   sse2_qos_pol_action_params_st *a
507     = va_arg (*va, sse2_qos_pol_action_params_st *);
508
509   if (unformat (input, "drop"))
510     a->action_type = SSE2_QOS_ACTION_DROP;
511   else if (unformat (input, "transmit"))
512     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
513   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
514     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
515   else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
522 {
523   u32 *r = va_arg (*va, u32 *);
524   u32 tid;
525
526   if (unformat (input, "ip4"))
527     tid = POLICER_CLASSIFY_TABLE_IP4;
528   else if (unformat (input, "ip6"))
529     tid = POLICER_CLASSIFY_TABLE_IP6;
530   else if (unformat (input, "l2"))
531     tid = POLICER_CLASSIFY_TABLE_L2;
532   else
533     return 0;
534
535   *r = tid;
536   return 1;
537 }
538
539 static uword
540 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = FLOW_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = FLOW_CLASSIFY_TABLE_IP6;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
557 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
558 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
559 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
560
561 #if (VPP_API_TEST_BUILTIN==0)
562 uword
563 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
564 {
565   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
566   mfib_itf_attribute_t attr;
567
568   old = *iflags;
569   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
570   {
571     if (unformat (input, mfib_itf_flag_long_names[attr]))
572       *iflags |= (1 << attr);
573   }
574   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
575   {
576     if (unformat (input, mfib_itf_flag_names[attr]))
577       *iflags |= (1 << attr);
578   }
579
580   return (old == *iflags ? 0 : 1);
581 }
582
583 uword
584 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
587   mfib_entry_attribute_t attr;
588
589   old = *eflags;
590   FOR_EACH_MFIB_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_flag_long_names[attr]))
593       *eflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_flag_names[attr]))
598       *eflags |= (1 << attr);
599   }
600
601   return (old == *eflags ? 0 : 1);
602 }
603
604 u8 *
605 format_ip4_address (u8 * s, va_list * args)
606 {
607   u8 *a = va_arg (*args, u8 *);
608   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
609 }
610
611 u8 *
612 format_ip6_address (u8 * s, va_list * args)
613 {
614   ip6_address_t *a = va_arg (*args, ip6_address_t *);
615   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
616
617   i_max_n_zero = ARRAY_LEN (a->as_u16);
618   max_n_zeros = 0;
619   i_first_zero = i_max_n_zero;
620   n_zeros = 0;
621   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
622     {
623       u32 is_zero = a->as_u16[i] == 0;
624       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
625         {
626           i_first_zero = i;
627           n_zeros = 0;
628         }
629       n_zeros += is_zero;
630       if ((!is_zero && n_zeros > max_n_zeros)
631           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
632         {
633           i_max_n_zero = i_first_zero;
634           max_n_zeros = n_zeros;
635           i_first_zero = ARRAY_LEN (a->as_u16);
636           n_zeros = 0;
637         }
638     }
639
640   last_double_colon = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       if (i == i_max_n_zero && max_n_zeros > 1)
644         {
645           s = format (s, "::");
646           i += max_n_zeros - 1;
647           last_double_colon = 1;
648         }
649       else
650         {
651           s = format (s, "%s%x",
652                       (last_double_colon || i == 0) ? "" : ":",
653                       clib_net_to_host_u16 (a->as_u16[i]));
654           last_double_colon = 0;
655         }
656     }
657
658   return s;
659 }
660
661 /* Format an IP46 address. */
662 u8 *
663 format_ip46_address (u8 * s, va_list * args)
664 {
665   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
666   ip46_type_t type = va_arg (*args, ip46_type_t);
667   int is_ip4 = 1;
668
669   switch (type)
670     {
671     case IP46_TYPE_ANY:
672       is_ip4 = ip46_address_is_ip4 (ip46);
673       break;
674     case IP46_TYPE_IP4:
675       is_ip4 = 1;
676       break;
677     case IP46_TYPE_IP6:
678       is_ip4 = 0;
679       break;
680     }
681
682   return is_ip4 ?
683     format (s, "%U", format_ip4_address, &ip46->ip4) :
684     format (s, "%U", format_ip6_address, &ip46->ip6);
685 }
686
687 u8 *
688 format_ethernet_address (u8 * s, va_list * args)
689 {
690   u8 *a = va_arg (*args, u8 *);
691
692   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
693                  a[0], a[1], a[2], a[3], a[4], a[5]);
694 }
695 #endif
696
697 static void
698 increment_v4_address (ip4_address_t * a)
699 {
700   u32 v;
701
702   v = ntohl (a->as_u32) + 1;
703   a->as_u32 = ntohl (v);
704 }
705
706 static void
707 increment_v6_address (ip6_address_t * a)
708 {
709   u64 v0, v1;
710
711   v0 = clib_net_to_host_u64 (a->as_u64[0]);
712   v1 = clib_net_to_host_u64 (a->as_u64[1]);
713
714   v1 += 1;
715   if (v1 == 0)
716     v0 += 1;
717   a->as_u64[0] = clib_net_to_host_u64 (v0);
718   a->as_u64[1] = clib_net_to_host_u64 (v1);
719 }
720
721 static void
722 increment_mac_address (u8 * mac)
723 {
724   u64 tmp = *((u64 *) mac);
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728
729   clib_memcpy (mac, &tmp, 6);
730 }
731
732 static void vl_api_create_loopback_reply_t_handler
733   (vl_api_create_loopback_reply_t * mp)
734 {
735   vat_main_t *vam = &vat_main;
736   i32 retval = ntohl (mp->retval);
737
738   vam->retval = retval;
739   vam->regenerate_interface_table = 1;
740   vam->sw_if_index = ntohl (mp->sw_if_index);
741   vam->result_ready = 1;
742 }
743
744 static void vl_api_create_loopback_reply_t_handler_json
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   vat_json_node_t node;
749
750   vat_json_init_object (&node);
751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
753
754   vat_json_print (vam->ofp, &node);
755   vat_json_free (&node);
756   vam->retval = ntohl (mp->retval);
757   vam->result_ready = 1;
758 }
759
760 static void vl_api_create_loopback_instance_reply_t_handler
761   (vl_api_create_loopback_instance_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler_json
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_af_packet_create_reply_t_handler
789   (vl_api_af_packet_create_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler_json
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_create_vlan_subif_reply_t_handler
818   (vl_api_create_vlan_subif_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler_json
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_subif_reply_t_handler
847   (vl_api_create_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler_json
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_interface_name_renumber_reply_t_handler
876   (vl_api_interface_name_renumber_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_interface_name_renumber_reply_t_handler_json
887   (vl_api_interface_name_renumber_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894
895   vat_json_print (vam->ofp, &node);
896   vat_json_free (&node);
897
898   vam->retval = ntohl (mp->retval);
899   vam->result_ready = 1;
900 }
901
902 /*
903  * Special-case: build the interface table, maintain
904  * the next loopback sw_if_index vbl.
905  */
906 static void vl_api_sw_interface_details_t_handler
907   (vl_api_sw_interface_details_t * mp)
908 {
909   vat_main_t *vam = &vat_main;
910   u8 *s = format (0, "%s%c", mp->interface_name, 0);
911
912   hash_set_mem (vam->sw_if_index_by_interface_name, s,
913                 ntohl (mp->sw_if_index));
914
915   /* In sub interface case, fill the sub interface table entry */
916   if (mp->sw_if_index != mp->sup_sw_if_index)
917     {
918       sw_interface_subif_t *sub = NULL;
919
920       vec_add2 (vam->sw_if_subif_table, sub, 1);
921
922       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
923       strncpy ((char *) sub->interface_name, (char *) s,
924                vec_len (sub->interface_name));
925       sub->sw_if_index = ntohl (mp->sw_if_index);
926       sub->sub_id = ntohl (mp->sub_id);
927
928       sub->sub_dot1ad = mp->sub_dot1ad;
929       sub->sub_number_of_tags = mp->sub_number_of_tags;
930       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
931       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
932       sub->sub_exact_match = mp->sub_exact_match;
933       sub->sub_default = mp->sub_default;
934       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
935       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
936
937       /* vlan tag rewrite */
938       sub->vtr_op = ntohl (mp->vtr_op);
939       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
940       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
941       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
942     }
943 }
944
945 static void vl_api_sw_interface_details_t_handler_json
946   (vl_api_sw_interface_details_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t *node = NULL;
950
951   if (VAT_JSON_ARRAY != vam->json_tree.type)
952     {
953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
954       vat_json_init_array (&vam->json_tree);
955     }
956   node = vat_json_array_add (&vam->json_tree);
957
958   vat_json_init_object (node);
959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
960   vat_json_object_add_uint (node, "sup_sw_if_index",
961                             ntohl (mp->sup_sw_if_index));
962   vat_json_object_add_uint (node, "l2_address_length",
963                             ntohl (mp->l2_address_length));
964   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
965                              sizeof (mp->l2_address));
966   vat_json_object_add_string_copy (node, "interface_name",
967                                    mp->interface_name);
968   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
969   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
970   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
971   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
972   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
973   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
974   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
975   vat_json_object_add_uint (node, "sub_number_of_tags",
976                             mp->sub_number_of_tags);
977   vat_json_object_add_uint (node, "sub_outer_vlan_id",
978                             ntohs (mp->sub_outer_vlan_id));
979   vat_json_object_add_uint (node, "sub_inner_vlan_id",
980                             ntohs (mp->sub_inner_vlan_id));
981   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
982   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
983   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
984                             mp->sub_outer_vlan_id_any);
985   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
986                             mp->sub_inner_vlan_id_any);
987   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
988   vat_json_object_add_uint (node, "vtr_push_dot1q",
989                             ntohl (mp->vtr_push_dot1q));
990   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
991   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
992   if (mp->sub_dot1ah)
993     {
994       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
995                                        format (0, "%U",
996                                                format_ethernet_address,
997                                                &mp->b_dmac));
998       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
999                                        format (0, "%U",
1000                                                format_ethernet_address,
1001                                                &mp->b_smac));
1002       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1003       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1004     }
1005 }
1006
1007 #if VPP_API_TEST_BUILTIN == 0
1008 static void vl_api_sw_interface_event_t_handler
1009   (vl_api_sw_interface_event_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   if (vam->interface_event_display)
1013     errmsg ("interface flags: sw_if_index %d %s %s",
1014             ntohl (mp->sw_if_index),
1015             mp->admin_up_down ? "admin-up" : "admin-down",
1016             mp->link_up_down ? "link-up" : "link-down");
1017 }
1018 #endif
1019
1020 static void vl_api_sw_interface_event_t_handler_json
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   /* JSON output not supported */
1024 }
1025
1026 static void
1027 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031
1032   vam->retval = retval;
1033   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void
1038 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   vat_json_node_t node;
1042   api_main_t *am = &api_main;
1043   void *oldheap;
1044   u8 *reply;
1045
1046   vat_json_init_object (&node);
1047   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1048   vat_json_object_add_uint (&node, "reply_in_shmem",
1049                             ntohl (mp->reply_in_shmem));
1050   /* Toss the shared-memory original... */
1051   pthread_mutex_lock (&am->vlib_rp->mutex);
1052   oldheap = svm_push_data_heap (am->vlib_rp);
1053
1054   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1055   vec_free (reply);
1056
1057   svm_pop_heap (oldheap);
1058   pthread_mutex_unlock (&am->vlib_rp->mutex);
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void
1068 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   u32 length = ntohl (mp->length);
1073
1074   vec_reset_length (vam->cmd_reply);
1075
1076   vam->retval = retval;
1077   if (retval == 0)
1078     {
1079       vec_validate (vam->cmd_reply, length);
1080       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void vl_api_classify_add_del_table_reply_t_handler
1106   (vl_api_classify_add_del_table_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   i32 retval = ntohl (mp->retval);
1110   if (vam->async_mode)
1111     {
1112       vam->async_errors += (retval < 0);
1113     }
1114   else
1115     {
1116       vam->retval = retval;
1117       if (retval == 0 &&
1118           ((mp->new_table_index != 0xFFFFFFFF) ||
1119            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1120            (mp->match_n_vectors != 0xFFFFFFFF)))
1121         /*
1122          * Note: this is just barely thread-safe, depends on
1123          * the main thread spinning waiting for an answer...
1124          */
1125         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1126                 ntohl (mp->new_table_index),
1127                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1128       vam->result_ready = 1;
1129     }
1130 }
1131
1132 static void vl_api_classify_add_del_table_reply_t_handler_json
1133   (vl_api_classify_add_del_table_reply_t * mp)
1134 {
1135   vat_main_t *vam = &vat_main;
1136   vat_json_node_t node;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "new_table_index",
1141                             ntohl (mp->new_table_index));
1142   vat_json_object_add_uint (&node, "skip_n_vectors",
1143                             ntohl (mp->skip_n_vectors));
1144   vat_json_object_add_uint (&node, "match_n_vectors",
1145                             ntohl (mp->match_n_vectors));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_get_node_index_reply_t_handler
1155   (vl_api_get_node_index_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("node index %d", ntohl (mp->node_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_get_node_index_reply_t_handler_json
1173   (vl_api_get_node_index_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_next_index_reply_t_handler
1190   (vl_api_get_next_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("next node index %d", ntohl (mp->next_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_next_index_reply_t_handler_json
1208   (vl_api_get_next_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_add_node_next_reply_t_handler
1225   (vl_api_add_node_next_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_add_node_next_reply_t_handler_json
1243   (vl_api_add_node_next_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_show_version_reply_t_handler
1260   (vl_api_show_version_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264
1265   if (retval >= 0)
1266     {
1267       errmsg ("        program: %s", mp->program);
1268       errmsg ("        version: %s", mp->version);
1269       errmsg ("     build date: %s", mp->build_date);
1270       errmsg ("build directory: %s", mp->build_directory);
1271     }
1272   vam->retval = retval;
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_show_version_reply_t_handler_json
1277   (vl_api_show_version_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_string_copy (&node, "program", mp->program);
1285   vat_json_object_add_string_copy (&node, "version", mp->version);
1286   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1287   vat_json_object_add_string_copy (&node, "build_directory",
1288                                    mp->build_directory);
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void
1298 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1299 {
1300   u32 sw_if_index = ntohl (mp->sw_if_index);
1301   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1302           mp->mac_ip ? "mac/ip binding" : "address resolution",
1303           ntohl (mp->pid), format_ip4_address, &mp->address,
1304           format_ethernet_address, mp->new_mac, sw_if_index);
1305 }
1306
1307 static void
1308 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1309 {
1310   /* JSON output not supported */
1311 }
1312
1313 static void
1314 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1315 {
1316   u32 sw_if_index = ntohl (mp->sw_if_index);
1317   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1318           mp->mac_ip ? "mac/ip binding" : "address resolution",
1319           ntohl (mp->pid), format_ip6_address, mp->address,
1320           format_ethernet_address, mp->new_mac, sw_if_index);
1321 }
1322
1323 static void
1324 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1325 {
1326   /* JSON output not supported */
1327 }
1328
1329 static void
1330 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1331 {
1332   u32 n_macs = ntohl (mp->n_macs);
1333   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1334           ntohl (mp->pid), mp->client_index, n_macs);
1335   int i;
1336   for (i = 0; i < n_macs; i++)
1337     {
1338       vl_api_mac_entry_t *mac = &mp->mac[i];
1339       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1340               i + 1, ntohl (mac->sw_if_index),
1341               format_ethernet_address, mac->mac_addr, mac->is_del);
1342       if (i == 1000)
1343         break;
1344     }
1345 }
1346
1347 static void
1348 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1349 {
1350   /* JSON output not supported */
1351 }
1352
1353 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1354 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1355
1356 /*
1357  * Special-case: build the bridge domain table, maintain
1358  * the next bd id vbl.
1359  */
1360 static void vl_api_bridge_domain_details_t_handler
1361   (vl_api_bridge_domain_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1365   int i;
1366
1367   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1368          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1369
1370   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1371          ntohl (mp->bd_id), mp->learn, mp->forward,
1372          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1373
1374   if (n_sw_ifs)
1375     {
1376       vl_api_bridge_domain_sw_if_t *sw_ifs;
1377       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1378              "Interface Name");
1379
1380       sw_ifs = mp->sw_if_details;
1381       for (i = 0; i < n_sw_ifs; i++)
1382         {
1383           u8 *sw_if_name = 0;
1384           u32 sw_if_index;
1385           hash_pair_t *p;
1386
1387           sw_if_index = ntohl (sw_ifs->sw_if_index);
1388
1389           /* *INDENT-OFF* */
1390           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1391                              ({
1392                                if ((u32) p->value[0] == sw_if_index)
1393                                  {
1394                                    sw_if_name = (u8 *)(p->key);
1395                                    break;
1396                                  }
1397                              }));
1398           /* *INDENT-ON* */
1399           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1400                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1401                  "sw_if_index not found!");
1402
1403           sw_ifs++;
1404         }
1405     }
1406 }
1407
1408 static void vl_api_bridge_domain_details_t_handler_json
1409   (vl_api_bridge_domain_details_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t *node, *array = NULL;
1413   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1414
1415   if (VAT_JSON_ARRAY != vam->json_tree.type)
1416     {
1417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1418       vat_json_init_array (&vam->json_tree);
1419     }
1420   node = vat_json_array_add (&vam->json_tree);
1421
1422   vat_json_init_object (node);
1423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1424   vat_json_object_add_uint (node, "flood", mp->flood);
1425   vat_json_object_add_uint (node, "forward", mp->forward);
1426   vat_json_object_add_uint (node, "learn", mp->learn);
1427   vat_json_object_add_uint (node, "bvi_sw_if_index",
1428                             ntohl (mp->bvi_sw_if_index));
1429   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1430   array = vat_json_object_add (node, "sw_if");
1431   vat_json_init_array (array);
1432
1433
1434
1435   if (n_sw_ifs)
1436     {
1437       vl_api_bridge_domain_sw_if_t *sw_ifs;
1438       int i;
1439
1440       sw_ifs = mp->sw_if_details;
1441       for (i = 0; i < n_sw_ifs; i++)
1442         {
1443           node = vat_json_array_add (array);
1444           vat_json_init_object (node);
1445           vat_json_object_add_uint (node, "sw_if_index",
1446                                     ntohl (sw_ifs->sw_if_index));
1447           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1448           sw_ifs++;
1449         }
1450     }
1451 }
1452
1453 static void vl_api_control_ping_reply_t_handler
1454   (vl_api_control_ping_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467   vam->socket_client_main.control_pings_outstanding--;
1468 }
1469
1470 static void vl_api_control_ping_reply_t_handler_json
1471   (vl_api_control_ping_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   i32 retval = ntohl (mp->retval);
1475
1476   if (VAT_JSON_NONE != vam->json_tree.type)
1477     {
1478       vat_json_print (vam->ofp, &vam->json_tree);
1479       vat_json_free (&vam->json_tree);
1480       vam->json_tree.type = VAT_JSON_NONE;
1481     }
1482   else
1483     {
1484       /* just print [] */
1485       vat_json_init_array (&vam->json_tree);
1486       vat_json_print (vam->ofp, &vam->json_tree);
1487       vam->json_tree.type = VAT_JSON_NONE;
1488     }
1489
1490   vam->retval = retval;
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495   vl_api_bridge_domain_set_mac_age_reply_t_handler
1496   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1512   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void
1528 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->result_ready = 1;
1540     }
1541 }
1542
1543 static void vl_api_l2_flags_reply_t_handler_json
1544   (vl_api_l2_flags_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t node;
1548
1549   vat_json_init_object (&node);
1550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1551   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1552                             ntohl (mp->resulting_feature_bitmap));
1553
1554   vat_json_print (vam->ofp, &node);
1555   vat_json_free (&node);
1556
1557   vam->retval = ntohl (mp->retval);
1558   vam->result_ready = 1;
1559 }
1560
1561 static void vl_api_bridge_flags_reply_t_handler
1562   (vl_api_bridge_flags_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   i32 retval = ntohl (mp->retval);
1566   if (vam->async_mode)
1567     {
1568       vam->async_errors += (retval < 0);
1569     }
1570   else
1571     {
1572       vam->retval = retval;
1573       vam->result_ready = 1;
1574     }
1575 }
1576
1577 static void vl_api_bridge_flags_reply_t_handler_json
1578   (vl_api_bridge_flags_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   vat_json_node_t node;
1582
1583   vat_json_init_object (&node);
1584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1585   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1586                             ntohl (mp->resulting_feature_bitmap));
1587
1588   vat_json_print (vam->ofp, &node);
1589   vat_json_free (&node);
1590
1591   vam->retval = ntohl (mp->retval);
1592   vam->result_ready = 1;
1593 }
1594
1595 static void vl_api_tap_connect_reply_t_handler
1596   (vl_api_tap_connect_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->sw_if_index = ntohl (mp->sw_if_index);
1608       vam->result_ready = 1;
1609     }
1610
1611 }
1612
1613 static void vl_api_tap_connect_reply_t_handler_json
1614   (vl_api_tap_connect_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628
1629 }
1630
1631 static void
1632 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->sw_if_index = ntohl (mp->sw_if_index);
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_modify_reply_t_handler_json
1649   (vl_api_tap_modify_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_tap_delete_reply_t_handler_json
1682   (vl_api_tap_delete_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void
1698 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->sw_if_index = ntohl (mp->sw_if_index);
1710       vam->result_ready = 1;
1711     }
1712
1713 }
1714
1715 static void vl_api_tap_create_v2_reply_t_handler_json
1716   (vl_api_tap_create_v2_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730
1731 }
1732
1733 static void
1734 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_delete_v2_reply_t_handler_json
1750   (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1766   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1782   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1790                             ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1800   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1817   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1834   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1850   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "fwd_entry_index",
1858                             clib_net_to_host_u32 (mp->fwd_entry_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 u8 *
1868 format_lisp_transport_protocol (u8 * s, va_list * args)
1869 {
1870   u32 proto = va_arg (*args, u32);
1871
1872   switch (proto)
1873     {
1874     case 1:
1875       return format (s, "udp");
1876     case 2:
1877       return format (s, "api");
1878     default:
1879       return 0;
1880     }
1881   return 0;
1882 }
1883
1884 static void vl_api_one_get_transport_protocol_reply_t_handler
1885   (vl_api_one_get_transport_protocol_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   i32 retval = ntohl (mp->retval);
1889   if (vam->async_mode)
1890     {
1891       vam->async_errors += (retval < 0);
1892     }
1893   else
1894     {
1895       u32 proto = mp->protocol;
1896       print (vam->ofp, "Transport protocol: %U",
1897              format_lisp_transport_protocol, proto);
1898       vam->retval = retval;
1899       vam->result_ready = 1;
1900     }
1901 }
1902
1903 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1904   (vl_api_one_get_transport_protocol_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   vat_json_node_t node;
1908   u8 *s;
1909
1910   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1911   vec_add1 (s, 0);
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1916
1917   vec_free (s);
1918   vat_json_print (vam->ofp, &node);
1919   vat_json_free (&node);
1920
1921   vam->retval = ntohl (mp->retval);
1922   vam->result_ready = 1;
1923 }
1924
1925 static void vl_api_one_add_del_locator_set_reply_t_handler
1926   (vl_api_one_add_del_locator_set_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   i32 retval = ntohl (mp->retval);
1930   if (vam->async_mode)
1931     {
1932       vam->async_errors += (retval < 0);
1933     }
1934   else
1935     {
1936       vam->retval = retval;
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1942   (vl_api_one_add_del_locator_set_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   vat_json_node_t node;
1946
1947   vat_json_init_object (&node);
1948   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1949   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1950
1951   vat_json_print (vam->ofp, &node);
1952   vat_json_free (&node);
1953
1954   vam->retval = ntohl (mp->retval);
1955   vam->result_ready = 1;
1956 }
1957
1958 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   i32 retval = ntohl (mp->retval);
1963   if (vam->async_mode)
1964     {
1965       vam->async_errors += (retval < 0);
1966     }
1967   else
1968     {
1969       vam->retval = retval;
1970       vam->sw_if_index = ntohl (mp->sw_if_index);
1971       vam->result_ready = 1;
1972     }
1973 }
1974
1975 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   vat_json_node_t node;
1980
1981   vat_json_init_object (&node);
1982   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1983   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1984
1985   vat_json_print (vam->ofp, &node);
1986   vat_json_free (&node);
1987
1988   vam->retval = ntohl (mp->retval);
1989   vam->result_ready = 1;
1990 }
1991
1992 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1993   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   i32 retval = ntohl (mp->retval);
1997   if (vam->async_mode)
1998     {
1999       vam->async_errors += (retval < 0);
2000     }
2001   else
2002     {
2003       vam->retval = retval;
2004       vam->sw_if_index = ntohl (mp->sw_if_index);
2005       vam->result_ready = 1;
2006     }
2007 }
2008
2009 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2010   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t node;
2014
2015   vat_json_init_object (&node);
2016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2017   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2018
2019   vat_json_print (vam->ofp, &node);
2020   vat_json_free (&node);
2021
2022   vam->retval = ntohl (mp->retval);
2023   vam->result_ready = 1;
2024 }
2025
2026 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2027   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   i32 retval = ntohl (mp->retval);
2031   if (vam->async_mode)
2032     {
2033       vam->async_errors += (retval < 0);
2034     }
2035   else
2036     {
2037       vam->retval = retval;
2038       vam->sw_if_index = ntohl (mp->sw_if_index);
2039       vam->result_ready = 1;
2040     }
2041 }
2042
2043 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2044   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vat_json_node_t node;
2048
2049   vat_json_init_object (&node);
2050   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2051   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2052
2053   vat_json_print (vam->ofp, &node);
2054   vat_json_free (&node);
2055
2056   vam->retval = ntohl (mp->retval);
2057   vam->result_ready = 1;
2058 }
2059
2060 static void vl_api_gre_add_del_tunnel_reply_t_handler
2061   (vl_api_gre_add_del_tunnel_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->sw_if_index = ntohl (mp->sw_if_index);
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2078   (vl_api_gre_add_del_tunnel_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_create_vhost_user_if_reply_t_handler
2095   (vl_api_create_vhost_user_if_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_create_vhost_user_if_reply_t_handler_json
2112   (vl_api_create_vhost_user_if_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static clib_error_t *
2129 receive_fd_msg (int socket_fd, int *my_fd)
2130 {
2131   char msgbuf[16];
2132   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2133   struct msghdr mh = { 0 };
2134   struct iovec iov[1];
2135   ssize_t size;
2136   struct ucred *cr = 0;
2137   struct cmsghdr *cmsg;
2138   pid_t pid __attribute__ ((unused));
2139   uid_t uid __attribute__ ((unused));
2140   gid_t gid __attribute__ ((unused));
2141
2142   iov[0].iov_base = msgbuf;
2143   iov[0].iov_len = 5;
2144   mh.msg_iov = iov;
2145   mh.msg_iovlen = 1;
2146   mh.msg_control = ctl;
2147   mh.msg_controllen = sizeof (ctl);
2148
2149   memset (ctl, 0, sizeof (ctl));
2150
2151   /* receive the incoming message */
2152   size = recvmsg (socket_fd, &mh, 0);
2153   if (size != 5)
2154     {
2155       return (size == 0) ? clib_error_return (0, "disconnected") :
2156         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2157                                 socket_fd);
2158     }
2159
2160   cmsg = CMSG_FIRSTHDR (&mh);
2161   while (cmsg)
2162     {
2163       if (cmsg->cmsg_level == SOL_SOCKET)
2164         {
2165           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2166             {
2167               cr = (struct ucred *) CMSG_DATA (cmsg);
2168               uid = cr->uid;
2169               gid = cr->gid;
2170               pid = cr->pid;
2171             }
2172           else if (cmsg->cmsg_type == SCM_RIGHTS)
2173             {
2174               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2175             }
2176         }
2177       cmsg = CMSG_NXTHDR (&mh, cmsg);
2178     }
2179   return 0;
2180 }
2181
2182 static void vl_api_memfd_segment_create_reply_t_handler
2183   (vl_api_memfd_segment_create_reply_t * mp)
2184 {
2185   /* Dont bother in the builtin version */
2186 #if VPP_API_TEST_BUILTIN == 0
2187   vat_main_t *vam = &vat_main;
2188   api_main_t *am = &api_main;
2189   socket_client_main_t *scm = &vam->socket_client_main;
2190   int my_fd = -1;
2191   clib_error_t *error;
2192   memfd_private_t memfd;
2193   i32 retval = ntohl (mp->retval);
2194
2195   if (retval == 0)
2196     {
2197       error = receive_fd_msg (scm->socket_fd, &my_fd);
2198       if (error)
2199         {
2200           retval = -99;
2201           goto out;
2202         }
2203
2204       memset (&memfd, 0, sizeof (memfd));
2205       memfd.fd = my_fd;
2206
2207       vam->client_index_invalid = 1;
2208
2209       /* Note: this closes memfd.fd */
2210       retval = memfd_slave_init (&memfd);
2211       if (retval)
2212         clib_warning ("WARNING: segment map returned %d", retval);
2213
2214       /* Pivot to the memory client segment that vpp just created */
2215
2216       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2217
2218       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2219
2220       vl_client_install_client_message_handlers ();
2221
2222       vl_client_connect_to_vlib_no_map ("pvt",
2223                                         "vpp_api_test(p)",
2224                                         32 /* input_queue_length */ );
2225       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2226
2227       vl_socket_client_enable_disable (&vam->socket_client_main,
2228                                        0 /* disable socket */ );
2229     }
2230
2231 out:
2232   if (vam->async_mode)
2233     {
2234       vam->async_errors += (retval < 0);
2235     }
2236   else
2237     {
2238       vam->retval = retval;
2239       vam->result_ready = 1;
2240     }
2241 #endif
2242 }
2243
2244 static void vl_api_memfd_segment_create_reply_t_handler_json
2245   (vl_api_memfd_segment_create_reply_t * mp)
2246 {
2247   clib_warning ("no");
2248 }
2249
2250 static void vl_api_dns_resolve_name_reply_t_handler
2251   (vl_api_dns_resolve_name_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263
2264       if (retval == 0)
2265         {
2266           if (mp->ip4_set)
2267             clib_warning ("ip4 address %U", format_ip4_address,
2268                           (ip4_address_t *) mp->ip4_address);
2269           if (mp->ip6_set)
2270             clib_warning ("ip6 address %U", format_ip6_address,
2271                           (ip6_address_t *) mp->ip6_address);
2272         }
2273       else
2274         clib_warning ("retval %d", retval);
2275     }
2276 }
2277
2278 static void vl_api_dns_resolve_name_reply_t_handler_json
2279   (vl_api_dns_resolve_name_reply_t * mp)
2280 {
2281   clib_warning ("not implemented");
2282 }
2283
2284 static void vl_api_dns_resolve_ip_reply_t_handler
2285   (vl_api_dns_resolve_ip_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   i32 retval = ntohl (mp->retval);
2289   if (vam->async_mode)
2290     {
2291       vam->async_errors += (retval < 0);
2292     }
2293   else
2294     {
2295       vam->retval = retval;
2296       vam->result_ready = 1;
2297
2298       if (retval == 0)
2299         {
2300           clib_warning ("canonical name %s", mp->name);
2301         }
2302       else
2303         clib_warning ("retval %d", retval);
2304     }
2305 }
2306
2307 static void vl_api_dns_resolve_ip_reply_t_handler_json
2308   (vl_api_dns_resolve_ip_reply_t * mp)
2309 {
2310   clib_warning ("not implemented");
2311 }
2312
2313
2314 static void vl_api_ip_address_details_t_handler
2315   (vl_api_ip_address_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   static ip_address_details_t empty_ip_address_details = { {0} };
2319   ip_address_details_t *address = NULL;
2320   ip_details_t *current_ip_details = NULL;
2321   ip_details_t *details = NULL;
2322
2323   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2324
2325   if (!details || vam->current_sw_if_index >= vec_len (details)
2326       || !details[vam->current_sw_if_index].present)
2327     {
2328       errmsg ("ip address details arrived but not stored");
2329       errmsg ("ip_dump should be called first");
2330       return;
2331     }
2332
2333   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2334
2335 #define addresses (current_ip_details->addr)
2336
2337   vec_validate_init_empty (addresses, vec_len (addresses),
2338                            empty_ip_address_details);
2339
2340   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2341
2342   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2343   address->prefix_length = mp->prefix_length;
2344 #undef addresses
2345 }
2346
2347 static void vl_api_ip_address_details_t_handler_json
2348   (vl_api_ip_address_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   vat_json_node_t *node = NULL;
2352   struct in6_addr ip6;
2353   struct in_addr ip4;
2354
2355   if (VAT_JSON_ARRAY != vam->json_tree.type)
2356     {
2357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2358       vat_json_init_array (&vam->json_tree);
2359     }
2360   node = vat_json_array_add (&vam->json_tree);
2361
2362   vat_json_init_object (node);
2363   if (vam->is_ipv6)
2364     {
2365       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2366       vat_json_object_add_ip6 (node, "ip", ip6);
2367     }
2368   else
2369     {
2370       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2371       vat_json_object_add_ip4 (node, "ip", ip4);
2372     }
2373   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2374 }
2375
2376 static void
2377 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   static ip_details_t empty_ip_details = { 0 };
2381   ip_details_t *ip = NULL;
2382   u32 sw_if_index = ~0;
2383
2384   sw_if_index = ntohl (mp->sw_if_index);
2385
2386   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2387                            sw_if_index, empty_ip_details);
2388
2389   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2390                          sw_if_index);
2391
2392   ip->present = 1;
2393 }
2394
2395 static void
2396 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   if (VAT_JSON_ARRAY != vam->json_tree.type)
2401     {
2402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2403       vat_json_init_array (&vam->json_tree);
2404     }
2405   vat_json_array_add_uint (&vam->json_tree,
2406                            clib_net_to_host_u32 (mp->sw_if_index));
2407 }
2408
2409 static void vl_api_map_domain_details_t_handler_json
2410   (vl_api_map_domain_details_t * mp)
2411 {
2412   vat_json_node_t *node = NULL;
2413   vat_main_t *vam = &vat_main;
2414   struct in6_addr ip6;
2415   struct in_addr ip4;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422
2423   node = vat_json_array_add (&vam->json_tree);
2424   vat_json_init_object (node);
2425
2426   vat_json_object_add_uint (node, "domain_index",
2427                             clib_net_to_host_u32 (mp->domain_index));
2428   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2429   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2430   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2431   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2432   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2433   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2434   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2435   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2436   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2437   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2438   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2439   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2440   vat_json_object_add_uint (node, "flags", mp->flags);
2441   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2442   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2443 }
2444
2445 static void vl_api_map_domain_details_t_handler
2446   (vl_api_map_domain_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   if (mp->is_translation)
2451     {
2452       print (vam->ofp,
2453              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2454              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2455              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2456              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2457              clib_net_to_host_u32 (mp->domain_index));
2458     }
2459   else
2460     {
2461       print (vam->ofp,
2462              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2463              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2464              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2465              format_ip6_address, mp->ip6_src,
2466              clib_net_to_host_u32 (mp->domain_index));
2467     }
2468   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2469          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2470          mp->is_translation ? "map-t" : "");
2471 }
2472
2473 static void vl_api_map_rule_details_t_handler_json
2474   (vl_api_map_rule_details_t * mp)
2475 {
2476   struct in6_addr ip6;
2477   vat_json_node_t *node = NULL;
2478   vat_main_t *vam = &vat_main;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485
2486   node = vat_json_array_add (&vam->json_tree);
2487   vat_json_init_object (node);
2488
2489   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2490   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2491   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2492 }
2493
2494 static void
2495 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2499          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2500 }
2501
2502 static void
2503 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2504 {
2505   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2506           "router_addr %U host_mac %U",
2507           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2508           format_ip4_address, &mp->host_address,
2509           format_ip4_address, &mp->router_address,
2510           format_ethernet_address, mp->host_mac);
2511 }
2512
2513 static void vl_api_dhcp_compl_event_t_handler_json
2514   (vl_api_dhcp_compl_event_t * mp)
2515 {
2516   /* JSON output not supported */
2517 }
2518
2519 static void
2520 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2521                               u32 counter)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   static u64 default_counter = 0;
2525
2526   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2527                            NULL);
2528   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2529                            sw_if_index, default_counter);
2530   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2531 }
2532
2533 static void
2534 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2535                                 interface_counter_t counter)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   static interface_counter_t default_counter = { 0, };
2539
2540   vec_validate_init_empty (vam->combined_interface_counters,
2541                            vnet_counter_type, NULL);
2542   vec_validate_init_empty (vam->combined_interface_counters
2543                            [vnet_counter_type], sw_if_index, default_counter);
2544   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2545 }
2546
2547 static void vl_api_vnet_interface_simple_counters_t_handler
2548   (vl_api_vnet_interface_simple_counters_t * mp)
2549 {
2550   /* not supported */
2551 }
2552
2553 static void vl_api_vnet_interface_combined_counters_t_handler
2554   (vl_api_vnet_interface_combined_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler_json
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   u64 *v_packets;
2563   u64 packets;
2564   u32 count;
2565   u32 first_sw_if_index;
2566   int i;
2567
2568   count = ntohl (mp->count);
2569   first_sw_if_index = ntohl (mp->first_sw_if_index);
2570
2571   v_packets = (u64 *) & mp->data;
2572   for (i = 0; i < count; i++)
2573     {
2574       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2575       set_simple_interface_counter (mp->vnet_counter_type,
2576                                     first_sw_if_index + i, packets);
2577       v_packets++;
2578     }
2579 }
2580
2581 static void vl_api_vnet_interface_combined_counters_t_handler_json
2582   (vl_api_vnet_interface_combined_counters_t * mp)
2583 {
2584   interface_counter_t counter;
2585   vlib_counter_t *v;
2586   u32 first_sw_if_index;
2587   int i;
2588   u32 count;
2589
2590   count = ntohl (mp->count);
2591   first_sw_if_index = ntohl (mp->first_sw_if_index);
2592
2593   v = (vlib_counter_t *) & mp->data;
2594   for (i = 0; i < count; i++)
2595     {
2596       counter.packets =
2597         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2598       counter.bytes =
2599         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2600       set_combined_interface_counter (mp->vnet_counter_type,
2601                                       first_sw_if_index + i, counter);
2602       v++;
2603     }
2604 }
2605
2606 static u32
2607 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i;
2611
2612   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2613     {
2614       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2615         {
2616           return i;
2617         }
2618     }
2619   return ~0;
2620 }
2621
2622 static u32
2623 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static void vl_api_vnet_ip4_fib_counters_t_handler
2639   (vl_api_vnet_ip4_fib_counters_t * mp)
2640 {
2641   /* not supported */
2642 }
2643
2644 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2645   (vl_api_vnet_ip4_fib_counters_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vl_api_ip4_fib_counter_t *v;
2649   ip4_fib_counter_t *counter;
2650   struct in_addr ip4;
2651   u32 vrf_id;
2652   u32 vrf_index;
2653   u32 count;
2654   int i;
2655
2656   vrf_id = ntohl (mp->vrf_id);
2657   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2658   if (~0 == vrf_index)
2659     {
2660       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2661       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2662       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2663       vec_validate (vam->ip4_fib_counters, vrf_index);
2664       vam->ip4_fib_counters[vrf_index] = NULL;
2665     }
2666
2667   vec_free (vam->ip4_fib_counters[vrf_index]);
2668   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2669   count = ntohl (mp->count);
2670   for (i = 0; i < count; i++)
2671     {
2672       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2673       counter = &vam->ip4_fib_counters[vrf_index][i];
2674       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2675       counter->address = ip4;
2676       counter->address_length = v->address_length;
2677       counter->packets = clib_net_to_host_u64 (v->packets);
2678       counter->bytes = clib_net_to_host_u64 (v->bytes);
2679       v++;
2680     }
2681 }
2682
2683 static void vl_api_vnet_ip4_nbr_counters_t_handler
2684   (vl_api_vnet_ip4_nbr_counters_t * mp)
2685 {
2686   /* not supported */
2687 }
2688
2689 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2690   (vl_api_vnet_ip4_nbr_counters_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vl_api_ip4_nbr_counter_t *v;
2694   ip4_nbr_counter_t *counter;
2695   u32 sw_if_index;
2696   u32 count;
2697   int i;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700   count = ntohl (mp->count);
2701   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2702
2703   if (mp->begin)
2704     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2705
2706   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2707   for (i = 0; i < count; i++)
2708     {
2709       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2710       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2711       counter->address.s_addr = v->address;
2712       counter->packets = clib_net_to_host_u64 (v->packets);
2713       counter->bytes = clib_net_to_host_u64 (v->bytes);
2714       counter->linkt = v->link_type;
2715       v++;
2716     }
2717 }
2718
2719 static void vl_api_vnet_ip6_fib_counters_t_handler
2720   (vl_api_vnet_ip6_fib_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2726   (vl_api_vnet_ip6_fib_counters_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   vl_api_ip6_fib_counter_t *v;
2730   ip6_fib_counter_t *counter;
2731   struct in6_addr ip6;
2732   u32 vrf_id;
2733   u32 vrf_index;
2734   u32 count;
2735   int i;
2736
2737   vrf_id = ntohl (mp->vrf_id);
2738   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2739   if (~0 == vrf_index)
2740     {
2741       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2742       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2743       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2744       vec_validate (vam->ip6_fib_counters, vrf_index);
2745       vam->ip6_fib_counters[vrf_index] = NULL;
2746     }
2747
2748   vec_free (vam->ip6_fib_counters[vrf_index]);
2749   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2750   count = ntohl (mp->count);
2751   for (i = 0; i < count; i++)
2752     {
2753       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2754       counter = &vam->ip6_fib_counters[vrf_index][i];
2755       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2756       counter->address = ip6;
2757       counter->address_length = v->address_length;
2758       counter->packets = clib_net_to_host_u64 (v->packets);
2759       counter->bytes = clib_net_to_host_u64 (v->bytes);
2760       v++;
2761     }
2762 }
2763
2764 static void vl_api_vnet_ip6_nbr_counters_t_handler
2765   (vl_api_vnet_ip6_nbr_counters_t * mp)
2766 {
2767   /* not supported */
2768 }
2769
2770 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2771   (vl_api_vnet_ip6_nbr_counters_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vl_api_ip6_nbr_counter_t *v;
2775   ip6_nbr_counter_t *counter;
2776   struct in6_addr ip6;
2777   u32 sw_if_index;
2778   u32 count;
2779   int i;
2780
2781   sw_if_index = ntohl (mp->sw_if_index);
2782   count = ntohl (mp->count);
2783   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2784
2785   if (mp->begin)
2786     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2787
2788   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2789   for (i = 0; i < count; i++)
2790     {
2791       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2792       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2793       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2794       counter->address = ip6;
2795       counter->packets = clib_net_to_host_u64 (v->packets);
2796       counter->bytes = clib_net_to_host_u64 (v->bytes);
2797       v++;
2798     }
2799 }
2800
2801 static void vl_api_get_first_msg_id_reply_t_handler
2802   (vl_api_get_first_msg_id_reply_t * mp)
2803 {
2804   vat_main_t *vam = &vat_main;
2805   i32 retval = ntohl (mp->retval);
2806
2807   if (vam->async_mode)
2808     {
2809       vam->async_errors += (retval < 0);
2810     }
2811   else
2812     {
2813       vam->retval = retval;
2814       vam->result_ready = 1;
2815     }
2816   if (retval >= 0)
2817     {
2818       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2819     }
2820 }
2821
2822 static void vl_api_get_first_msg_id_reply_t_handler_json
2823   (vl_api_get_first_msg_id_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t node;
2827
2828   vat_json_init_object (&node);
2829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2830   vat_json_object_add_uint (&node, "first_msg_id",
2831                             (uint) ntohs (mp->first_msg_id));
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void vl_api_get_node_graph_reply_t_handler
2841   (vl_api_get_node_graph_reply_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   api_main_t *am = &api_main;
2845   i32 retval = ntohl (mp->retval);
2846   u8 *pvt_copy, *reply;
2847   void *oldheap;
2848   vlib_node_t *node;
2849   int i;
2850
2851   if (vam->async_mode)
2852     {
2853       vam->async_errors += (retval < 0);
2854     }
2855   else
2856     {
2857       vam->retval = retval;
2858       vam->result_ready = 1;
2859     }
2860
2861   /* "Should never happen..." */
2862   if (retval != 0)
2863     return;
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866   pvt_copy = vec_dup (reply);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   if (vam->graph_nodes)
2878     {
2879       hash_free (vam->graph_node_index_by_name);
2880
2881       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2882         {
2883           node = vam->graph_nodes[i];
2884           vec_free (node->name);
2885           vec_free (node->next_nodes);
2886           vec_free (node);
2887         }
2888       vec_free (vam->graph_nodes);
2889     }
2890
2891   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2892   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2893   vec_free (pvt_copy);
2894
2895   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2896     {
2897       node = vam->graph_nodes[i];
2898       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2899     }
2900 }
2901
2902 static void vl_api_get_node_graph_reply_t_handler_json
2903   (vl_api_get_node_graph_reply_t * mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   api_main_t *am = &api_main;
2907   void *oldheap;
2908   vat_json_node_t node;
2909   u8 *reply;
2910
2911   /* $$$$ make this real? */
2912   vat_json_init_object (&node);
2913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2914   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2915
2916   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2917
2918   /* Toss the shared-memory original... */
2919   pthread_mutex_lock (&am->vlib_rp->mutex);
2920   oldheap = svm_push_data_heap (am->vlib_rp);
2921
2922   vec_free (reply);
2923
2924   svm_pop_heap (oldheap);
2925   pthread_mutex_unlock (&am->vlib_rp->mutex);
2926
2927   vat_json_print (vam->ofp, &node);
2928   vat_json_free (&node);
2929
2930   vam->retval = ntohl (mp->retval);
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   u8 *s = 0;
2939
2940   if (mp->local)
2941     {
2942       s = format (s, "%=16d%=16d%=16d",
2943                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2944     }
2945   else
2946     {
2947       s = format (s, "%=16U%=16d%=16d",
2948                   mp->is_ipv6 ? format_ip6_address :
2949                   format_ip4_address,
2950                   mp->ip_address, mp->priority, mp->weight);
2951     }
2952
2953   print (vam->ofp, "%v", s);
2954   vec_free (s);
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = NULL;
2962   struct in6_addr ip6;
2963   struct in_addr ip4;
2964
2965   if (VAT_JSON_ARRAY != vam->json_tree.type)
2966     {
2967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2968       vat_json_init_array (&vam->json_tree);
2969     }
2970   node = vat_json_array_add (&vam->json_tree);
2971   vat_json_init_object (node);
2972
2973   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2974   vat_json_object_add_uint (node, "priority", mp->priority);
2975   vat_json_object_add_uint (node, "weight", mp->weight);
2976
2977   if (mp->local)
2978     vat_json_object_add_uint (node, "sw_if_index",
2979                               clib_net_to_host_u32 (mp->sw_if_index));
2980   else
2981     {
2982       if (mp->is_ipv6)
2983         {
2984           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2985           vat_json_object_add_ip6 (node, "address", ip6);
2986         }
2987       else
2988         {
2989           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2990           vat_json_object_add_ip4 (node, "address", ip4);
2991         }
2992     }
2993 }
2994
2995 static void
2996 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2997                                           mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   u8 *ls_name = 0;
3001
3002   ls_name = format (0, "%s", mp->ls_name);
3003
3004   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3005          ls_name);
3006   vec_free (ls_name);
3007 }
3008
3009 static void
3010   vl_api_one_locator_set_details_t_handler_json
3011   (vl_api_one_locator_set_details_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t *node = 0;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018   vec_add1 (ls_name, 0);
3019
3020   if (VAT_JSON_ARRAY != vam->json_tree.type)
3021     {
3022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3023       vat_json_init_array (&vam->json_tree);
3024     }
3025   node = vat_json_array_add (&vam->json_tree);
3026
3027   vat_json_init_object (node);
3028   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3029   vat_json_object_add_uint (node, "ls_index",
3030                             clib_net_to_host_u32 (mp->ls_index));
3031   vec_free (ls_name);
3032 }
3033
3034 typedef struct
3035 {
3036   u32 spi;
3037   u8 si;
3038 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3039
3040 uword
3041 unformat_nsh_address (unformat_input_t * input, va_list * args)
3042 {
3043   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3044   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3045 }
3046
3047 u8 *
3048 format_nsh_address_vat (u8 * s, va_list * args)
3049 {
3050   nsh_t *a = va_arg (*args, nsh_t *);
3051   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3052 }
3053
3054 static u8 *
3055 format_lisp_flat_eid (u8 * s, va_list * args)
3056 {
3057   u32 type = va_arg (*args, u32);
3058   u8 *eid = va_arg (*args, u8 *);
3059   u32 eid_len = va_arg (*args, u32);
3060
3061   switch (type)
3062     {
3063     case 0:
3064       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3065     case 1:
3066       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3067     case 2:
3068       return format (s, "%U", format_ethernet_address, eid);
3069     case 3:
3070       return format (s, "%U", format_nsh_address_vat, eid);
3071     }
3072   return 0;
3073 }
3074
3075 static u8 *
3076 format_lisp_eid_vat (u8 * s, va_list * args)
3077 {
3078   u32 type = va_arg (*args, u32);
3079   u8 *eid = va_arg (*args, u8 *);
3080   u32 eid_len = va_arg (*args, u32);
3081   u8 *seid = va_arg (*args, u8 *);
3082   u32 seid_len = va_arg (*args, u32);
3083   u32 is_src_dst = va_arg (*args, u32);
3084
3085   if (is_src_dst)
3086     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3087
3088   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3089
3090   return s;
3091 }
3092
3093 static void
3094 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   u8 *s = 0, *eid = 0;
3098
3099   if (~0 == mp->locator_set_index)
3100     s = format (0, "action: %d", mp->action);
3101   else
3102     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3103
3104   eid = format (0, "%U", format_lisp_eid_vat,
3105                 mp->eid_type,
3106                 mp->eid,
3107                 mp->eid_prefix_len,
3108                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109   vec_add1 (eid, 0);
3110
3111   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3112          clib_net_to_host_u32 (mp->vni),
3113          eid,
3114          mp->is_local ? "local" : "remote",
3115          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3116          clib_net_to_host_u16 (mp->key_id), mp->key);
3117
3118   vec_free (s);
3119   vec_free (eid);
3120 }
3121
3122 static void
3123 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3124                                              * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = 0;
3128   u8 *eid = 0;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136
3137   vat_json_init_object (node);
3138   if (~0 == mp->locator_set_index)
3139     vat_json_object_add_uint (node, "action", mp->action);
3140   else
3141     vat_json_object_add_uint (node, "locator_set_index",
3142                               clib_net_to_host_u32 (mp->locator_set_index));
3143
3144   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3145   if (mp->eid_type == 3)
3146     {
3147       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3148       vat_json_init_object (nsh_json);
3149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3150       vat_json_object_add_uint (nsh_json, "spi",
3151                                 clib_net_to_host_u32 (nsh->spi));
3152       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3153     }
3154   else
3155     {
3156       eid = format (0, "%U", format_lisp_eid_vat,
3157                     mp->eid_type,
3158                     mp->eid,
3159                     mp->eid_prefix_len,
3160                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3161       vec_add1 (eid, 0);
3162       vat_json_object_add_string_copy (node, "eid", eid);
3163       vec_free (eid);
3164     }
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3167   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3168
3169   if (mp->key_id)
3170     {
3171       vat_json_object_add_uint (node, "key_id",
3172                                 clib_net_to_host_u16 (mp->key_id));
3173       vat_json_object_add_string_copy (node, "key", mp->key);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   u8 *seid = 0, *deid = 0;
3182   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3183
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   if (mp->is_ip4)
3194     format_ip_address_fcn = format_ip4_address;
3195   else
3196     format_ip_address_fcn = format_ip6_address;
3197
3198
3199   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3200          clib_net_to_host_u32 (mp->vni),
3201          seid, deid,
3202          format_ip_address_fcn, mp->lloc,
3203          format_ip_address_fcn, mp->rloc,
3204          clib_net_to_host_u32 (mp->pkt_count),
3205          clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3213 {
3214   struct in6_addr ip6;
3215   struct in_addr ip4;
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = 0;
3218   u8 *deid = 0, *seid = 0;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   deid = format (0, "%U", format_lisp_eid_vat,
3229                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3230
3231   seid = format (0, "%U", format_lisp_eid_vat,
3232                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3233
3234   vec_add1 (deid, 0);
3235   vec_add1 (seid, 0);
3236
3237   vat_json_object_add_string_copy (node, "seid", seid);
3238   vat_json_object_add_string_copy (node, "deid", deid);
3239   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3240
3241   if (mp->is_ip4)
3242     {
3243       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3244       vat_json_object_add_ip4 (node, "lloc", ip4);
3245       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "rloc", ip4);
3247     }
3248   else
3249     {
3250       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3251       vat_json_object_add_ip6 (node, "lloc", ip6);
3252       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3253       vat_json_object_add_ip6 (node, "rloc", ip6);
3254     }
3255   vat_json_object_add_uint (node, "pkt_count",
3256                             clib_net_to_host_u32 (mp->pkt_count));
3257   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3258
3259   vec_free (deid);
3260   vec_free (seid);
3261 }
3262
3263 static void
3264   vl_api_one_eid_table_map_details_t_handler
3265   (vl_api_one_eid_table_map_details_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268
3269   u8 *line = format (0, "%=10d%=10d",
3270                      clib_net_to_host_u32 (mp->vni),
3271                      clib_net_to_host_u32 (mp->dp_table));
3272   print (vam->ofp, "%v", line);
3273   vec_free (line);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler_json
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node = NULL;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "dp_table",
3291                             clib_net_to_host_u32 (mp->dp_table));
3292   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3293 }
3294
3295 static void
3296   vl_api_one_eid_table_vni_details_t_handler
3297   (vl_api_one_eid_table_vni_details_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3302   print (vam->ofp, "%v", line);
3303   vec_free (line);
3304 }
3305
3306 static void
3307   vl_api_one_eid_table_vni_details_t_handler_json
3308   (vl_api_one_eid_table_vni_details_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t *node = NULL;
3312
3313   if (VAT_JSON_ARRAY != vam->json_tree.type)
3314     {
3315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3316       vat_json_init_array (&vam->json_tree);
3317     }
3318   node = vat_json_array_add (&vam->json_tree);
3319   vat_json_init_object (node);
3320   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3325   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3331   print (vam->ofp, "fallback threshold value: %d", mp->value);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3339   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   vat_json_init_object (node);
3347   vat_json_object_add_uint (node, "value", mp->value);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_map_register_state_reply_t_handler
3358   (vl_api_show_one_map_register_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler_json
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t _node, *node = &_node;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3378
3379   vat_json_init_object (node);
3380   vat_json_object_add_string_copy (node, "state", s);
3381
3382   vat_json_print (vam->ofp, node);
3383   vat_json_free (node);
3384
3385   vam->retval = retval;
3386   vam->result_ready = 1;
3387   vec_free (s);
3388 }
3389
3390 static void
3391   vl_api_show_one_rloc_probe_state_reply_t_handler
3392   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   int retval = clib_net_to_host_u32 (mp->retval);
3396
3397   if (retval)
3398     goto end;
3399
3400   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t _node, *node = &_node;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3415   vat_json_init_object (node);
3416   vat_json_object_add_string_copy (node, "state", s);
3417
3418   vat_json_print (vam->ofp, node);
3419   vat_json_free (node);
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423   vec_free (s);
3424 }
3425
3426 static void
3427   vl_api_show_one_stats_enable_disable_reply_t_handler
3428   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432
3433   if (retval)
3434     goto end;
3435
3436   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3437 end:
3438   vam->retval = retval;
3439   vam->result_ready = 1;
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t _node, *node = &_node;
3448   int retval = clib_net_to_host_u32 (mp->retval);
3449
3450   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3451   vat_json_init_object (node);
3452   vat_json_object_add_string_copy (node, "state", s);
3453
3454   vat_json_print (vam->ofp, node);
3455   vat_json_free (node);
3456
3457   vam->retval = retval;
3458   vam->result_ready = 1;
3459   vec_free (s);
3460 }
3461
3462 static void
3463 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3464 {
3465   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3466   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3467   e->vni = clib_net_to_host_u32 (e->vni);
3468 }
3469
3470 static void
3471   gpe_fwd_entries_get_reply_t_net_to_host
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u32 i;
3475
3476   mp->count = clib_net_to_host_u32 (mp->count);
3477   for (i = 0; i < mp->count; i++)
3478     {
3479       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3480     }
3481 }
3482
3483 static u8 *
3484 format_gpe_encap_mode (u8 * s, va_list * args)
3485 {
3486   u32 mode = va_arg (*args, u32);
3487
3488   switch (mode)
3489     {
3490     case 0:
3491       return format (s, "lisp");
3492     case 1:
3493       return format (s, "vxlan");
3494     }
3495   return 0;
3496 }
3497
3498 static void
3499   vl_api_gpe_get_encap_mode_reply_t_handler
3500   (vl_api_gpe_get_encap_mode_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503
3504   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3505   vam->retval = ntohl (mp->retval);
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510   vl_api_gpe_get_encap_mode_reply_t_handler_json
3511   (vl_api_gpe_get_encap_mode_reply_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t node;
3515
3516   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3517   vec_add1 (encap_mode, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3521
3522   vec_free (encap_mode);
3523   vat_json_print (vam->ofp, &node);
3524   vat_json_free (&node);
3525
3526   vam->retval = ntohl (mp->retval);
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_fwd_entry_path_details_t_handler
3532   (vl_api_gpe_fwd_entry_path_details_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3536
3537   if (mp->lcl_loc.is_ip4)
3538     format_ip_address_fcn = format_ip4_address;
3539   else
3540     format_ip_address_fcn = format_ip6_address;
3541
3542   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3543          format_ip_address_fcn, &mp->lcl_loc,
3544          format_ip_address_fcn, &mp->rmt_loc);
3545 }
3546
3547 static void
3548 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3549 {
3550   struct in6_addr ip6;
3551   struct in_addr ip4;
3552
3553   if (loc->is_ip4)
3554     {
3555       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3556       vat_json_object_add_ip4 (n, "address", ip4);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3561       vat_json_object_add_ip6 (n, "address", ip6);
3562     }
3563   vat_json_object_add_uint (n, "weight", loc->weight);
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entry_path_details_t_handler_json
3568   (vl_api_gpe_fwd_entry_path_details_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   vat_json_node_t *node = NULL;
3572   vat_json_node_t *loc_node;
3573
3574   if (VAT_JSON_ARRAY != vam->json_tree.type)
3575     {
3576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3577       vat_json_init_array (&vam->json_tree);
3578     }
3579   node = vat_json_array_add (&vam->json_tree);
3580   vat_json_init_object (node);
3581
3582   loc_node = vat_json_object_add (node, "local_locator");
3583   vat_json_init_object (loc_node);
3584   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3585
3586   loc_node = vat_json_object_add (node, "remote_locator");
3587   vat_json_init_object (loc_node);
3588   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3589 }
3590
3591 static void
3592   vl_api_gpe_fwd_entries_get_reply_t_handler
3593   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_fwd_entry_t *e;
3599
3600   if (retval)
3601     goto end;
3602
3603   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3604
3605   for (i = 0; i < mp->count; i++)
3606     {
3607       e = &mp->entries[i];
3608       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3609              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3610              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3611     }
3612
3613 end:
3614   vam->retval = retval;
3615   vam->result_ready = 1;
3616 }
3617
3618 static void
3619   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3620   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3621 {
3622   u8 *s = 0;
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t *e = 0, root;
3625   u32 i;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_fwd_entry_t *fwd;
3628
3629   if (retval)
3630     goto end;
3631
3632   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < mp->count; i++)
3636     {
3637       e = vat_json_array_add (&root);
3638       fwd = &mp->entries[i];
3639
3640       vat_json_init_object (e);
3641       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3642       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3643       vat_json_object_add_int (e, "vni", fwd->vni);
3644       vat_json_object_add_int (e, "action", fwd->action);
3645
3646       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3647                   fwd->leid_prefix_len);
3648       vec_add1 (s, 0);
3649       vat_json_object_add_string_copy (e, "leid", s);
3650       vec_free (s);
3651
3652       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3653                   fwd->reid_prefix_len);
3654       vec_add1 (s, 0);
3655       vat_json_object_add_string_copy (e, "reid", s);
3656       vec_free (s);
3657     }
3658
3659   vat_json_print (vam->ofp, &root);
3660   vat_json_free (&root);
3661
3662 end:
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3669   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_gpe_native_fwd_rpath_t *r;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     {
3683       r = &mp->entries[i];
3684       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3685              clib_net_to_host_u32 (r->fib_index),
3686              clib_net_to_host_u32 (r->nh_sw_if_index),
3687              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3688     }
3689
3690 end:
3691   vam->retval = retval;
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3697   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   vat_json_node_t root, *e;
3701   u32 i, n;
3702   int retval = clib_net_to_host_u32 (mp->retval);
3703   vl_api_gpe_native_fwd_rpath_t *r;
3704   u8 *s;
3705
3706   if (retval)
3707     goto end;
3708
3709   n = clib_net_to_host_u32 (mp->count);
3710   vat_json_init_array (&root);
3711
3712   for (i = 0; i < n; i++)
3713     {
3714       e = vat_json_array_add (&root);
3715       vat_json_init_object (e);
3716       r = &mp->entries[i];
3717       s =
3718         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3719                 r->nh_addr);
3720       vec_add1 (s, 0);
3721       vat_json_object_add_string_copy (e, "ip4", s);
3722       vec_free (s);
3723
3724       vat_json_object_add_uint (e, "fib_index",
3725                                 clib_net_to_host_u32 (r->fib_index));
3726       vat_json_object_add_uint (e, "nh_sw_if_index",
3727                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3728     }
3729
3730   vat_json_print (vam->ofp, &root);
3731   vat_json_free (&root);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3740   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743   u32 i, n;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745
3746   if (retval)
3747     goto end;
3748
3749   n = clib_net_to_host_u32 (mp->count);
3750
3751   for (i = 0; i < n; i++)
3752     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3761   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_ndp_entries_get_reply_t_handler
3787   (vl_api_one_ndp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_entries_get_reply_t_handler_json
3809   (vl_api_one_ndp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_ndp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip6", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_entries_get_reply_t_handler
3852   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   u32 i, n;
3856   int retval = clib_net_to_host_u32 (mp->retval);
3857
3858   if (retval)
3859     goto end;
3860
3861   n = clib_net_to_host_u32 (mp->count);
3862
3863   for (i = 0; i < n; i++)
3864     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3865            format_ethernet_address, mp->entries[i].mac);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3874   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3875 {
3876   u8 *s = 0;
3877   vat_main_t *vam = &vat_main;
3878   vat_json_node_t *e = 0, root;
3879   u32 i, n;
3880   int retval = clib_net_to_host_u32 (mp->retval);
3881   vl_api_one_l2_arp_entry_t *arp_entry;
3882
3883   if (retval)
3884     goto end;
3885
3886   n = clib_net_to_host_u32 (mp->count);
3887   vat_json_init_array (&root);
3888
3889   for (i = 0; i < n; i++)
3890     {
3891       e = vat_json_array_add (&root);
3892       arp_entry = &mp->entries[i];
3893
3894       vat_json_init_object (e);
3895       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3896       vec_add1 (s, 0);
3897
3898       vat_json_object_add_string_copy (e, "mac", s);
3899       vec_free (s);
3900
3901       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3902       vec_add1 (s, 0);
3903       vat_json_object_add_string_copy (e, "ip4", s);
3904       vec_free (s);
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_ndp_bd_get_reply_t_handler_json
3939   (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_l2_arp_bd_get_reply_t_handler
3968   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973
3974   if (retval)
3975     goto end;
3976
3977   n = clib_net_to_host_u32 (mp->count);
3978
3979   for (i = 0; i < n; i++)
3980     {
3981       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3982     }
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002   vat_json_init_array (&root);
4003
4004   for (i = 0; i < n; i++)
4005     {
4006       vat_json_array_add_uint (&root,
4007                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4008     }
4009
4010   vat_json_print (vam->ofp, &root);
4011   vat_json_free (&root);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_adjacencies_get_reply_t_handler
4020   (vl_api_one_adjacencies_get_reply_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   u32 i, n;
4024   int retval = clib_net_to_host_u32 (mp->retval);
4025   vl_api_one_adjacency_t *a;
4026
4027   if (retval)
4028     goto end;
4029
4030   n = clib_net_to_host_u32 (mp->count);
4031
4032   for (i = 0; i < n; i++)
4033     {
4034       a = &mp->adjacencies[i];
4035       print (vam->ofp, "%U %40U",
4036              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4037              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4038     }
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_adjacencies_get_reply_t_handler_json
4047   (vl_api_one_adjacencies_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_adjacency_t *a;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       a = &mp->adjacencies[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4069                   a->leid_prefix_len);
4070       vec_add1 (s, 0);
4071       vat_json_object_add_string_copy (e, "leid", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4075                   a->reid_prefix_len);
4076       vec_add1 (s, 0);
4077       vat_json_object_add_string_copy (e, "reid", s);
4078       vec_free (s);
4079     }
4080
4081   vat_json_print (vam->ofp, &root);
4082   vat_json_free (&root);
4083
4084 end:
4085   vam->retval = retval;
4086   vam->result_ready = 1;
4087 }
4088
4089 static void
4090 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093
4094   print (vam->ofp, "%=20U",
4095          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4096          mp->ip_address);
4097 }
4098
4099 static void
4100   vl_api_one_map_server_details_t_handler_json
4101   (vl_api_one_map_server_details_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105   struct in6_addr ip6;
4106   struct in_addr ip4;
4107
4108   if (VAT_JSON_ARRAY != vam->json_tree.type)
4109     {
4110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4111       vat_json_init_array (&vam->json_tree);
4112     }
4113   node = vat_json_array_add (&vam->json_tree);
4114
4115   vat_json_init_object (node);
4116   if (mp->is_ipv6)
4117     {
4118       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4119       vat_json_object_add_ip6 (node, "map-server", ip6);
4120     }
4121   else
4122     {
4123       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4124       vat_json_object_add_ip4 (node, "map-server", ip4);
4125     }
4126 }
4127
4128 static void
4129 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4130                                            * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133
4134   print (vam->ofp, "%=20U",
4135          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4136          mp->ip_address);
4137 }
4138
4139 static void
4140   vl_api_one_map_resolver_details_t_handler_json
4141   (vl_api_one_map_resolver_details_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t *node = NULL;
4145   struct in6_addr ip6;
4146   struct in_addr ip4;
4147
4148   if (VAT_JSON_ARRAY != vam->json_tree.type)
4149     {
4150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4151       vat_json_init_array (&vam->json_tree);
4152     }
4153   node = vat_json_array_add (&vam->json_tree);
4154
4155   vat_json_init_object (node);
4156   if (mp->is_ipv6)
4157     {
4158       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4159       vat_json_object_add_ip6 (node, "map resolver", ip6);
4160     }
4161   else
4162     {
4163       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4164       vat_json_object_add_ip4 (node, "map resolver", ip4);
4165     }
4166 }
4167
4168 static void
4169 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4170 {
4171   vat_main_t *vam = &vat_main;
4172   i32 retval = ntohl (mp->retval);
4173
4174   if (0 <= retval)
4175     {
4176       print (vam->ofp, "feature: %s\ngpe: %s",
4177              mp->feature_status ? "enabled" : "disabled",
4178              mp->gpe_status ? "enabled" : "disabled");
4179     }
4180
4181   vam->retval = retval;
4182   vam->result_ready = 1;
4183 }
4184
4185 static void
4186   vl_api_show_one_status_reply_t_handler_json
4187   (vl_api_show_one_status_reply_t * mp)
4188 {
4189   vat_main_t *vam = &vat_main;
4190   vat_json_node_t node;
4191   u8 *gpe_status = NULL;
4192   u8 *feature_status = NULL;
4193
4194   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4195   feature_status = format (0, "%s",
4196                            mp->feature_status ? "enabled" : "disabled");
4197   vec_add1 (gpe_status, 0);
4198   vec_add1 (feature_status, 0);
4199
4200   vat_json_init_object (&node);
4201   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4202   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4203
4204   vec_free (gpe_status);
4205   vec_free (feature_status);
4206
4207   vat_json_print (vam->ofp, &node);
4208   vat_json_free (&node);
4209
4210   vam->retval = ntohl (mp->retval);
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4216   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   i32 retval = ntohl (mp->retval);
4220
4221   if (retval >= 0)
4222     {
4223       print (vam->ofp, "%=20s", mp->locator_set_name);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t *node = NULL;
4236
4237   if (VAT_JSON_ARRAY != vam->json_tree.type)
4238     {
4239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4240       vat_json_init_array (&vam->json_tree);
4241     }
4242   node = vat_json_array_add (&vam->json_tree);
4243
4244   vat_json_init_object (node);
4245   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4246
4247   vat_json_print (vam->ofp, node);
4248   vat_json_free (node);
4249
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static u8 *
4255 format_lisp_map_request_mode (u8 * s, va_list * args)
4256 {
4257   u32 mode = va_arg (*args, u32);
4258
4259   switch (mode)
4260     {
4261     case 0:
4262       return format (0, "dst-only");
4263     case 1:
4264       return format (0, "src-dst");
4265     }
4266   return 0;
4267 }
4268
4269 static void
4270   vl_api_show_one_map_request_mode_reply_t_handler
4271   (vl_api_show_one_map_request_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   i32 retval = ntohl (mp->retval);
4275
4276   if (0 <= retval)
4277     {
4278       u32 mode = mp->mode;
4279       print (vam->ofp, "map_request_mode: %U",
4280              format_lisp_map_request_mode, mode);
4281     }
4282
4283   vam->retval = retval;
4284   vam->result_ready = 1;
4285 }
4286
4287 static void
4288   vl_api_show_one_map_request_mode_reply_t_handler_json
4289   (vl_api_show_one_map_request_mode_reply_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t node;
4293   u8 *s = 0;
4294   u32 mode;
4295
4296   mode = mp->mode;
4297   s = format (0, "%U", format_lisp_map_request_mode, mode);
4298   vec_add1 (s, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vec_free (s);
4306   vam->retval = ntohl (mp->retval);
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_one_show_xtr_mode_reply_t_handler
4312   (vl_api_one_show_xtr_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316
4317   if (0 <= retval)
4318     {
4319       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4320     }
4321
4322   vam->retval = retval;
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler_json
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   vat_json_node_t node;
4332   u8 *status = 0;
4333
4334   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4335   vec_add1 (status, 0);
4336
4337   vat_json_init_object (&node);
4338   vat_json_object_add_string_copy (&node, "status", status);
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_pitr_mode_reply_t_handler
4351   (vl_api_one_show_pitr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler_json
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371   u8 *status = 0;
4372
4373   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4374   vec_add1 (status, 0);
4375
4376   vat_json_init_object (&node);
4377   vat_json_object_add_string_copy (&node, "status", status);
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_petr_mode_reply_t_handler
4390   (vl_api_one_show_petr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   if (0 <= retval)
4396     {
4397       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler_json
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *status = 0;
4411
4412   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4413   vec_add1 (status, 0);
4414
4415   vat_json_init_object (&node);
4416   vat_json_object_add_string_copy (&node, "status", status);
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_use_petr_reply_t_handler
4429   (vl_api_show_one_use_petr_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4437       if (mp->status)
4438         {
4439           print (vam->ofp, "Proxy-ETR address; %U",
4440                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4441                  mp->address);
4442         }
4443     }
4444
4445   vam->retval = retval;
4446   vam->result_ready = 1;
4447 }
4448
4449 static void
4450   vl_api_show_one_use_petr_reply_t_handler_json
4451   (vl_api_show_one_use_petr_reply_t * mp)
4452 {
4453   vat_main_t *vam = &vat_main;
4454   vat_json_node_t node;
4455   u8 *status = 0;
4456   struct in_addr ip4;
4457   struct in6_addr ip6;
4458
4459   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4460   vec_add1 (status, 0);
4461
4462   vat_json_init_object (&node);
4463   vat_json_object_add_string_copy (&node, "status", status);
4464   if (mp->status)
4465     {
4466       if (mp->is_ip4)
4467         {
4468           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4469           vat_json_object_add_ip6 (&node, "address", ip6);
4470         }
4471       else
4472         {
4473           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4474           vat_json_object_add_ip4 (&node, "address", ip4);
4475         }
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_nsh_mapping_reply_t_handler
4489   (vl_api_show_one_nsh_mapping_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "%-20s%-16s",
4497              mp->is_set ? "set" : "not-set",
4498              mp->is_set ? (char *) mp->locator_set_name : "");
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_nsh_mapping_reply_t_handler_json
4507   (vl_api_show_one_nsh_mapping_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511   u8 *status = 0;
4512
4513   status = format (0, "%s", mp->is_set ? "yes" : "no");
4514   vec_add1 (status, 0);
4515
4516   vat_json_init_object (&node);
4517   vat_json_object_add_string_copy (&node, "is_set", status);
4518   if (mp->is_set)
4519     {
4520       vat_json_object_add_string_copy (&node, "locator_set",
4521                                        mp->locator_set_name);
4522     }
4523
4524   vec_free (status);
4525
4526   vat_json_print (vam->ofp, &node);
4527   vat_json_free (&node);
4528
4529   vam->retval = ntohl (mp->retval);
4530   vam->result_ready = 1;
4531 }
4532
4533 static void
4534   vl_api_show_one_map_register_ttl_reply_t_handler
4535   (vl_api_show_one_map_register_ttl_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   i32 retval = ntohl (mp->retval);
4539
4540   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4541
4542   if (0 <= retval)
4543     {
4544       print (vam->ofp, "ttl: %u", mp->ttl);
4545     }
4546
4547   vam->retval = retval;
4548   vam->result_ready = 1;
4549 }
4550
4551 static void
4552   vl_api_show_one_map_register_ttl_reply_t_handler_json
4553   (vl_api_show_one_map_register_ttl_reply_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   vat_json_node_t node;
4557
4558   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4559   vat_json_init_object (&node);
4560   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   i32 retval = ntohl (mp->retval);
4574
4575   if (0 <= retval)
4576     {
4577       print (vam->ofp, "%-20s%-16s",
4578              mp->status ? "enabled" : "disabled",
4579              mp->status ? (char *) mp->locator_set_name : "");
4580     }
4581
4582   vam->retval = retval;
4583   vam->result_ready = 1;
4584 }
4585
4586 static void
4587 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4588 {
4589   vat_main_t *vam = &vat_main;
4590   vat_json_node_t node;
4591   u8 *status = 0;
4592
4593   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4594   vec_add1 (status, 0);
4595
4596   vat_json_init_object (&node);
4597   vat_json_object_add_string_copy (&node, "status", status);
4598   if (mp->status)
4599     {
4600       vat_json_object_add_string_copy (&node, "locator_set",
4601                                        mp->locator_set_name);
4602     }
4603
4604   vec_free (status);
4605
4606   vat_json_print (vam->ofp, &node);
4607   vat_json_free (&node);
4608
4609   vam->retval = ntohl (mp->retval);
4610   vam->result_ready = 1;
4611 }
4612
4613 static u8 *
4614 format_policer_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4619     s = format (s, "1r2c");
4620   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4621     s = format (s, "1r3c");
4622   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4623     s = format (s, "2r3c-2698");
4624   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4625     s = format (s, "2r3c-4115");
4626   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4627     s = format (s, "2r3c-mef5cf1");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_policer_rate_type (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637
4638   if (i == SSE2_QOS_RATE_KBPS)
4639     s = format (s, "kbps");
4640   else if (i == SSE2_QOS_RATE_PPS)
4641     s = format (s, "pps");
4642   else
4643     s = format (s, "ILLEGAL");
4644   return s;
4645 }
4646
4647 static u8 *
4648 format_policer_round_type (u8 * s, va_list * va)
4649 {
4650   u32 i = va_arg (*va, u32);
4651
4652   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4653     s = format (s, "closest");
4654   else if (i == SSE2_QOS_ROUND_TO_UP)
4655     s = format (s, "up");
4656   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4657     s = format (s, "down");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_action_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ACTION_DROP)
4669     s = format (s, "drop");
4670   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4671     s = format (s, "transmit");
4672   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4673     s = format (s, "mark-and-transmit");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_dscp (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683   char *t = 0;
4684
4685   switch (i)
4686     {
4687 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4688       foreach_vnet_dscp
4689 #undef _
4690     default:
4691       return format (s, "ILLEGAL");
4692     }
4693   s = format (s, "%s", t);
4694   return s;
4695 }
4696
4697 static void
4698 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4702
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705   else
4706     conform_dscp_str = format (0, "");
4707
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710   else
4711     exceed_dscp_str = format (0, "");
4712
4713   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4714     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4715   else
4716     violate_dscp_str = format (0, "");
4717
4718   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4719          "rate type %U, round type %U, %s rate, %s color-aware, "
4720          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4721          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4722          "conform action %U%s, exceed action %U%s, violate action %U%s",
4723          mp->name,
4724          format_policer_type, mp->type,
4725          ntohl (mp->cir),
4726          ntohl (mp->eir),
4727          clib_net_to_host_u64 (mp->cb),
4728          clib_net_to_host_u64 (mp->eb),
4729          format_policer_rate_type, mp->rate_type,
4730          format_policer_round_type, mp->round_type,
4731          mp->single_rate ? "single" : "dual",
4732          mp->color_aware ? "is" : "not",
4733          ntohl (mp->cir_tokens_per_period),
4734          ntohl (mp->pir_tokens_per_period),
4735          ntohl (mp->scale),
4736          ntohl (mp->current_limit),
4737          ntohl (mp->current_bucket),
4738          ntohl (mp->extended_limit),
4739          ntohl (mp->extended_bucket),
4740          clib_net_to_host_u64 (mp->last_update_time),
4741          format_policer_action_type, mp->conform_action_type,
4742          conform_dscp_str,
4743          format_policer_action_type, mp->exceed_action_type,
4744          exceed_dscp_str,
4745          format_policer_action_type, mp->violate_action_type,
4746          violate_dscp_str);
4747
4748   vec_free (conform_dscp_str);
4749   vec_free (exceed_dscp_str);
4750   vec_free (violate_dscp_str);
4751 }
4752
4753 static void vl_api_policer_details_t_handler_json
4754   (vl_api_policer_details_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t *node;
4758   u8 *rate_type_str, *round_type_str, *type_str;
4759   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4760
4761   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4762   round_type_str =
4763     format (0, "%U", format_policer_round_type, mp->round_type);
4764   type_str = format (0, "%U", format_policer_type, mp->type);
4765   conform_action_str = format (0, "%U", format_policer_action_type,
4766                                mp->conform_action_type);
4767   exceed_action_str = format (0, "%U", format_policer_action_type,
4768                               mp->exceed_action_type);
4769   violate_action_str = format (0, "%U", format_policer_action_type,
4770                                mp->violate_action_type);
4771
4772   if (VAT_JSON_ARRAY != vam->json_tree.type)
4773     {
4774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4775       vat_json_init_array (&vam->json_tree);
4776     }
4777   node = vat_json_array_add (&vam->json_tree);
4778
4779   vat_json_init_object (node);
4780   vat_json_object_add_string_copy (node, "name", mp->name);
4781   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4782   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4783   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4784   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4785   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4786   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4787   vat_json_object_add_string_copy (node, "type", type_str);
4788   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4789   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4790   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4791   vat_json_object_add_uint (node, "cir_tokens_per_period",
4792                             ntohl (mp->cir_tokens_per_period));
4793   vat_json_object_add_uint (node, "eir_tokens_per_period",
4794                             ntohl (mp->pir_tokens_per_period));
4795   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4796   vat_json_object_add_uint (node, "current_bucket",
4797                             ntohl (mp->current_bucket));
4798   vat_json_object_add_uint (node, "extended_limit",
4799                             ntohl (mp->extended_limit));
4800   vat_json_object_add_uint (node, "extended_bucket",
4801                             ntohl (mp->extended_bucket));
4802   vat_json_object_add_uint (node, "last_update_time",
4803                             ntohl (mp->last_update_time));
4804   vat_json_object_add_string_copy (node, "conform_action",
4805                                    conform_action_str);
4806   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4807     {
4808       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4809       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4810       vec_free (dscp_str);
4811     }
4812   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4813   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4814     {
4815       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4816       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4817       vec_free (dscp_str);
4818     }
4819   vat_json_object_add_string_copy (node, "violate_action",
4820                                    violate_action_str);
4821   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4824       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827
4828   vec_free (rate_type_str);
4829   vec_free (round_type_str);
4830   vec_free (type_str);
4831   vec_free (conform_action_str);
4832   vec_free (exceed_action_str);
4833   vec_free (violate_action_str);
4834 }
4835
4836 static void
4837 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4838                                            mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   int i, count = ntohl (mp->count);
4842
4843   if (count > 0)
4844     print (vam->ofp, "classify table ids (%d) : ", count);
4845   for (i = 0; i < count; i++)
4846     {
4847       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4848       print (vam->ofp, (i < count - 1) ? "," : "");
4849     }
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855   vl_api_classify_table_ids_reply_t_handler_json
4856   (vl_api_classify_table_ids_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   int i, count = ntohl (mp->count);
4860
4861   if (count > 0)
4862     {
4863       vat_json_node_t node;
4864
4865       vat_json_init_object (&node);
4866       for (i = 0; i < count; i++)
4867         {
4868           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4869         }
4870       vat_json_print (vam->ofp, &node);
4871       vat_json_free (&node);
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_by_interface_reply_t_handler
4879   (vl_api_classify_table_by_interface_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   u32 table_id;
4883
4884   table_id = ntohl (mp->l2_table_id);
4885   if (table_id != ~0)
4886     print (vam->ofp, "l2 table id : %d", table_id);
4887   else
4888     print (vam->ofp, "l2 table id : No input ACL tables configured");
4889   table_id = ntohl (mp->ip4_table_id);
4890   if (table_id != ~0)
4891     print (vam->ofp, "ip4 table id : %d", table_id);
4892   else
4893     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4894   table_id = ntohl (mp->ip6_table_id);
4895   if (table_id != ~0)
4896     print (vam->ofp, "ip6 table id : %d", table_id);
4897   else
4898     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4899   vam->retval = ntohl (mp->retval);
4900   vam->result_ready = 1;
4901 }
4902
4903 static void
4904   vl_api_classify_table_by_interface_reply_t_handler_json
4905   (vl_api_classify_table_by_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   vat_json_init_object (&node);
4911
4912   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4913   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4914   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_policer_add_del_reply_t_handler
4924   (vl_api_policer_add_del_reply_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (vam->async_mode)
4929     {
4930       vam->async_errors += (retval < 0);
4931     }
4932   else
4933     {
4934       vam->retval = retval;
4935       vam->result_ready = 1;
4936       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4937         /*
4938          * Note: this is just barely thread-safe, depends on
4939          * the main thread spinning waiting for an answer...
4940          */
4941         errmsg ("policer index %d", ntohl (mp->policer_index));
4942     }
4943 }
4944
4945 static void vl_api_policer_add_del_reply_t_handler_json
4946   (vl_api_policer_add_del_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   vat_json_init_object (&node);
4952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4953   vat_json_object_add_uint (&node, "policer_index",
4954                             ntohl (mp->policer_index));
4955
4956   vat_json_print (vam->ofp, &node);
4957   vat_json_free (&node);
4958
4959   vam->retval = ntohl (mp->retval);
4960   vam->result_ready = 1;
4961 }
4962
4963 /* Format hex dump. */
4964 u8 *
4965 format_hex_bytes (u8 * s, va_list * va)
4966 {
4967   u8 *bytes = va_arg (*va, u8 *);
4968   int n_bytes = va_arg (*va, int);
4969   uword i;
4970
4971   /* Print short or long form depending on byte count. */
4972   uword short_form = n_bytes <= 32;
4973   u32 indent = format_get_indent (s);
4974
4975   if (n_bytes == 0)
4976     return s;
4977
4978   for (i = 0; i < n_bytes; i++)
4979     {
4980       if (!short_form && (i % 32) == 0)
4981         s = format (s, "%08x: ", i);
4982       s = format (s, "%02x", bytes[i]);
4983       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4984         s = format (s, "\n%U", format_white_space, indent);
4985     }
4986
4987   return s;
4988 }
4989
4990 static void
4991 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4992                                             * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   i32 retval = ntohl (mp->retval);
4996   if (retval == 0)
4997     {
4998       print (vam->ofp, "classify table info :");
4999       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5000              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5001              ntohl (mp->miss_next_index));
5002       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5003              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5004              ntohl (mp->match_n_vectors));
5005       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5006              ntohl (mp->mask_length));
5007     }
5008   vam->retval = retval;
5009   vam->result_ready = 1;
5010 }
5011
5012 static void
5013   vl_api_classify_table_info_reply_t_handler_json
5014   (vl_api_classify_table_info_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t node;
5018
5019   i32 retval = ntohl (mp->retval);
5020   if (retval == 0)
5021     {
5022       vat_json_init_object (&node);
5023
5024       vat_json_object_add_int (&node, "sessions",
5025                                ntohl (mp->active_sessions));
5026       vat_json_object_add_int (&node, "nexttbl",
5027                                ntohl (mp->next_table_index));
5028       vat_json_object_add_int (&node, "nextnode",
5029                                ntohl (mp->miss_next_index));
5030       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5031       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5032       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5033       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5034                       ntohl (mp->mask_length), 0);
5035       vat_json_object_add_string_copy (&node, "mask", s);
5036
5037       vat_json_print (vam->ofp, &node);
5038       vat_json_free (&node);
5039     }
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void
5045 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5046                                            mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049
5050   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5051          ntohl (mp->hit_next_index), ntohl (mp->advance),
5052          ntohl (mp->opaque_index));
5053   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5054          ntohl (mp->match_length));
5055 }
5056
5057 static void
5058   vl_api_classify_session_details_t_handler_json
5059   (vl_api_classify_session_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   vat_json_node_t *node = NULL;
5063
5064   if (VAT_JSON_ARRAY != vam->json_tree.type)
5065     {
5066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5067       vat_json_init_array (&vam->json_tree);
5068     }
5069   node = vat_json_array_add (&vam->json_tree);
5070
5071   vat_json_init_object (node);
5072   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5073   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5074   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5075   u8 *s =
5076     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5077             0);
5078   vat_json_object_add_string_copy (node, "match", s);
5079 }
5080
5081 static void vl_api_pg_create_interface_reply_t_handler
5082   (vl_api_pg_create_interface_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085
5086   vam->retval = ntohl (mp->retval);
5087   vam->result_ready = 1;
5088 }
5089
5090 static void vl_api_pg_create_interface_reply_t_handler_json
5091   (vl_api_pg_create_interface_reply_t * mp)
5092 {
5093   vat_main_t *vam = &vat_main;
5094   vat_json_node_t node;
5095
5096   i32 retval = ntohl (mp->retval);
5097   if (retval == 0)
5098     {
5099       vat_json_init_object (&node);
5100
5101       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5102
5103       vat_json_print (vam->ofp, &node);
5104       vat_json_free (&node);
5105     }
5106   vam->retval = ntohl (mp->retval);
5107   vam->result_ready = 1;
5108 }
5109
5110 static void vl_api_policer_classify_details_t_handler
5111   (vl_api_policer_classify_details_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114
5115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5116          ntohl (mp->table_index));
5117 }
5118
5119 static void vl_api_policer_classify_details_t_handler_json
5120   (vl_api_policer_classify_details_t * mp)
5121 {
5122   vat_main_t *vam = &vat_main;
5123   vat_json_node_t *node;
5124
5125   if (VAT_JSON_ARRAY != vam->json_tree.type)
5126     {
5127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5128       vat_json_init_array (&vam->json_tree);
5129     }
5130   node = vat_json_array_add (&vam->json_tree);
5131
5132   vat_json_init_object (node);
5133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5138   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   i32 retval = ntohl (mp->retval);
5142   if (vam->async_mode)
5143     {
5144       vam->async_errors += (retval < 0);
5145     }
5146   else
5147     {
5148       vam->retval = retval;
5149       vam->sw_if_index = ntohl (mp->sw_if_index);
5150       vam->result_ready = 1;
5151     }
5152 }
5153
5154 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5155   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5156 {
5157   vat_main_t *vam = &vat_main;
5158   vat_json_node_t node;
5159
5160   vat_json_init_object (&node);
5161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5162   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5163
5164   vat_json_print (vam->ofp, &node);
5165   vat_json_free (&node);
5166
5167   vam->retval = ntohl (mp->retval);
5168   vam->result_ready = 1;
5169 }
5170
5171 static void vl_api_flow_classify_details_t_handler
5172   (vl_api_flow_classify_details_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175
5176   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5177          ntohl (mp->table_index));
5178 }
5179
5180 static void vl_api_flow_classify_details_t_handler_json
5181   (vl_api_flow_classify_details_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t *node;
5185
5186   if (VAT_JSON_ARRAY != vam->json_tree.type)
5187     {
5188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5189       vat_json_init_array (&vam->json_tree);
5190     }
5191   node = vat_json_array_add (&vam->json_tree);
5192
5193   vat_json_init_object (node);
5194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5195   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5196 }
5197
5198 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5199 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5200 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5201 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5202 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5203 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5204 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5205 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5206 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5207 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5208 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5209 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5210 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5211 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5212 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5213 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5214 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5215 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5216 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5217 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5218 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5219 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5220
5221 /*
5222  * Generate boilerplate reply handlers, which
5223  * dig the return value out of the xxx_reply_t API message,
5224  * stick it into vam->retval, and set vam->result_ready
5225  *
5226  * Could also do this by pointing N message decode slots at
5227  * a single function, but that could break in subtle ways.
5228  */
5229
5230 #define foreach_standard_reply_retval_handler           \
5231 _(sw_interface_set_flags_reply)                         \
5232 _(sw_interface_add_del_address_reply)                   \
5233 _(sw_interface_set_rx_mode_reply)                       \
5234 _(sw_interface_set_table_reply)                         \
5235 _(sw_interface_set_mpls_enable_reply)                   \
5236 _(sw_interface_set_vpath_reply)                         \
5237 _(sw_interface_set_vxlan_bypass_reply)                  \
5238 _(sw_interface_set_geneve_bypass_reply)                 \
5239 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5240 _(sw_interface_set_l2_bridge_reply)                     \
5241 _(bridge_domain_add_del_reply)                          \
5242 _(sw_interface_set_l2_xconnect_reply)                   \
5243 _(l2fib_add_del_reply)                                  \
5244 _(l2fib_flush_int_reply)                                \
5245 _(l2fib_flush_bd_reply)                                 \
5246 _(ip_add_del_route_reply)                               \
5247 _(ip_table_add_del_reply)                               \
5248 _(ip_mroute_add_del_reply)                              \
5249 _(mpls_route_add_del_reply)                             \
5250 _(mpls_table_add_del_reply)                             \
5251 _(mpls_ip_bind_unbind_reply)                            \
5252 _(bier_route_add_del_reply)                             \
5253 _(bier_table_add_del_reply)                             \
5254 _(proxy_arp_add_del_reply)                              \
5255 _(proxy_arp_intfc_enable_disable_reply)                 \
5256 _(sw_interface_set_unnumbered_reply)                    \
5257 _(ip_neighbor_add_del_reply)                            \
5258 _(oam_add_del_reply)                                    \
5259 _(reset_fib_reply)                                      \
5260 _(dhcp_proxy_config_reply)                              \
5261 _(dhcp_proxy_set_vss_reply)                             \
5262 _(dhcp_client_config_reply)                             \
5263 _(set_ip_flow_hash_reply)                               \
5264 _(sw_interface_ip6_enable_disable_reply)                \
5265 _(sw_interface_ip6_set_link_local_address_reply)        \
5266 _(ip6nd_proxy_add_del_reply)                            \
5267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5268 _(sw_interface_ip6nd_ra_config_reply)                   \
5269 _(set_arp_neighbor_limit_reply)                         \
5270 _(l2_patch_add_del_reply)                               \
5271 _(sr_policy_add_reply)                                  \
5272 _(sr_policy_mod_reply)                                  \
5273 _(sr_policy_del_reply)                                  \
5274 _(sr_localsid_add_del_reply)                            \
5275 _(sr_steering_add_del_reply)                            \
5276 _(classify_add_del_session_reply)                       \
5277 _(classify_set_interface_ip_table_reply)                \
5278 _(classify_set_interface_l2_tables_reply)               \
5279 _(l2tpv3_set_tunnel_cookies_reply)                      \
5280 _(l2tpv3_interface_enable_disable_reply)                \
5281 _(l2tpv3_set_lookup_key_reply)                          \
5282 _(l2_fib_clear_table_reply)                             \
5283 _(l2_interface_efp_filter_reply)                        \
5284 _(l2_interface_vlan_tag_rewrite_reply)                  \
5285 _(modify_vhost_user_if_reply)                           \
5286 _(delete_vhost_user_if_reply)                           \
5287 _(want_ip4_arp_events_reply)                            \
5288 _(want_ip6_nd_events_reply)                             \
5289 _(want_l2_macs_events_reply)                            \
5290 _(input_acl_set_interface_reply)                        \
5291 _(ipsec_spd_add_del_reply)                              \
5292 _(ipsec_interface_add_del_spd_reply)                    \
5293 _(ipsec_spd_add_del_entry_reply)                        \
5294 _(ipsec_sad_add_del_entry_reply)                        \
5295 _(ipsec_sa_set_key_reply)                               \
5296 _(ipsec_tunnel_if_add_del_reply)                        \
5297 _(ipsec_tunnel_if_set_key_reply)                        \
5298 _(ipsec_tunnel_if_set_sa_reply)                         \
5299 _(ikev2_profile_add_del_reply)                          \
5300 _(ikev2_profile_set_auth_reply)                         \
5301 _(ikev2_profile_set_id_reply)                           \
5302 _(ikev2_profile_set_ts_reply)                           \
5303 _(ikev2_set_local_key_reply)                            \
5304 _(ikev2_set_responder_reply)                            \
5305 _(ikev2_set_ike_transforms_reply)                       \
5306 _(ikev2_set_esp_transforms_reply)                       \
5307 _(ikev2_set_sa_lifetime_reply)                          \
5308 _(ikev2_initiate_sa_init_reply)                         \
5309 _(ikev2_initiate_del_ike_sa_reply)                      \
5310 _(ikev2_initiate_del_child_sa_reply)                    \
5311 _(ikev2_initiate_rekey_child_sa_reply)                  \
5312 _(delete_loopback_reply)                                \
5313 _(bd_ip_mac_add_del_reply)                              \
5314 _(map_del_domain_reply)                                 \
5315 _(map_add_del_rule_reply)                               \
5316 _(want_interface_events_reply)                          \
5317 _(want_stats_reply)                                     \
5318 _(cop_interface_enable_disable_reply)                   \
5319 _(cop_whitelist_enable_disable_reply)                   \
5320 _(sw_interface_clear_stats_reply)                       \
5321 _(ioam_enable_reply)                                    \
5322 _(ioam_disable_reply)                                   \
5323 _(one_add_del_locator_reply)                            \
5324 _(one_add_del_local_eid_reply)                          \
5325 _(one_add_del_remote_mapping_reply)                     \
5326 _(one_add_del_adjacency_reply)                          \
5327 _(one_add_del_map_resolver_reply)                       \
5328 _(one_add_del_map_server_reply)                         \
5329 _(one_enable_disable_reply)                             \
5330 _(one_rloc_probe_enable_disable_reply)                  \
5331 _(one_map_register_enable_disable_reply)                \
5332 _(one_map_register_set_ttl_reply)                       \
5333 _(one_set_transport_protocol_reply)                     \
5334 _(one_map_register_fallback_threshold_reply)            \
5335 _(one_pitr_set_locator_set_reply)                       \
5336 _(one_map_request_mode_reply)                           \
5337 _(one_add_del_map_request_itr_rlocs_reply)              \
5338 _(one_eid_table_add_del_map_reply)                      \
5339 _(one_use_petr_reply)                                   \
5340 _(one_stats_enable_disable_reply)                       \
5341 _(one_add_del_l2_arp_entry_reply)                       \
5342 _(one_add_del_ndp_entry_reply)                          \
5343 _(one_stats_flush_reply)                                \
5344 _(one_enable_disable_xtr_mode_reply)                    \
5345 _(one_enable_disable_pitr_mode_reply)                   \
5346 _(one_enable_disable_petr_mode_reply)                   \
5347 _(gpe_enable_disable_reply)                             \
5348 _(gpe_set_encap_mode_reply)                             \
5349 _(gpe_add_del_iface_reply)                              \
5350 _(gpe_add_del_native_fwd_rpath_reply)                   \
5351 _(af_packet_delete_reply)                               \
5352 _(policer_classify_set_interface_reply)                 \
5353 _(netmap_create_reply)                                  \
5354 _(netmap_delete_reply)                                  \
5355 _(set_ipfix_exporter_reply)                             \
5356 _(set_ipfix_classify_stream_reply)                      \
5357 _(ipfix_classify_table_add_del_reply)                   \
5358 _(flow_classify_set_interface_reply)                    \
5359 _(sw_interface_span_enable_disable_reply)               \
5360 _(pg_capture_reply)                                     \
5361 _(pg_enable_disable_reply)                              \
5362 _(ip_source_and_port_range_check_add_del_reply)         \
5363 _(ip_source_and_port_range_check_interface_add_del_reply)\
5364 _(delete_subif_reply)                                   \
5365 _(l2_interface_pbb_tag_rewrite_reply)                   \
5366 _(punt_reply)                                           \
5367 _(feature_enable_disable_reply)                         \
5368 _(sw_interface_tag_add_del_reply)                       \
5369 _(sw_interface_set_mtu_reply)                           \
5370 _(p2p_ethernet_add_reply)                               \
5371 _(p2p_ethernet_del_reply)                               \
5372 _(lldp_config_reply)                                    \
5373 _(sw_interface_set_lldp_reply)                          \
5374 _(tcp_configure_src_addresses_reply)                    \
5375 _(dns_enable_disable_reply)                             \
5376 _(dns_name_server_add_del_reply)                        \
5377 _(session_rule_add_del_reply)                           \
5378 _(ip_container_proxy_add_del_reply)
5379
5380 #define _(n)                                    \
5381     static void vl_api_##n##_t_handler          \
5382     (vl_api_##n##_t * mp)                       \
5383     {                                           \
5384         vat_main_t * vam = &vat_main;           \
5385         i32 retval = ntohl(mp->retval);         \
5386         if (vam->async_mode) {                  \
5387             vam->async_errors += (retval < 0);  \
5388         } else {                                \
5389             vam->retval = retval;               \
5390             vam->result_ready = 1;              \
5391         }                                       \
5392     }
5393 foreach_standard_reply_retval_handler;
5394 #undef _
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler_json     \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         vat_json_node_t node;                   \
5402         vat_json_init_object(&node);            \
5403         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5404         vat_json_print(vam->ofp, &node);        \
5405         vam->retval = ntohl(mp->retval);        \
5406         vam->result_ready = 1;                  \
5407     }
5408 foreach_standard_reply_retval_handler;
5409 #undef _
5410
5411 /*
5412  * Table of message reply handlers, must include boilerplate handlers
5413  * we just generated
5414  */
5415
5416 #define foreach_vpe_api_reply_msg                                       \
5417 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5418 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5419 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5420 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5421 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5422 _(CLI_REPLY, cli_reply)                                                 \
5423 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5424 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5425   sw_interface_add_del_address_reply)                                   \
5426 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5427 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5428 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5429 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5430 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5431 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5432 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5433 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5434   sw_interface_set_l2_xconnect_reply)                                   \
5435 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5436   sw_interface_set_l2_bridge_reply)                                     \
5437 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5438 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5439 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5440 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5441 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5442 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5443 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5444 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5445 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5446 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5447 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5448 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5449 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5450 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5451 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5453 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5454 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5455 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5456 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5457 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5458 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5459 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5460 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5461 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5462   proxy_arp_intfc_enable_disable_reply)                                 \
5463 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5465   sw_interface_set_unnumbered_reply)                                    \
5466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5472 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5473 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5477   sw_interface_ip6_enable_disable_reply)                                \
5478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5479   sw_interface_ip6_set_link_local_address_reply)                        \
5480 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5481 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5483   sw_interface_ip6nd_ra_prefix_reply)                                   \
5484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5485   sw_interface_ip6nd_ra_config_reply)                                   \
5486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5488 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5489 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5490 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5491 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5492 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5493 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5494 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5495 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5496 classify_set_interface_ip_table_reply)                                  \
5497 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5498   classify_set_interface_l2_tables_reply)                               \
5499 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5500 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5501 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5502 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5503 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5504   l2tpv3_interface_enable_disable_reply)                                \
5505 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5506 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5507 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5508 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5509 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5510 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5511 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5512 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5513 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5514 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5515 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5516 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5517 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5518 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5519 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5520 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5521 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5522 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5523 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5524 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5525 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5526 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5527 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5528 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5529 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5530 _(L2_MACS_EVENT, l2_macs_event)                                         \
5531 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5532 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5533 _(IP_DETAILS, ip_details)                                               \
5534 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5535 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5536 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5537 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5538 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5539 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5540 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5541 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5542 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5543 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5544 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5545 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5546 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5547 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5548 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5549 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5550 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5551 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5552 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5553 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5554 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5555 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5556 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5557 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5558 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5571 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5572 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5573 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5574 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5575 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5576 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5577 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5578 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5579 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5580 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5581 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5582   one_map_register_enable_disable_reply)                                \
5583 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5584 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5585 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5586 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5587   one_map_register_fallback_threshold_reply)                            \
5588 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5589   one_rloc_probe_enable_disable_reply)                                  \
5590 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5591 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5592 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5593 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5594 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5595 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5596 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5597 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5598 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5599 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5600 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5601 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5602 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5603 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5604 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5605 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5606   show_one_stats_enable_disable_reply)                                  \
5607 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5608 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5609 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5610 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5611 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5612 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5613 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5614 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5615   one_enable_disable_pitr_mode_reply)                                   \
5616 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5617   one_enable_disable_petr_mode_reply)                                   \
5618 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5619 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5620 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5621 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5622 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5623 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5624 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5625 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5626 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5627 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5628 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5629 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5630   gpe_add_del_native_fwd_rpath_reply)                                   \
5631 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5632   gpe_fwd_entry_path_details)                                           \
5633 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5634 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5635   one_add_del_map_request_itr_rlocs_reply)                              \
5636 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5637   one_get_map_request_itr_rlocs_reply)                                  \
5638 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5639 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5640 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5641 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5642 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5643 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5644   show_one_map_register_state_reply)                                    \
5645 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5646 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5647   show_one_map_register_fallback_threshold_reply)                       \
5648 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5649 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5650 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5651 _(POLICER_DETAILS, policer_details)                                     \
5652 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5653 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5654 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5655 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5656 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5657 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5658 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5659 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5660 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5661 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5662 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5663 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5664 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5665 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5666 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5667 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5668 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5669 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5670 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5671 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5672 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5673 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5674 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5675 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5676 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5677  ip_source_and_port_range_check_add_del_reply)                          \
5678 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5679  ip_source_and_port_range_check_interface_add_del_reply)                \
5680 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5681 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5682 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5683 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5684 _(PUNT_REPLY, punt_reply)                                               \
5685 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5686 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5687 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5688 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5689 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5690 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5691 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5692 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5693 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5694 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5695 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5696 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5697 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5698 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5699 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5700 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5701 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5702 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5703 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5704 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5705 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5706
5707 #define foreach_standalone_reply_msg                                    \
5708 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5709 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5710 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5713 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5714 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5715 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5716
5717 typedef struct
5718 {
5719   u8 *name;
5720   u32 value;
5721 } name_sort_t;
5722
5723
5724 #define STR_VTR_OP_CASE(op)     \
5725     case L2_VTR_ ## op:         \
5726         return "" # op;
5727
5728 static const char *
5729 str_vtr_op (u32 vtr_op)
5730 {
5731   switch (vtr_op)
5732     {
5733       STR_VTR_OP_CASE (DISABLED);
5734       STR_VTR_OP_CASE (PUSH_1);
5735       STR_VTR_OP_CASE (PUSH_2);
5736       STR_VTR_OP_CASE (POP_1);
5737       STR_VTR_OP_CASE (POP_2);
5738       STR_VTR_OP_CASE (TRANSLATE_1_1);
5739       STR_VTR_OP_CASE (TRANSLATE_1_2);
5740       STR_VTR_OP_CASE (TRANSLATE_2_1);
5741       STR_VTR_OP_CASE (TRANSLATE_2_2);
5742     }
5743
5744   return "UNKNOWN";
5745 }
5746
5747 static int
5748 dump_sub_interface_table (vat_main_t * vam)
5749 {
5750   const sw_interface_subif_t *sub = NULL;
5751
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   print (vam->ofp,
5760          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5761          "Interface", "sw_if_index",
5762          "sub id", "dot1ad", "tags", "outer id",
5763          "inner id", "exact", "default", "outer any", "inner any");
5764
5765   vec_foreach (sub, vam->sw_if_subif_table)
5766   {
5767     print (vam->ofp,
5768            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5769            sub->interface_name,
5770            sub->sw_if_index,
5771            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5772            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5773            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5774            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5775     if (sub->vtr_op != L2_VTR_DISABLED)
5776       {
5777         print (vam->ofp,
5778                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5779                "tag1: %d tag2: %d ]",
5780                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5781                sub->vtr_tag1, sub->vtr_tag2);
5782       }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 name_sort_cmp (void *a1, void *a2)
5790 {
5791   name_sort_t *n1 = a1;
5792   name_sort_t *n2 = a2;
5793
5794   return strcmp ((char *) n1->name, (char *) n2->name);
5795 }
5796
5797 static int
5798 dump_interface_table (vat_main_t * vam)
5799 {
5800   hash_pair_t *p;
5801   name_sort_t *nses = 0, *ns;
5802
5803   if (vam->json_output)
5804     {
5805       clib_warning
5806         ("JSON output supported only for VPE API calls and dump_stats_table");
5807       return -99;
5808     }
5809
5810   /* *INDENT-OFF* */
5811   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5812   ({
5813     vec_add2 (nses, ns, 1);
5814     ns->name = (u8 *)(p->key);
5815     ns->value = (u32) p->value[0];
5816   }));
5817   /* *INDENT-ON* */
5818
5819   vec_sort_with_function (nses, name_sort_cmp);
5820
5821   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5822   vec_foreach (ns, nses)
5823   {
5824     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5825   }
5826   vec_free (nses);
5827   return 0;
5828 }
5829
5830 static int
5831 dump_ip_table (vat_main_t * vam, int is_ipv6)
5832 {
5833   const ip_details_t *det = NULL;
5834   const ip_address_details_t *address = NULL;
5835   u32 i = ~0;
5836
5837   print (vam->ofp, "%-12s", "sw_if_index");
5838
5839   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5840   {
5841     i++;
5842     if (!det->present)
5843       {
5844         continue;
5845       }
5846     print (vam->ofp, "%-12d", i);
5847     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5848     if (!det->addr)
5849       {
5850         continue;
5851       }
5852     vec_foreach (address, det->addr)
5853     {
5854       print (vam->ofp,
5855              "            %-30U%-13d",
5856              is_ipv6 ? format_ip6_address : format_ip4_address,
5857              address->ip, address->prefix_length);
5858     }
5859   }
5860
5861   return 0;
5862 }
5863
5864 static int
5865 dump_ipv4_table (vat_main_t * vam)
5866 {
5867   if (vam->json_output)
5868     {
5869       clib_warning
5870         ("JSON output supported only for VPE API calls and dump_stats_table");
5871       return -99;
5872     }
5873
5874   return dump_ip_table (vam, 0);
5875 }
5876
5877 static int
5878 dump_ipv6_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 1);
5888 }
5889
5890 static char *
5891 counter_type_to_str (u8 counter_type, u8 is_combined)
5892 {
5893   if (!is_combined)
5894     {
5895       switch (counter_type)
5896         {
5897         case VNET_INTERFACE_COUNTER_DROP:
5898           return "drop";
5899         case VNET_INTERFACE_COUNTER_PUNT:
5900           return "punt";
5901         case VNET_INTERFACE_COUNTER_IP4:
5902           return "ip4";
5903         case VNET_INTERFACE_COUNTER_IP6:
5904           return "ip6";
5905         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5906           return "rx-no-buf";
5907         case VNET_INTERFACE_COUNTER_RX_MISS:
5908           return "rx-miss";
5909         case VNET_INTERFACE_COUNTER_RX_ERROR:
5910           return "rx-error";
5911         case VNET_INTERFACE_COUNTER_TX_ERROR:
5912           return "tx-error";
5913         default:
5914           return "INVALID-COUNTER-TYPE";
5915         }
5916     }
5917   else
5918     {
5919       switch (counter_type)
5920         {
5921         case VNET_INTERFACE_COUNTER_RX:
5922           return "rx";
5923         case VNET_INTERFACE_COUNTER_TX:
5924           return "tx";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929 }
5930
5931 static int
5932 dump_stats_table (vat_main_t * vam)
5933 {
5934   vat_json_node_t node;
5935   vat_json_node_t *msg_array;
5936   vat_json_node_t *msg;
5937   vat_json_node_t *counter_array;
5938   vat_json_node_t *counter;
5939   interface_counter_t c;
5940   u64 packets;
5941   ip4_fib_counter_t *c4;
5942   ip6_fib_counter_t *c6;
5943   ip4_nbr_counter_t *n4;
5944   ip6_nbr_counter_t *n6;
5945   int i, j;
5946
5947   if (!vam->json_output)
5948     {
5949       clib_warning ("dump_stats_table supported only in JSON format");
5950       return -99;
5951     }
5952
5953   vat_json_init_object (&node);
5954
5955   /* interface counters */
5956   msg_array = vat_json_object_add (&node, "interface_counters");
5957   vat_json_init_array (msg_array);
5958   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5959     {
5960       msg = vat_json_array_add (msg_array);
5961       vat_json_init_object (msg);
5962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5963                                        (u8 *) counter_type_to_str (i, 0));
5964       vat_json_object_add_int (msg, "is_combined", 0);
5965       counter_array = vat_json_object_add (msg, "data");
5966       vat_json_init_array (counter_array);
5967       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5968         {
5969           packets = vam->simple_interface_counters[i][j];
5970           vat_json_array_add_uint (counter_array, packets);
5971         }
5972     }
5973   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5978                                        (u8 *) counter_type_to_str (i, 1));
5979       vat_json_object_add_int (msg, "is_combined", 1);
5980       counter_array = vat_json_object_add (msg, "data");
5981       vat_json_init_array (counter_array);
5982       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5983         {
5984           c = vam->combined_interface_counters[i][j];
5985           counter = vat_json_array_add (counter_array);
5986           vat_json_init_object (counter);
5987           vat_json_object_add_uint (counter, "packets", c.packets);
5988           vat_json_object_add_uint (counter, "bytes", c.bytes);
5989         }
5990     }
5991
5992   /* ip4 fib counters */
5993   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "vrf_id",
6000                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           c4 = &vam->ip4_fib_counters[i][j];
6008           vat_json_object_add_ip4 (counter, "address", c4->address);
6009           vat_json_object_add_uint (counter, "address_length",
6010                                     c4->address_length);
6011           vat_json_object_add_uint (counter, "packets", c4->packets);
6012           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6013         }
6014     }
6015
6016   /* ip6 fib counters */
6017   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6018   vat_json_init_array (msg_array);
6019   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6020     {
6021       msg = vat_json_array_add (msg_array);
6022       vat_json_init_object (msg);
6023       vat_json_object_add_uint (msg, "vrf_id",
6024                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6025       counter_array = vat_json_object_add (msg, "c");
6026       vat_json_init_array (counter_array);
6027       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6028         {
6029           counter = vat_json_array_add (counter_array);
6030           vat_json_init_object (counter);
6031           c6 = &vam->ip6_fib_counters[i][j];
6032           vat_json_object_add_ip6 (counter, "address", c6->address);
6033           vat_json_object_add_uint (counter, "address_length",
6034                                     c6->address_length);
6035           vat_json_object_add_uint (counter, "packets", c6->packets);
6036           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6037         }
6038     }
6039
6040   /* ip4 nbr counters */
6041   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6042   vat_json_init_array (msg_array);
6043   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6044     {
6045       msg = vat_json_array_add (msg_array);
6046       vat_json_init_object (msg);
6047       vat_json_object_add_uint (msg, "sw_if_index", i);
6048       counter_array = vat_json_object_add (msg, "c");
6049       vat_json_init_array (counter_array);
6050       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6051         {
6052           counter = vat_json_array_add (counter_array);
6053           vat_json_init_object (counter);
6054           n4 = &vam->ip4_nbr_counters[i][j];
6055           vat_json_object_add_ip4 (counter, "address", n4->address);
6056           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6057           vat_json_object_add_uint (counter, "packets", n4->packets);
6058           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6059         }
6060     }
6061
6062   /* ip6 nbr counters */
6063   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6064   vat_json_init_array (msg_array);
6065   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6066     {
6067       msg = vat_json_array_add (msg_array);
6068       vat_json_init_object (msg);
6069       vat_json_object_add_uint (msg, "sw_if_index", i);
6070       counter_array = vat_json_object_add (msg, "c");
6071       vat_json_init_array (counter_array);
6072       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6073         {
6074           counter = vat_json_array_add (counter_array);
6075           vat_json_init_object (counter);
6076           n6 = &vam->ip6_nbr_counters[i][j];
6077           vat_json_object_add_ip6 (counter, "address", n6->address);
6078           vat_json_object_add_uint (counter, "packets", n6->packets);
6079           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6080         }
6081     }
6082
6083   vat_json_print (vam->ofp, &node);
6084   vat_json_free (&node);
6085
6086   return 0;
6087 }
6088
6089 /*
6090  * Pass CLI buffers directly in the CLI_INBAND API message,
6091  * instead of an additional shared memory area.
6092  */
6093 static int
6094 exec_inband (vat_main_t * vam)
6095 {
6096   vl_api_cli_inband_t *mp;
6097   unformat_input_t *i = vam->input;
6098   int ret;
6099
6100   if (vec_len (i->buffer) == 0)
6101     return -1;
6102
6103   if (vam->exec_mode == 0 && unformat (i, "mode"))
6104     {
6105       vam->exec_mode = 1;
6106       return 0;
6107     }
6108   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6109     {
6110       vam->exec_mode = 0;
6111       return 0;
6112     }
6113
6114   /*
6115    * In order for the CLI command to work, it
6116    * must be a vector ending in \n, not a C-string ending
6117    * in \n\0.
6118    */
6119   u32 len = vec_len (vam->input->buffer);
6120   M2 (CLI_INBAND, mp, len);
6121   clib_memcpy (mp->cmd, vam->input->buffer, len);
6122   mp->length = htonl (len);
6123
6124   S (mp);
6125   W (ret);
6126   /* json responses may or may not include a useful reply... */
6127   if (vec_len (vam->cmd_reply))
6128     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6129   return ret;
6130 }
6131
6132 int
6133 exec (vat_main_t * vam)
6134 {
6135   return exec_inband (vam);
6136 }
6137
6138 static int
6139 api_create_loopback (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_create_loopback_t *mp;
6143   vl_api_create_loopback_instance_t *mp_lbi;
6144   u8 mac_address[6];
6145   u8 mac_set = 0;
6146   u8 is_specified = 0;
6147   u32 user_instance = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6155         mac_set = 1;
6156       if (unformat (i, "instance %d", &user_instance))
6157         is_specified = 1;
6158       else
6159         break;
6160     }
6161
6162   if (is_specified)
6163     {
6164       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6165       mp_lbi->is_specified = is_specified;
6166       if (is_specified)
6167         mp_lbi->user_instance = htonl (user_instance);
6168       if (mac_set)
6169         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6170       S (mp_lbi);
6171     }
6172   else
6173     {
6174       /* Construct the API message */
6175       M (CREATE_LOOPBACK, mp);
6176       if (mac_set)
6177         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6178       S (mp);
6179     }
6180
6181   W (ret);
6182   return ret;
6183 }
6184
6185 static int
6186 api_delete_loopback (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_delete_loopback_t *mp;
6190   u32 sw_if_index = ~0;
6191   int ret;
6192
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         ;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index == ~0)
6202     {
6203       errmsg ("missing sw_if_index");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (DELETE_LOOPBACK, mp);
6209   mp->sw_if_index = ntohl (sw_if_index);
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_want_stats (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_want_stats_t *mp;
6221   int enable = -1;
6222   int ret;
6223
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (enable == -1)
6235     {
6236       errmsg ("missing enable|disable");
6237       return -99;
6238     }
6239
6240   M (WANT_STATS, mp);
6241   mp->enable_disable = enable;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_want_interface_events (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_want_interface_events_t *mp;
6253   int enable = -1;
6254   int ret;
6255
6256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6257     {
6258       if (unformat (i, "enable"))
6259         enable = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (enable == -1)
6267     {
6268       errmsg ("missing enable|disable");
6269       return -99;
6270     }
6271
6272   M (WANT_INTERFACE_EVENTS, mp);
6273   mp->enable_disable = enable;
6274
6275   vam->interface_event_display = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282
6283 /* Note: non-static, called once to set up the initial intfc table */
6284 int
6285 api_sw_interface_dump (vat_main_t * vam)
6286 {
6287   vl_api_sw_interface_dump_t *mp;
6288   vl_api_control_ping_t *mp_ping;
6289   hash_pair_t *p;
6290   name_sort_t *nses = 0, *ns;
6291   sw_interface_subif_t *sub = NULL;
6292   int ret;
6293
6294   /* Toss the old name table */
6295   /* *INDENT-OFF* */
6296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6297   ({
6298     vec_add2 (nses, ns, 1);
6299     ns->name = (u8 *)(p->key);
6300     ns->value = (u32) p->value[0];
6301   }));
6302   /* *INDENT-ON* */
6303
6304   hash_free (vam->sw_if_index_by_interface_name);
6305
6306   vec_foreach (ns, nses) vec_free (ns->name);
6307
6308   vec_free (nses);
6309
6310   vec_foreach (sub, vam->sw_if_subif_table)
6311   {
6312     vec_free (sub->interface_name);
6313   }
6314   vec_free (vam->sw_if_subif_table);
6315
6316   /* recreate the interface name hash table */
6317   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6318
6319   /* Get list of ethernets */
6320   M (SW_INTERFACE_DUMP, mp);
6321   mp->name_filter_valid = 1;
6322   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6323   S (mp);
6324
6325   /* and local / loopback interfaces */
6326   M (SW_INTERFACE_DUMP, mp);
6327   mp->name_filter_valid = 1;
6328   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6329   S (mp);
6330
6331   /* and packet-generator interfaces */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and vxlan-gpe tunnel interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6341            sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and vxlan tunnel interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and geneve tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and host (af_packet) interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and l2tpv3 tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6366            sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and GRE tunnel interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and LISP-GPE interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "lisp_gpe",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and IPSEC tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* Use a control ping for synchronization */
6389   MPING (CONTROL_PING, mp_ping);
6390   S (mp_ping);
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_flags (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_flags_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   u8 admin_up = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "admin-up"))
6410         admin_up = 1;
6411       else if (unformat (i, "admin-down"))
6412         admin_up = 0;
6413       else
6414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         sw_if_index_set = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_FLAGS, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->admin_up_down = admin_up;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply, return the good/bad news... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_rx_mode (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_rx_mode_t *mp;
6446   u32 sw_if_index;
6447   u8 sw_if_index_set = 0;
6448   int ret;
6449   u8 queue_id_valid = 0;
6450   u32 queue_id;
6451   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "queue %d", &queue_id))
6457         queue_id_valid = 1;
6458       else if (unformat (i, "polling"))
6459         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6460       else if (unformat (i, "interrupt"))
6461         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6462       else if (unformat (i, "adaptive"))
6463         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6464       else
6465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6479     {
6480       errmsg ("missing rx-mode");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (SW_INTERFACE_SET_RX_MODE, mp);
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->mode = mode;
6488   mp->queue_id_valid = queue_id_valid;
6489   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6490
6491   /* send it... */
6492   S (mp);
6493
6494   /* Wait for a reply, return the good/bad news... */
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_clear_stats (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_clear_stats_t *mp;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else
6516         break;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_CLEAR_STATS, mp);
6521
6522   if (sw_if_index_set == 1)
6523     mp->sw_if_index = ntohl (sw_if_index);
6524   else
6525     mp->sw_if_index = ~0;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply, return the good/bad news... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_add_del_address (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_add_del_address_t *mp;
6540   u32 sw_if_index;
6541   u8 sw_if_index_set = 0;
6542   u8 is_add = 1, del_all = 0;
6543   u32 address_length = 0;
6544   u8 v4_address_set = 0;
6545   u8 v6_address_set = 0;
6546   ip4_address_t v4address;
6547   ip6_address_t v6address;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "del-all"))
6554         del_all = 1;
6555       else if (unformat (i, "del"))
6556         is_add = 0;
6557       else
6558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "%U/%d",
6563                          unformat_ip4_address, &v4address, &address_length))
6564         v4_address_set = 1;
6565       else if (unformat (i, "%U/%d",
6566                          unformat_ip6_address, &v6address, &address_length))
6567         v6_address_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577   if (v4_address_set && v6_address_set)
6578     {
6579       errmsg ("both v4 and v6 addresses set");
6580       return -99;
6581     }
6582   if (!v4_address_set && !v6_address_set && !del_all)
6583     {
6584       errmsg ("no addresses set");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6590
6591   mp->sw_if_index = ntohl (sw_if_index);
6592   mp->is_add = is_add;
6593   mp->del_all = del_all;
6594   if (v6_address_set)
6595     {
6596       mp->is_ipv6 = 1;
6597       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6598     }
6599   else
6600     {
6601       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6602     }
6603   mp->address_length = address_length;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return good/bad news  */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_mpls_enable_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "disable"))
6631         enable = 0;
6632       else if (unformat (i, "dis"))
6633         enable = 0;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->enable = enable;
6649
6650   /* send it... */
6651   S (mp);
6652
6653   /* Wait for a reply... */
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_sw_interface_set_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_set_table_t *mp;
6663   u32 sw_if_index, vrf_id = 0;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "vrf %d", &vrf_id))
6676         ;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   /* Construct the API message */
6690   M (SW_INTERFACE_SET_TABLE, mp);
6691
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694   mp->vrf_id = ntohl (vrf_id);
6695
6696   /* send it... */
6697   S (mp);
6698
6699   /* Wait for a reply... */
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static void vl_api_sw_interface_get_table_reply_t_handler
6705   (vl_api_sw_interface_get_table_reply_t * mp)
6706 {
6707   vat_main_t *vam = &vat_main;
6708
6709   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6710
6711   vam->retval = ntohl (mp->retval);
6712   vam->result_ready = 1;
6713
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler_json
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t node;
6721
6722   vat_json_init_object (&node);
6723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6724   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6725
6726   vat_json_print (vam->ofp, &node);
6727   vat_json_free (&node);
6728
6729   vam->retval = ntohl (mp->retval);
6730   vam->result_ready = 1;
6731 }
6732
6733 static int
6734 api_sw_interface_get_table (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_get_table_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 is_ipv6 = 0;
6741   int ret;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "ipv6"))
6750         is_ipv6 = 1;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   M (SW_INTERFACE_GET_TABLE, mp);
6762   mp->sw_if_index = htonl (sw_if_index);
6763   mp->is_ipv6 = is_ipv6;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vpath (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vpath_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "enable"))
6788         is_enable = 1;
6789       else if (unformat (i, "disable"))
6790         is_enable = 0;
6791       else
6792         break;
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (SW_INTERFACE_SET_VPATH, mp);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->enable = is_enable;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply... */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6820   u32 sw_if_index = 0;
6821   u8 sw_if_index_set = 0;
6822   u8 is_enable = 1;
6823   u8 is_ipv6 = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "enable"))
6834         is_enable = 1;
6835       else if (unformat (i, "disable"))
6836         is_enable = 0;
6837       else if (unformat (i, "ip4"))
6838         is_ipv6 = 0;
6839       else if (unformat (i, "ip6"))
6840         is_ipv6 = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855   mp->enable = is_enable;
6856   mp->is_ipv6 = is_ipv6;
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863   return ret;
6864 }
6865
6866 static int
6867 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_geneve_bypass_t *mp;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_enable = 1;
6874   u8 is_ipv6 = 0;
6875   int ret;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "enable"))
6885         is_enable = 1;
6886       else if (unformat (i, "disable"))
6887         is_enable = 0;
6888       else if (unformat (i, "ip4"))
6889         is_ipv6 = 0;
6890       else if (unformat (i, "ip6"))
6891         is_ipv6 = 1;
6892       else
6893         break;
6894     }
6895
6896   if (sw_if_index_set == 0)
6897     {
6898       errmsg ("missing interface name or sw_if_index");
6899       return -99;
6900     }
6901
6902   /* Construct the API message */
6903   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6904
6905   mp->sw_if_index = ntohl (sw_if_index);
6906   mp->enable = is_enable;
6907   mp->is_ipv6 = is_ipv6;
6908
6909   /* send it... */
6910   S (mp);
6911
6912   /* Wait for a reply... */
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_xconnect_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 tx_sw_if_index;
6925   u8 tx_sw_if_index_set = 0;
6926   u8 enable = 1;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6933         rx_sw_if_index_set = 1;
6934       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6935         tx_sw_if_index_set = 1;
6936       else if (unformat (i, "rx"))
6937         {
6938           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939             {
6940               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6941                             &rx_sw_if_index))
6942                 rx_sw_if_index_set = 1;
6943             }
6944           else
6945             break;
6946         }
6947       else if (unformat (i, "tx"))
6948         {
6949           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950             {
6951               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6952                             &tx_sw_if_index))
6953                 tx_sw_if_index_set = 1;
6954             }
6955           else
6956             break;
6957         }
6958       else if (unformat (i, "enable"))
6959         enable = 1;
6960       else if (unformat (i, "disable"))
6961         enable = 0;
6962       else
6963         break;
6964     }
6965
6966   if (rx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing rx interface name or rx_sw_if_index");
6969       return -99;
6970     }
6971
6972   if (enable && (tx_sw_if_index_set == 0))
6973     {
6974       errmsg ("missing tx interface name or tx_sw_if_index");
6975       return -99;
6976     }
6977
6978   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6979
6980   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6981   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6982   mp->enable = enable;
6983
6984   S (mp);
6985   W (ret);
6986   return ret;
6987 }
6988
6989 static int
6990 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_sw_interface_set_l2_bridge_t *mp;
6994   u32 rx_sw_if_index;
6995   u8 rx_sw_if_index_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u8 bvi = 0;
6999   u32 shg = 0;
7000   u8 enable = 1;
7001   int ret;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7007         rx_sw_if_index_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else
7011         if (unformat
7012             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7013         rx_sw_if_index_set = 1;
7014       else if (unformat (i, "shg %d", &shg))
7015         ;
7016       else if (unformat (i, "bvi"))
7017         bvi = 1;
7018       else if (unformat (i, "enable"))
7019         enable = 1;
7020       else if (unformat (i, "disable"))
7021         enable = 0;
7022       else
7023         break;
7024     }
7025
7026   if (rx_sw_if_index_set == 0)
7027     {
7028       errmsg ("missing rx interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   if (enable && (bd_id_set == 0))
7033     {
7034       errmsg ("missing bridge domain");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7039
7040   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7041   mp->bd_id = ntohl (bd_id);
7042   mp->shg = (u8) shg;
7043   mp->bvi = bvi;
7044   mp->enable = enable;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_bridge_domain_dump (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_bridge_domain_dump_t *mp;
7056   vl_api_control_ping_t *mp_ping;
7057   u32 bd_id = ~0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "bd_id %d", &bd_id))
7064         ;
7065       else
7066         break;
7067     }
7068
7069   M (BRIDGE_DOMAIN_DUMP, mp);
7070   mp->bd_id = ntohl (bd_id);
7071   S (mp);
7072
7073   /* Use a control ping for synchronization */
7074   MPING (CONTROL_PING, mp_ping);
7075   S (mp_ping);
7076
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_bridge_domain_add_del (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_bridge_domain_add_del_t *mp;
7086   u32 bd_id = ~0;
7087   u8 is_add = 1;
7088   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7089   u8 *bd_tag = NULL;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id))
7097         ;
7098       else if (unformat (i, "flood %d", &flood))
7099         ;
7100       else if (unformat (i, "uu-flood %d", &uu_flood))
7101         ;
7102       else if (unformat (i, "forward %d", &forward))
7103         ;
7104       else if (unformat (i, "learn %d", &learn))
7105         ;
7106       else if (unformat (i, "arp-term %d", &arp_term))
7107         ;
7108       else if (unformat (i, "mac-age %d", &mac_age))
7109         ;
7110       else if (unformat (i, "bd-tag %s", &bd_tag))
7111         ;
7112       else if (unformat (i, "del"))
7113         {
7114           is_add = 0;
7115           flood = uu_flood = forward = learn = 0;
7116         }
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       ret = -99;
7125       goto done;
7126     }
7127
7128   if (mac_age > 255)
7129     {
7130       errmsg ("mac age must be less than 256 ");
7131       ret = -99;
7132       goto done;
7133     }
7134
7135   if ((bd_tag) && (vec_len (bd_tag) > 63))
7136     {
7137       errmsg ("bd-tag cannot be longer than 63");
7138       ret = -99;
7139       goto done;
7140     }
7141
7142   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7143
7144   mp->bd_id = ntohl (bd_id);
7145   mp->flood = flood;
7146   mp->uu_flood = uu_flood;
7147   mp->forward = forward;
7148   mp->learn = learn;
7149   mp->arp_term = arp_term;
7150   mp->is_add = is_add;
7151   mp->mac_age = (u8) mac_age;
7152   if (bd_tag)
7153     {
7154       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7155       mp->bd_tag[vec_len (bd_tag)] = 0;
7156     }
7157   S (mp);
7158   W (ret);
7159
7160 done:
7161   vec_free (bd_tag);
7162   return ret;
7163 }
7164
7165 static int
7166 api_l2fib_flush_bd (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_l2fib_flush_bd_t *mp;
7170   u32 bd_id = ~0;
7171   int ret;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id));
7177       else
7178         break;
7179     }
7180
7181   if (bd_id == ~0)
7182     {
7183       errmsg ("missing bridge domain");
7184       return -99;
7185     }
7186
7187   M (L2FIB_FLUSH_BD, mp);
7188
7189   mp->bd_id = htonl (bd_id);
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_l2fib_flush_int (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_l2fib_flush_int_t *mp;
7201   u32 sw_if_index = ~0;
7202   int ret;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "sw_if_index %d", &sw_if_index));
7208       else
7209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7210       else
7211         break;
7212     }
7213
7214   if (sw_if_index == ~0)
7215     {
7216       errmsg ("missing interface name or sw_if_index");
7217       return -99;
7218     }
7219
7220   M (L2FIB_FLUSH_INT, mp);
7221
7222   mp->sw_if_index = ntohl (sw_if_index);
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_add_del (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_add_del_t *mp;
7234   f64 timeout;
7235   u8 mac[6] = { 0 };
7236   u8 mac_set = 0;
7237   u32 bd_id;
7238   u8 bd_id_set = 0;
7239   u32 sw_if_index = ~0;
7240   u8 sw_if_index_set = 0;
7241   u8 is_add = 1;
7242   u8 static_mac = 0;
7243   u8 filter_mac = 0;
7244   u8 bvi_mac = 0;
7245   int count = 1;
7246   f64 before = 0;
7247   int j;
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7253         mac_set = 1;
7254       else if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7257         sw_if_index_set = 1;
7258       else if (unformat (i, "sw_if"))
7259         {
7260           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261             {
7262               if (unformat
7263                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7264                 sw_if_index_set = 1;
7265             }
7266           else
7267             break;
7268         }
7269       else if (unformat (i, "static"))
7270         static_mac = 1;
7271       else if (unformat (i, "filter"))
7272         {
7273           filter_mac = 1;
7274           static_mac = 1;
7275         }
7276       else if (unformat (i, "bvi"))
7277         {
7278           bvi_mac = 1;
7279           static_mac = 1;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "count %d", &count))
7284         ;
7285       else
7286         break;
7287     }
7288
7289   if (mac_set == 0)
7290     {
7291       errmsg ("missing mac address");
7292       return -99;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7302     {
7303       errmsg ("missing interface name or sw_if_index");
7304       return -99;
7305     }
7306
7307   if (count > 1)
7308     {
7309       /* Turn on async mode */
7310       vam->async_mode = 1;
7311       vam->async_errors = 0;
7312       before = vat_time_now (vam);
7313     }
7314
7315   for (j = 0; j < count; j++)
7316     {
7317       M (L2FIB_ADD_DEL, mp);
7318
7319       clib_memcpy (mp->mac, mac, 6);
7320       mp->bd_id = ntohl (bd_id);
7321       mp->is_add = is_add;
7322
7323       if (is_add)
7324         {
7325           mp->sw_if_index = ntohl (sw_if_index);
7326           mp->static_mac = static_mac;
7327           mp->filter_mac = filter_mac;
7328           mp->bvi_mac = bvi_mac;
7329         }
7330       increment_mac_address (mac);
7331       /* send it... */
7332       S (mp);
7333     }
7334
7335   if (count > 1)
7336     {
7337       vl_api_control_ping_t *mp_ping;
7338       f64 after;
7339
7340       /* Shut off async mode */
7341       vam->async_mode = 0;
7342
7343       MPING (CONTROL_PING, mp_ping);
7344       S (mp_ping);
7345
7346       timeout = vat_time_now (vam) + 1.0;
7347       while (vat_time_now (vam) < timeout)
7348         if (vam->result_ready == 1)
7349           goto out;
7350       vam->retval = -99;
7351
7352     out:
7353       if (vam->retval == -99)
7354         errmsg ("timeout");
7355
7356       if (vam->async_errors > 0)
7357         {
7358           errmsg ("%d asynchronous errors", vam->async_errors);
7359           vam->retval = -98;
7360         }
7361       vam->async_errors = 0;
7362       after = vat_time_now (vam);
7363
7364       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7365              count, after - before, count / (after - before));
7366     }
7367   else
7368     {
7369       int ret;
7370
7371       /* Wait for a reply... */
7372       W (ret);
7373       return ret;
7374     }
7375   /* Return the good/bad news */
7376   return (vam->retval);
7377 }
7378
7379 static int
7380 api_bridge_domain_set_mac_age (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bridge_domain_set_mac_age_t *mp;
7384   u32 bd_id = ~0;
7385   u32 mac_age = 0;
7386   int ret;
7387
7388   /* Parse args required to build the message */
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id));
7392       else if (unformat (i, "mac-age %d", &mac_age));
7393       else
7394         break;
7395     }
7396
7397   if (bd_id == ~0)
7398     {
7399       errmsg ("missing bridge domain");
7400       return -99;
7401     }
7402
7403   if (mac_age > 255)
7404     {
7405       errmsg ("mac age must be less than 256 ");
7406       return -99;
7407     }
7408
7409   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7410
7411   mp->bd_id = htonl (bd_id);
7412   mp->mac_age = (u8) mac_age;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_l2_flags (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_l2_flags_t *mp;
7424   u32 sw_if_index;
7425   u32 flags = 0;
7426   u8 sw_if_index_set = 0;
7427   u8 is_set = 0;
7428   int ret;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "sw_if_index %d", &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if"))
7436         {
7437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438             {
7439               if (unformat
7440                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7441                 sw_if_index_set = 1;
7442             }
7443           else
7444             break;
7445         }
7446       else if (unformat (i, "learn"))
7447         flags |= L2_LEARN;
7448       else if (unformat (i, "forward"))
7449         flags |= L2_FWD;
7450       else if (unformat (i, "flood"))
7451         flags |= L2_FLOOD;
7452       else if (unformat (i, "uu-flood"))
7453         flags |= L2_UU_FLOOD;
7454       else if (unformat (i, "arp-term"))
7455         flags |= L2_ARP_TERM;
7456       else if (unformat (i, "off"))
7457         is_set = 0;
7458       else if (unformat (i, "disable"))
7459         is_set = 0;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing interface name or sw_if_index");
7467       return -99;
7468     }
7469
7470   M (L2_FLAGS, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473   mp->feature_bitmap = ntohl (flags);
7474   mp->is_set = is_set;
7475
7476   S (mp);
7477   W (ret);
7478   return ret;
7479 }
7480
7481 static int
7482 api_bridge_flags (vat_main_t * vam)
7483 {
7484   unformat_input_t *i = vam->input;
7485   vl_api_bridge_flags_t *mp;
7486   u32 bd_id;
7487   u8 bd_id_set = 0;
7488   u8 is_set = 1;
7489   u32 flags = 0;
7490   int ret;
7491
7492   /* Parse args required to build the message */
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "bd_id %d", &bd_id))
7496         bd_id_set = 1;
7497       else if (unformat (i, "learn"))
7498         flags |= L2_LEARN;
7499       else if (unformat (i, "forward"))
7500         flags |= L2_FWD;
7501       else if (unformat (i, "flood"))
7502         flags |= L2_FLOOD;
7503       else if (unformat (i, "uu-flood"))
7504         flags |= L2_UU_FLOOD;
7505       else if (unformat (i, "arp-term"))
7506         flags |= L2_ARP_TERM;
7507       else if (unformat (i, "off"))
7508         is_set = 0;
7509       else if (unformat (i, "disable"))
7510         is_set = 0;
7511       else
7512         break;
7513     }
7514
7515   if (bd_id_set == 0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   M (BRIDGE_FLAGS, mp);
7522
7523   mp->bd_id = ntohl (bd_id);
7524   mp->feature_bitmap = ntohl (flags);
7525   mp->is_set = is_set;
7526
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_bd_ip_mac_add_del (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_bd_ip_mac_add_del_t *mp;
7537   u32 bd_id;
7538   u8 is_ipv6 = 0;
7539   u8 is_add = 1;
7540   u8 bd_id_set = 0;
7541   u8 ip_set = 0;
7542   u8 mac_set = 0;
7543   ip4_address_t v4addr;
7544   ip6_address_t v6addr;
7545   u8 macaddr[6];
7546   int ret;
7547
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "bd_id %d", &bd_id))
7553         {
7554           bd_id_set++;
7555         }
7556       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7557         {
7558           ip_set++;
7559         }
7560       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7561         {
7562           ip_set++;
7563           is_ipv6++;
7564         }
7565       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7566         {
7567           mac_set++;
7568         }
7569       else if (unformat (i, "del"))
7570         is_add = 0;
7571       else
7572         break;
7573     }
7574
7575   if (bd_id_set == 0)
7576     {
7577       errmsg ("missing bridge domain");
7578       return -99;
7579     }
7580   else if (ip_set == 0)
7581     {
7582       errmsg ("missing IP address");
7583       return -99;
7584     }
7585   else if (mac_set == 0)
7586     {
7587       errmsg ("missing MAC address");
7588       return -99;
7589     }
7590
7591   M (BD_IP_MAC_ADD_DEL, mp);
7592
7593   mp->bd_id = ntohl (bd_id);
7594   mp->is_ipv6 = is_ipv6;
7595   mp->is_add = is_add;
7596   if (is_ipv6)
7597     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7598   else
7599     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7600   clib_memcpy (mp->mac_address, macaddr, 6);
7601   S (mp);
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_connect (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_connect_t *mp;
7611   u8 mac_address[6];
7612   u8 random_mac = 1;
7613   u8 name_set = 0;
7614   u8 *tap_name;
7615   u8 *tag = 0;
7616   ip4_address_t ip4_address;
7617   u32 ip4_mask_width;
7618   int ip4_address_set = 0;
7619   ip6_address_t ip6_address;
7620   u32 ip6_mask_width;
7621   int ip6_address_set = 0;
7622   int ret;
7623
7624   memset (mac_address, 0, sizeof (mac_address));
7625
7626   /* Parse args required to build the message */
7627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7630         {
7631           random_mac = 0;
7632         }
7633       else if (unformat (i, "random-mac"))
7634         random_mac = 1;
7635       else if (unformat (i, "tapname %s", &tap_name))
7636         name_set = 1;
7637       else if (unformat (i, "tag %s", &tag))
7638         ;
7639       else if (unformat (i, "address %U/%d",
7640                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7641         ip4_address_set = 1;
7642       else if (unformat (i, "address %U/%d",
7643                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7644         ip6_address_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (name_set == 0)
7650     {
7651       errmsg ("missing tap name");
7652       return -99;
7653     }
7654   if (vec_len (tap_name) > 63)
7655     {
7656       errmsg ("tap name too long");
7657       return -99;
7658     }
7659   vec_add1 (tap_name, 0);
7660
7661   if (vec_len (tag) > 63)
7662     {
7663       errmsg ("tag too long");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_CONNECT, mp);
7669
7670   mp->use_random_mac = random_mac;
7671   clib_memcpy (mp->mac_address, mac_address, 6);
7672   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7673   if (tag)
7674     clib_memcpy (mp->tag, tag, vec_len (tag));
7675
7676   if (ip4_address_set)
7677     {
7678       mp->ip4_address_set = 1;
7679       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7680       mp->ip4_mask_width = ip4_mask_width;
7681     }
7682   if (ip6_address_set)
7683     {
7684       mp->ip6_address_set = 1;
7685       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7686       mp->ip6_mask_width = ip6_mask_width;
7687     }
7688
7689   vec_free (tap_name);
7690   vec_free (tag);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_tap_modify (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_tap_modify_t *mp;
7705   u8 mac_address[6];
7706   u8 random_mac = 1;
7707   u8 name_set = 0;
7708   u8 *tap_name;
7709   u32 sw_if_index = ~0;
7710   u8 sw_if_index_set = 0;
7711   int ret;
7712
7713   memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7723         {
7724           random_mac = 0;
7725         }
7726       else if (unformat (i, "random-mac"))
7727         random_mac = 1;
7728       else if (unformat (i, "tapname %s", &tap_name))
7729         name_set = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing vpp interface name");
7737       return -99;
7738     }
7739   if (name_set == 0)
7740     {
7741       errmsg ("missing tap name");
7742       return -99;
7743     }
7744   if (vec_len (tap_name) > 63)
7745     {
7746       errmsg ("tap name too long");
7747     }
7748   vec_add1 (tap_name, 0);
7749
7750   /* Construct the API message */
7751   M (TAP_MODIFY, mp);
7752
7753   mp->use_random_mac = random_mac;
7754   mp->sw_if_index = ntohl (sw_if_index);
7755   clib_memcpy (mp->mac_address, mac_address, 6);
7756   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7757   vec_free (tap_name);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_tap_delete (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_tap_delete_t *mp;
7772   u32 sw_if_index = ~0;
7773   u8 sw_if_index_set = 0;
7774   int ret;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing vpp interface name");
7790       return -99;
7791     }
7792
7793   /* Construct the API message */
7794   M (TAP_DELETE, mp);
7795
7796   mp->sw_if_index = ntohl (sw_if_index);
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply... */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 static int
7807 api_tap_create_v2 (vat_main_t * vam)
7808 {
7809   unformat_input_t *i = vam->input;
7810   vl_api_tap_create_v2_t *mp;
7811   u8 mac_address[6];
7812   u8 random_mac = 1;
7813   u8 *tap_name = 0;
7814   u8 *host_namespace = 0;
7815   u8 *host_bridge = 0;
7816   ip4_address_t host_ip4_addr;
7817   u32 host_ip4_prefix_len = 0;
7818   ip6_address_t host_ip6_addr;
7819   u32 host_ip6_prefix_len = 0;
7820   int ret;
7821   int rx_ring_sz = 0, tx_ring_sz = 0;
7822
7823   memset (mac_address, 0, sizeof (mac_address));
7824
7825   /* Parse args required to build the message */
7826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7827     {
7828       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7829         {
7830           random_mac = 0;
7831         }
7832       else if (unformat (i, "name %s", &tap_name))
7833         ;
7834       else if (unformat (i, "host-ns %s", &host_namespace))
7835         ;
7836       else if (unformat (i, "host-bridge %s", &host_bridge))
7837         ;
7838       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7839                          &host_ip4_addr, &host_ip4_prefix_len))
7840         ;
7841       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7842                          &host_ip6_addr, &host_ip6_prefix_len))
7843         ;
7844       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7845         ;
7846       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7847         ;
7848       else
7849         break;
7850     }
7851
7852   if (tap_name == 0)
7853     {
7854       errmsg ("missing tap name. ");
7855       return -99;
7856     }
7857   if (vec_len (tap_name) > 63)
7858     {
7859       errmsg ("tap name too long. ");
7860       return -99;
7861     }
7862   if (vec_len (host_namespace) > 63)
7863     {
7864       errmsg ("host name space too long. ");
7865       return -99;
7866     }
7867   if (vec_len (host_bridge) > 63)
7868     {
7869       errmsg ("host bridge name too long. ");
7870       return -99;
7871     }
7872   if (host_ip4_prefix_len > 32)
7873     {
7874       errmsg ("host ip4 prefix length not valid. ");
7875       return -99;
7876     }
7877   if (host_ip6_prefix_len > 128)
7878     {
7879       errmsg ("host ip6 prefix length not valid. ");
7880       return -99;
7881     }
7882   if (!is_pow2 (rx_ring_sz))
7883     {
7884       errmsg ("rx ring size must be power of 2. ");
7885       return -99;
7886     }
7887   if (rx_ring_sz > 32768)
7888     {
7889       errmsg ("rx ring size must be 32768 or lower. ");
7890       return -99;
7891     }
7892   if (!is_pow2 (tx_ring_sz))
7893     {
7894       errmsg ("tx ring size must be power of 2. ");
7895       return -99;
7896     }
7897   if (tx_ring_sz > 32768)
7898     {
7899       errmsg ("tx ring size must be 32768 or lower. ");
7900       return -99;
7901     }
7902
7903   vec_add1 (tap_name, 0);
7904
7905   /* Construct the API message */
7906   M (TAP_CREATE_V2, mp);
7907
7908   mp->use_random_mac = random_mac;
7909   clib_memcpy (mp->mac_address, mac_address, 6);
7910   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7911   mp->host_namespace_set = host_namespace != 0;
7912   mp->host_bridge_set = host_bridge != 0;
7913   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7914   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7915   mp->rx_ring_sz = rx_ring_sz;
7916   mp->tx_ring_sz = tx_ring_sz;
7917   if (host_namespace)
7918     clib_memcpy (mp->host_namespace, host_namespace,
7919                  vec_len (host_namespace));
7920   if (host_bridge)
7921     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7922   if (host_ip4_prefix_len)
7923     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7924   if (host_ip4_prefix_len)
7925     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7926
7927
7928   vec_free (tap_name);
7929
7930   /* send it... */
7931   S (mp);
7932
7933   /* Wait for a reply... */
7934   W (ret);
7935   return ret;
7936 }
7937
7938 static int
7939 api_tap_delete_v2 (vat_main_t * vam)
7940 {
7941   unformat_input_t *i = vam->input;
7942   vl_api_tap_delete_v2_t *mp;
7943   u32 sw_if_index = ~0;
7944   u8 sw_if_index_set = 0;
7945   int ret;
7946
7947   /* Parse args required to build the message */
7948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7949     {
7950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7951         sw_if_index_set = 1;
7952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7953         sw_if_index_set = 1;
7954       else
7955         break;
7956     }
7957
7958   if (sw_if_index_set == 0)
7959     {
7960       errmsg ("missing vpp interface name. ");
7961       return -99;
7962     }
7963
7964   /* Construct the API message */
7965   M (TAP_DELETE_V2, mp);
7966
7967   mp->sw_if_index = ntohl (sw_if_index);
7968
7969   /* send it... */
7970   S (mp);
7971
7972   /* Wait for a reply... */
7973   W (ret);
7974   return ret;
7975 }
7976
7977 static int
7978 api_ip_table_add_del (vat_main_t * vam)
7979 {
7980   unformat_input_t *i = vam->input;
7981   vl_api_ip_table_add_del_t *mp;
7982   u32 table_id = ~0;
7983   u8 is_ipv6 = 0;
7984   u8 is_add = 1;
7985   int ret = 0;
7986
7987   /* Parse args required to build the message */
7988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7989     {
7990       if (unformat (i, "ipv6"))
7991         is_ipv6 = 1;
7992       else if (unformat (i, "del"))
7993         is_add = 0;
7994       else if (unformat (i, "add"))
7995         is_add = 1;
7996       else if (unformat (i, "table %d", &table_id))
7997         ;
7998       else
7999         {
8000           clib_warning ("parse error '%U'", format_unformat_error, i);
8001           return -99;
8002         }
8003     }
8004
8005   if (~0 == table_id)
8006     {
8007       errmsg ("missing table-ID");
8008       return -99;
8009     }
8010
8011   /* Construct the API message */
8012   M (IP_TABLE_ADD_DEL, mp);
8013
8014   mp->table_id = ntohl (table_id);
8015   mp->is_ipv6 = is_ipv6;
8016   mp->is_add = is_add;
8017
8018   /* send it... */
8019   S (mp);
8020
8021   /* Wait for a reply... */
8022   W (ret);
8023
8024   return ret;
8025 }
8026
8027 static int
8028 api_ip_add_del_route (vat_main_t * vam)
8029 {
8030   unformat_input_t *i = vam->input;
8031   vl_api_ip_add_del_route_t *mp;
8032   u32 sw_if_index = ~0, vrf_id = 0;
8033   u8 is_ipv6 = 0;
8034   u8 is_local = 0, is_drop = 0;
8035   u8 is_unreach = 0, is_prohibit = 0;
8036   u8 create_vrf_if_needed = 0;
8037   u8 is_add = 1;
8038   u32 next_hop_weight = 1;
8039   u8 is_multipath = 0;
8040   u8 address_set = 0;
8041   u8 address_length_set = 0;
8042   u32 next_hop_table_id = 0;
8043   u32 resolve_attempts = 0;
8044   u32 dst_address_length = 0;
8045   u8 next_hop_set = 0;
8046   ip4_address_t v4_dst_address, v4_next_hop_address;
8047   ip6_address_t v6_dst_address, v6_next_hop_address;
8048   int count = 1;
8049   int j;
8050   f64 before = 0;
8051   u32 random_add_del = 0;
8052   u32 *random_vector = 0;
8053   uword *random_hash;
8054   u32 random_seed = 0xdeaddabe;
8055   u32 classify_table_index = ~0;
8056   u8 is_classify = 0;
8057   u8 resolve_host = 0, resolve_attached = 0;
8058   mpls_label_t *next_hop_out_label_stack = NULL;
8059   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8060   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8061
8062   /* Parse args required to build the message */
8063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8064     {
8065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8066         ;
8067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8068         ;
8069       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8070         {
8071           address_set = 1;
8072           is_ipv6 = 0;
8073         }
8074       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8075         {
8076           address_set = 1;
8077           is_ipv6 = 1;
8078         }
8079       else if (unformat (i, "/%d", &dst_address_length))
8080         {
8081           address_length_set = 1;
8082         }
8083
8084       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8085                                          &v4_next_hop_address))
8086         {
8087           next_hop_set = 1;
8088         }
8089       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8090                                          &v6_next_hop_address))
8091         {
8092           next_hop_set = 1;
8093         }
8094       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8095         ;
8096       else if (unformat (i, "weight %d", &next_hop_weight))
8097         ;
8098       else if (unformat (i, "drop"))
8099         {
8100           is_drop = 1;
8101         }
8102       else if (unformat (i, "null-send-unreach"))
8103         {
8104           is_unreach = 1;
8105         }
8106       else if (unformat (i, "null-send-prohibit"))
8107         {
8108           is_prohibit = 1;
8109         }
8110       else if (unformat (i, "local"))
8111         {
8112           is_local = 1;
8113         }
8114       else if (unformat (i, "classify %d", &classify_table_index))
8115         {
8116           is_classify = 1;
8117         }
8118       else if (unformat (i, "del"))
8119         is_add = 0;
8120       else if (unformat (i, "add"))
8121         is_add = 1;
8122       else if (unformat (i, "resolve-via-host"))
8123         resolve_host = 1;
8124       else if (unformat (i, "resolve-via-attached"))
8125         resolve_attached = 1;
8126       else if (unformat (i, "multipath"))
8127         is_multipath = 1;
8128       else if (unformat (i, "vrf %d", &vrf_id))
8129         ;
8130       else if (unformat (i, "create-vrf"))
8131         create_vrf_if_needed = 1;
8132       else if (unformat (i, "count %d", &count))
8133         ;
8134       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8135         ;
8136       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8137         ;
8138       else if (unformat (i, "out-label %d", &next_hop_out_label))
8139         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8140       else if (unformat (i, "via-label %d", &next_hop_via_label))
8141         ;
8142       else if (unformat (i, "random"))
8143         random_add_del = 1;
8144       else if (unformat (i, "seed %d", &random_seed))
8145         ;
8146       else
8147         {
8148           clib_warning ("parse error '%U'", format_unformat_error, i);
8149           return -99;
8150         }
8151     }
8152
8153   if (!next_hop_set && !is_drop && !is_local &&
8154       !is_classify && !is_unreach && !is_prohibit &&
8155       MPLS_LABEL_INVALID == next_hop_via_label)
8156     {
8157       errmsg
8158         ("next hop / local / drop / unreach / prohibit / classify not set");
8159       return -99;
8160     }
8161
8162   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8163     {
8164       errmsg ("next hop and next-hop via label set");
8165       return -99;
8166     }
8167   if (address_set == 0)
8168     {
8169       errmsg ("missing addresses");
8170       return -99;
8171     }
8172
8173   if (address_length_set == 0)
8174     {
8175       errmsg ("missing address length");
8176       return -99;
8177     }
8178
8179   /* Generate a pile of unique, random routes */
8180   if (random_add_del)
8181     {
8182       u32 this_random_address;
8183       random_hash = hash_create (count, sizeof (uword));
8184
8185       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8186       for (j = 0; j <= count; j++)
8187         {
8188           do
8189             {
8190               this_random_address = random_u32 (&random_seed);
8191               this_random_address =
8192                 clib_host_to_net_u32 (this_random_address);
8193             }
8194           while (hash_get (random_hash, this_random_address));
8195           vec_add1 (random_vector, this_random_address);
8196           hash_set (random_hash, this_random_address, 1);
8197         }
8198       hash_free (random_hash);
8199       v4_dst_address.as_u32 = random_vector[0];
8200     }
8201
8202   if (count > 1)
8203     {
8204       /* Turn on async mode */
8205       vam->async_mode = 1;
8206       vam->async_errors = 0;
8207       before = vat_time_now (vam);
8208     }
8209
8210   for (j = 0; j < count; j++)
8211     {
8212       /* Construct the API message */
8213       M2 (IP_ADD_DEL_ROUTE, mp,
8214           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8215
8216       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8217       mp->table_id = ntohl (vrf_id);
8218       mp->create_vrf_if_needed = create_vrf_if_needed;
8219
8220       mp->is_add = is_add;
8221       mp->is_drop = is_drop;
8222       mp->is_unreach = is_unreach;
8223       mp->is_prohibit = is_prohibit;
8224       mp->is_ipv6 = is_ipv6;
8225       mp->is_local = is_local;
8226       mp->is_classify = is_classify;
8227       mp->is_multipath = is_multipath;
8228       mp->is_resolve_host = resolve_host;
8229       mp->is_resolve_attached = resolve_attached;
8230       mp->next_hop_weight = next_hop_weight;
8231       mp->dst_address_length = dst_address_length;
8232       mp->next_hop_table_id = ntohl (next_hop_table_id);
8233       mp->classify_table_index = ntohl (classify_table_index);
8234       mp->next_hop_via_label = ntohl (next_hop_via_label);
8235       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8236       if (0 != mp->next_hop_n_out_labels)
8237         {
8238           memcpy (mp->next_hop_out_label_stack,
8239                   next_hop_out_label_stack,
8240                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8241           vec_free (next_hop_out_label_stack);
8242         }
8243
8244       if (is_ipv6)
8245         {
8246           clib_memcpy (mp->dst_address, &v6_dst_address,
8247                        sizeof (v6_dst_address));
8248           if (next_hop_set)
8249             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8250                          sizeof (v6_next_hop_address));
8251           increment_v6_address (&v6_dst_address);
8252         }
8253       else
8254         {
8255           clib_memcpy (mp->dst_address, &v4_dst_address,
8256                        sizeof (v4_dst_address));
8257           if (next_hop_set)
8258             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8259                          sizeof (v4_next_hop_address));
8260           if (random_add_del)
8261             v4_dst_address.as_u32 = random_vector[j + 1];
8262           else
8263             increment_v4_address (&v4_dst_address);
8264         }
8265       /* send it... */
8266       S (mp);
8267       /* If we receive SIGTERM, stop now... */
8268       if (vam->do_exit)
8269         break;
8270     }
8271
8272   /* When testing multiple add/del ops, use a control-ping to sync */
8273   if (count > 1)
8274     {
8275       vl_api_control_ping_t *mp_ping;
8276       f64 after;
8277       f64 timeout;
8278
8279       /* Shut off async mode */
8280       vam->async_mode = 0;
8281
8282       MPING (CONTROL_PING, mp_ping);
8283       S (mp_ping);
8284
8285       timeout = vat_time_now (vam) + 1.0;
8286       while (vat_time_now (vam) < timeout)
8287         if (vam->result_ready == 1)
8288           goto out;
8289       vam->retval = -99;
8290
8291     out:
8292       if (vam->retval == -99)
8293         errmsg ("timeout");
8294
8295       if (vam->async_errors > 0)
8296         {
8297           errmsg ("%d asynchronous errors", vam->async_errors);
8298           vam->retval = -98;
8299         }
8300       vam->async_errors = 0;
8301       after = vat_time_now (vam);
8302
8303       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8304       if (j > 0)
8305         count = j;
8306
8307       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8308              count, after - before, count / (after - before));
8309     }
8310   else
8311     {
8312       int ret;
8313
8314       /* Wait for a reply... */
8315       W (ret);
8316       return ret;
8317     }
8318
8319   /* Return the good/bad news */
8320   return (vam->retval);
8321 }
8322
8323 static int
8324 api_ip_mroute_add_del (vat_main_t * vam)
8325 {
8326   unformat_input_t *i = vam->input;
8327   vl_api_ip_mroute_add_del_t *mp;
8328   u32 sw_if_index = ~0, vrf_id = 0;
8329   u8 is_ipv6 = 0;
8330   u8 is_local = 0;
8331   u8 create_vrf_if_needed = 0;
8332   u8 is_add = 1;
8333   u8 address_set = 0;
8334   u32 grp_address_length = 0;
8335   ip4_address_t v4_grp_address, v4_src_address;
8336   ip6_address_t v6_grp_address, v6_src_address;
8337   mfib_itf_flags_t iflags = 0;
8338   mfib_entry_flags_t eflags = 0;
8339   int ret;
8340
8341   /* Parse args required to build the message */
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "sw_if_index %d", &sw_if_index))
8345         ;
8346       else if (unformat (i, "%U %U",
8347                          unformat_ip4_address, &v4_src_address,
8348                          unformat_ip4_address, &v4_grp_address))
8349         {
8350           grp_address_length = 64;
8351           address_set = 1;
8352           is_ipv6 = 0;
8353         }
8354       else if (unformat (i, "%U %U",
8355                          unformat_ip6_address, &v6_src_address,
8356                          unformat_ip6_address, &v6_grp_address))
8357         {
8358           grp_address_length = 256;
8359           address_set = 1;
8360           is_ipv6 = 1;
8361         }
8362       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8363         {
8364           memset (&v4_src_address, 0, sizeof (v4_src_address));
8365           grp_address_length = 32;
8366           address_set = 1;
8367           is_ipv6 = 0;
8368         }
8369       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8370         {
8371           memset (&v6_src_address, 0, sizeof (v6_src_address));
8372           grp_address_length = 128;
8373           address_set = 1;
8374           is_ipv6 = 1;
8375         }
8376       else if (unformat (i, "/%d", &grp_address_length))
8377         ;
8378       else if (unformat (i, "local"))
8379         {
8380           is_local = 1;
8381         }
8382       else if (unformat (i, "del"))
8383         is_add = 0;
8384       else if (unformat (i, "add"))
8385         is_add = 1;
8386       else if (unformat (i, "vrf %d", &vrf_id))
8387         ;
8388       else if (unformat (i, "create-vrf"))
8389         create_vrf_if_needed = 1;
8390       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8391         ;
8392       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8393         ;
8394       else
8395         {
8396           clib_warning ("parse error '%U'", format_unformat_error, i);
8397           return -99;
8398         }
8399     }
8400
8401   if (address_set == 0)
8402     {
8403       errmsg ("missing addresses\n");
8404       return -99;
8405     }
8406
8407   /* Construct the API message */
8408   M (IP_MROUTE_ADD_DEL, mp);
8409
8410   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8411   mp->table_id = ntohl (vrf_id);
8412   mp->create_vrf_if_needed = create_vrf_if_needed;
8413
8414   mp->is_add = is_add;
8415   mp->is_ipv6 = is_ipv6;
8416   mp->is_local = is_local;
8417   mp->itf_flags = ntohl (iflags);
8418   mp->entry_flags = ntohl (eflags);
8419   mp->grp_address_length = grp_address_length;
8420   mp->grp_address_length = ntohs (mp->grp_address_length);
8421
8422   if (is_ipv6)
8423     {
8424       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8425       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8426     }
8427   else
8428     {
8429       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8430       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8431
8432     }
8433
8434   /* send it... */
8435   S (mp);
8436   /* Wait for a reply... */
8437   W (ret);
8438   return ret;
8439 }
8440
8441 static int
8442 api_mpls_table_add_del (vat_main_t * vam)
8443 {
8444   unformat_input_t *i = vam->input;
8445   vl_api_mpls_table_add_del_t *mp;
8446   u32 table_id = ~0;
8447   u8 is_add = 1;
8448   int ret = 0;
8449
8450   /* Parse args required to build the message */
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "table %d", &table_id))
8454         ;
8455       else if (unformat (i, "del"))
8456         is_add = 0;
8457       else if (unformat (i, "add"))
8458         is_add = 1;
8459       else
8460         {
8461           clib_warning ("parse error '%U'", format_unformat_error, i);
8462           return -99;
8463         }
8464     }
8465
8466   if (~0 == table_id)
8467     {
8468       errmsg ("missing table-ID");
8469       return -99;
8470     }
8471
8472   /* Construct the API message */
8473   M (MPLS_TABLE_ADD_DEL, mp);
8474
8475   mp->mt_table_id = ntohl (table_id);
8476   mp->mt_is_add = is_add;
8477
8478   /* send it... */
8479   S (mp);
8480
8481   /* Wait for a reply... */
8482   W (ret);
8483
8484   return ret;
8485 }
8486
8487 static int
8488 api_mpls_route_add_del (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_mpls_route_add_del_t *mp;
8492   u32 sw_if_index = ~0, table_id = 0;
8493   u8 create_table_if_needed = 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, "create-table"))
8544         create_table_if_needed = 1;
8545       else if (unformat (i, "classify %d", &classify_table_index))
8546         {
8547           is_classify = 1;
8548         }
8549       else if (unformat (i, "del"))
8550         is_add = 0;
8551       else if (unformat (i, "add"))
8552         is_add = 1;
8553       else if (unformat (i, "resolve-via-host"))
8554         resolve_host = 1;
8555       else if (unformat (i, "resolve-via-attached"))
8556         resolve_attached = 1;
8557       else if (unformat (i, "multipath"))
8558         is_multipath = 1;
8559       else if (unformat (i, "count %d", &count))
8560         ;
8561       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8562         {
8563           next_hop_set = 1;
8564           next_hop_proto = DPO_PROTO_IP4;
8565         }
8566       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8567         {
8568           next_hop_set = 1;
8569           next_hop_proto = DPO_PROTO_IP6;
8570         }
8571       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8572         ;
8573       else if (unformat (i, "via-label %d", &next_hop_via_label))
8574         ;
8575       else if (unformat (i, "out-label %d", &next_hop_out_label))
8576         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8577       else
8578         {
8579           clib_warning ("parse error '%U'", format_unformat_error, i);
8580           return -99;
8581         }
8582     }
8583
8584   if (!next_hop_set && !is_classify)
8585     {
8586       errmsg ("next hop / classify not set");
8587       return -99;
8588     }
8589
8590   if (MPLS_LABEL_INVALID == local_label)
8591     {
8592       errmsg ("missing label");
8593       return -99;
8594     }
8595
8596   if (count > 1)
8597     {
8598       /* Turn on async mode */
8599       vam->async_mode = 1;
8600       vam->async_errors = 0;
8601       before = vat_time_now (vam);
8602     }
8603
8604   for (j = 0; j < count; j++)
8605     {
8606       /* Construct the API message */
8607       M2 (MPLS_ROUTE_ADD_DEL, mp,
8608           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8609
8610       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8611       mp->mr_table_id = ntohl (table_id);
8612       mp->mr_create_table_if_needed = create_table_if_needed;
8613
8614       mp->mr_is_add = is_add;
8615       mp->mr_next_hop_proto = next_hop_proto;
8616       mp->mr_is_classify = is_classify;
8617       mp->mr_is_multipath = is_multipath;
8618       mp->mr_is_resolve_host = resolve_host;
8619       mp->mr_is_resolve_attached = resolve_attached;
8620       mp->mr_next_hop_weight = next_hop_weight;
8621       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8622       mp->mr_classify_table_index = ntohl (classify_table_index);
8623       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8624       mp->mr_label = ntohl (local_label);
8625       mp->mr_eos = is_eos;
8626
8627       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8628       if (0 != mp->mr_next_hop_n_out_labels)
8629         {
8630           memcpy (mp->mr_next_hop_out_label_stack,
8631                   next_hop_out_label_stack,
8632                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8633           vec_free (next_hop_out_label_stack);
8634         }
8635
8636       if (next_hop_set)
8637         {
8638           if (DPO_PROTO_IP4 == next_hop_proto)
8639             {
8640               clib_memcpy (mp->mr_next_hop,
8641                            &v4_next_hop_address,
8642                            sizeof (v4_next_hop_address));
8643             }
8644           else if (DPO_PROTO_IP6 == next_hop_proto)
8645
8646             {
8647               clib_memcpy (mp->mr_next_hop,
8648                            &v6_next_hop_address,
8649                            sizeof (v6_next_hop_address));
8650             }
8651         }
8652       local_label++;
8653
8654       /* send it... */
8655       S (mp);
8656       /* If we receive SIGTERM, stop now... */
8657       if (vam->do_exit)
8658         break;
8659     }
8660
8661   /* When testing multiple add/del ops, use a control-ping to sync */
8662   if (count > 1)
8663     {
8664       vl_api_control_ping_t *mp_ping;
8665       f64 after;
8666       f64 timeout;
8667
8668       /* Shut off async mode */
8669       vam->async_mode = 0;
8670
8671       MPING (CONTROL_PING, mp_ping);
8672       S (mp_ping);
8673
8674       timeout = vat_time_now (vam) + 1.0;
8675       while (vat_time_now (vam) < timeout)
8676         if (vam->result_ready == 1)
8677           goto out;
8678       vam->retval = -99;
8679
8680     out:
8681       if (vam->retval == -99)
8682         errmsg ("timeout");
8683
8684       if (vam->async_errors > 0)
8685         {
8686           errmsg ("%d asynchronous errors", vam->async_errors);
8687           vam->retval = -98;
8688         }
8689       vam->async_errors = 0;
8690       after = vat_time_now (vam);
8691
8692       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8693       if (j > 0)
8694         count = j;
8695
8696       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8697              count, after - before, count / (after - before));
8698     }
8699   else
8700     {
8701       int ret;
8702
8703       /* Wait for a reply... */
8704       W (ret);
8705       return ret;
8706     }
8707
8708   /* Return the good/bad news */
8709   return (vam->retval);
8710 }
8711
8712 static int
8713 api_mpls_ip_bind_unbind (vat_main_t * vam)
8714 {
8715   unformat_input_t *i = vam->input;
8716   vl_api_mpls_ip_bind_unbind_t *mp;
8717   u32 ip_table_id = 0;
8718   u8 create_table_if_needed = 0;
8719   u8 is_bind = 1;
8720   u8 is_ip4 = 1;
8721   ip4_address_t v4_address;
8722   ip6_address_t v6_address;
8723   u32 address_length;
8724   u8 address_set = 0;
8725   mpls_label_t local_label = MPLS_LABEL_INVALID;
8726   int ret;
8727
8728   /* Parse args required to build the message */
8729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8730     {
8731       if (unformat (i, "%U/%d", unformat_ip4_address,
8732                     &v4_address, &address_length))
8733         {
8734           is_ip4 = 1;
8735           address_set = 1;
8736         }
8737       else if (unformat (i, "%U/%d", unformat_ip6_address,
8738                          &v6_address, &address_length))
8739         {
8740           is_ip4 = 0;
8741           address_set = 1;
8742         }
8743       else if (unformat (i, "%d", &local_label))
8744         ;
8745       else if (unformat (i, "create-table"))
8746         create_table_if_needed = 1;
8747       else if (unformat (i, "table-id %d", &ip_table_id))
8748         ;
8749       else if (unformat (i, "unbind"))
8750         is_bind = 0;
8751       else if (unformat (i, "bind"))
8752         is_bind = 1;
8753       else
8754         {
8755           clib_warning ("parse error '%U'", format_unformat_error, i);
8756           return -99;
8757         }
8758     }
8759
8760   if (!address_set)
8761     {
8762       errmsg ("IP addres not set");
8763       return -99;
8764     }
8765
8766   if (MPLS_LABEL_INVALID == local_label)
8767     {
8768       errmsg ("missing label");
8769       return -99;
8770     }
8771
8772   /* Construct the API message */
8773   M (MPLS_IP_BIND_UNBIND, mp);
8774
8775   mp->mb_create_table_if_needed = create_table_if_needed;
8776   mp->mb_is_bind = is_bind;
8777   mp->mb_is_ip4 = is_ip4;
8778   mp->mb_ip_table_id = ntohl (ip_table_id);
8779   mp->mb_mpls_table_id = 0;
8780   mp->mb_label = ntohl (local_label);
8781   mp->mb_address_length = address_length;
8782
8783   if (is_ip4)
8784     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8785   else
8786     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8787
8788   /* send it... */
8789   S (mp);
8790
8791   /* Wait for a reply... */
8792   W (ret);
8793   return ret;
8794 }
8795
8796 static int
8797 api_bier_table_add_del (vat_main_t * vam)
8798 {
8799   unformat_input_t *i = vam->input;
8800   vl_api_bier_table_add_del_t *mp;
8801   u8 is_add = 1;
8802   u32 set = 0, sub_domain = 0, hdr_len = 3;
8803   mpls_label_t local_label = MPLS_LABEL_INVALID;
8804   int ret;
8805
8806   /* Parse args required to build the message */
8807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808     {
8809       if (unformat (i, "sub-domain %d", &sub_domain))
8810         ;
8811       else if (unformat (i, "set %d", &set))
8812         ;
8813       else if (unformat (i, "label %d", &local_label))
8814         ;
8815       else if (unformat (i, "hdr-len %d", &hdr_len))
8816         ;
8817       else if (unformat (i, "add"))
8818         is_add = 1;
8819       else if (unformat (i, "del"))
8820         is_add = 0;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (MPLS_LABEL_INVALID == local_label)
8829     {
8830       errmsg ("missing label\n");
8831       return -99;
8832     }
8833
8834   /* Construct the API message */
8835   M (BIER_TABLE_ADD_DEL, mp);
8836
8837   mp->bt_is_add = is_add;
8838   mp->bt_label = ntohl (local_label);
8839   mp->bt_tbl_id.bt_set = set;
8840   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8841   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8842
8843   /* send it... */
8844   S (mp);
8845
8846   /* Wait for a reply... */
8847   W (ret);
8848
8849   return (ret);
8850 }
8851
8852 static int
8853 api_bier_route_add_del (vat_main_t * vam)
8854 {
8855   unformat_input_t *i = vam->input;
8856   vl_api_bier_route_add_del_t *mp;
8857   u8 is_add = 1;
8858   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8859   ip4_address_t v4_next_hop_address;
8860   ip6_address_t v6_next_hop_address;
8861   u8 next_hop_set = 0;
8862   u8 next_hop_proto_is_ip4 = 1;
8863   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8864   int ret;
8865
8866   /* Parse args required to build the message */
8867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8868     {
8869       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8870         {
8871           next_hop_proto_is_ip4 = 1;
8872           next_hop_set = 1;
8873         }
8874       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8875         {
8876           next_hop_proto_is_ip4 = 0;
8877           next_hop_set = 1;
8878         }
8879       if (unformat (i, "sub-domain %d", &sub_domain))
8880         ;
8881       else if (unformat (i, "set %d", &set))
8882         ;
8883       else if (unformat (i, "hdr-len %d", &hdr_len))
8884         ;
8885       else if (unformat (i, "bp %d", &bp))
8886         ;
8887       else if (unformat (i, "add"))
8888         is_add = 1;
8889       else if (unformat (i, "del"))
8890         is_add = 0;
8891       else if (unformat (i, "out-label %d", &next_hop_out_label))
8892         ;
8893       else
8894         {
8895           clib_warning ("parse error '%U'", format_unformat_error, i);
8896           return -99;
8897         }
8898     }
8899
8900   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8901     {
8902       errmsg ("next hop / label set\n");
8903       return -99;
8904     }
8905   if (0 == bp)
8906     {
8907       errmsg ("bit=position not set\n");
8908       return -99;
8909     }
8910
8911   /* Construct the API message */
8912   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8913
8914   mp->br_is_add = is_add;
8915   mp->br_tbl_id.bt_set = set;
8916   mp->br_tbl_id.bt_sub_domain = sub_domain;
8917   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8918   mp->br_bp = ntohs (bp);
8919   mp->br_n_paths = 1;
8920   mp->br_paths[0].n_labels = 1;
8921   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8922   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8923
8924   if (next_hop_proto_is_ip4)
8925     {
8926       clib_memcpy (mp->br_paths[0].next_hop,
8927                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8928     }
8929   else
8930     {
8931       clib_memcpy (mp->br_paths[0].next_hop,
8932                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8933     }
8934
8935   /* send it... */
8936   S (mp);
8937
8938   /* Wait for a reply... */
8939   W (ret);
8940
8941   return (ret);
8942 }
8943
8944 static int
8945 api_proxy_arp_add_del (vat_main_t * vam)
8946 {
8947   unformat_input_t *i = vam->input;
8948   vl_api_proxy_arp_add_del_t *mp;
8949   u32 vrf_id = 0;
8950   u8 is_add = 1;
8951   ip4_address_t lo, hi;
8952   u8 range_set = 0;
8953   int ret;
8954
8955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8956     {
8957       if (unformat (i, "vrf %d", &vrf_id))
8958         ;
8959       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8960                          unformat_ip4_address, &hi))
8961         range_set = 1;
8962       else if (unformat (i, "del"))
8963         is_add = 0;
8964       else
8965         {
8966           clib_warning ("parse error '%U'", format_unformat_error, i);
8967           return -99;
8968         }
8969     }
8970
8971   if (range_set == 0)
8972     {
8973       errmsg ("address range not set");
8974       return -99;
8975     }
8976
8977   M (PROXY_ARP_ADD_DEL, mp);
8978
8979   mp->vrf_id = ntohl (vrf_id);
8980   mp->is_add = is_add;
8981   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8982   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8983
8984   S (mp);
8985   W (ret);
8986   return ret;
8987 }
8988
8989 static int
8990 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8991 {
8992   unformat_input_t *i = vam->input;
8993   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8994   u32 sw_if_index;
8995   u8 enable = 1;
8996   u8 sw_if_index_set = 0;
8997   int ret;
8998
8999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9002         sw_if_index_set = 1;
9003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9004         sw_if_index_set = 1;
9005       else if (unformat (i, "enable"))
9006         enable = 1;
9007       else if (unformat (i, "disable"))
9008         enable = 0;
9009       else
9010         {
9011           clib_warning ("parse error '%U'", format_unformat_error, i);
9012           return -99;
9013         }
9014     }
9015
9016   if (sw_if_index_set == 0)
9017     {
9018       errmsg ("missing interface name or sw_if_index");
9019       return -99;
9020     }
9021
9022   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9023
9024   mp->sw_if_index = ntohl (sw_if_index);
9025   mp->enable_disable = enable;
9026
9027   S (mp);
9028   W (ret);
9029   return ret;
9030 }
9031
9032 static int
9033 api_mpls_tunnel_add_del (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_mpls_tunnel_add_del_t *mp;
9037
9038   u8 is_add = 1;
9039   u8 l2_only = 0;
9040   u32 sw_if_index = ~0;
9041   u32 next_hop_sw_if_index = ~0;
9042   u32 next_hop_proto_is_ip4 = 1;
9043
9044   u32 next_hop_table_id = 0;
9045   ip4_address_t v4_next_hop_address = {
9046     .as_u32 = 0,
9047   };
9048   ip6_address_t v6_next_hop_address = { {0} };
9049   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9050   int ret;
9051
9052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9053     {
9054       if (unformat (i, "add"))
9055         is_add = 1;
9056       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9057         is_add = 0;
9058       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9059         ;
9060       else if (unformat (i, "via %U",
9061                          unformat_ip4_address, &v4_next_hop_address))
9062         {
9063           next_hop_proto_is_ip4 = 1;
9064         }
9065       else if (unformat (i, "via %U",
9066                          unformat_ip6_address, &v6_next_hop_address))
9067         {
9068           next_hop_proto_is_ip4 = 0;
9069         }
9070       else if (unformat (i, "l2-only"))
9071         l2_only = 1;
9072       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9073         ;
9074       else if (unformat (i, "out-label %d", &next_hop_out_label))
9075         vec_add1 (labels, ntohl (next_hop_out_label));
9076       else
9077         {
9078           clib_warning ("parse error '%U'", format_unformat_error, i);
9079           return -99;
9080         }
9081     }
9082
9083   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9084
9085   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9086   mp->mt_sw_if_index = ntohl (sw_if_index);
9087   mp->mt_is_add = is_add;
9088   mp->mt_l2_only = l2_only;
9089   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9090   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9091
9092   mp->mt_next_hop_n_out_labels = vec_len (labels);
9093
9094   if (0 != mp->mt_next_hop_n_out_labels)
9095     {
9096       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9097                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9098       vec_free (labels);
9099     }
9100
9101   if (next_hop_proto_is_ip4)
9102     {
9103       clib_memcpy (mp->mt_next_hop,
9104                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9105     }
9106   else
9107     {
9108       clib_memcpy (mp->mt_next_hop,
9109                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9110     }
9111
9112   S (mp);
9113   W (ret);
9114   return ret;
9115 }
9116
9117 static int
9118 api_sw_interface_set_unnumbered (vat_main_t * vam)
9119 {
9120   unformat_input_t *i = vam->input;
9121   vl_api_sw_interface_set_unnumbered_t *mp;
9122   u32 sw_if_index;
9123   u32 unnum_sw_index = ~0;
9124   u8 is_add = 1;
9125   u8 sw_if_index_set = 0;
9126   int ret;
9127
9128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9129     {
9130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9131         sw_if_index_set = 1;
9132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9133         sw_if_index_set = 1;
9134       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9135         ;
9136       else if (unformat (i, "del"))
9137         is_add = 0;
9138       else
9139         {
9140           clib_warning ("parse error '%U'", format_unformat_error, i);
9141           return -99;
9142         }
9143     }
9144
9145   if (sw_if_index_set == 0)
9146     {
9147       errmsg ("missing interface name or sw_if_index");
9148       return -99;
9149     }
9150
9151   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9152
9153   mp->sw_if_index = ntohl (sw_if_index);
9154   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9155   mp->is_add = is_add;
9156
9157   S (mp);
9158   W (ret);
9159   return ret;
9160 }
9161
9162 static int
9163 api_ip_neighbor_add_del (vat_main_t * vam)
9164 {
9165   unformat_input_t *i = vam->input;
9166   vl_api_ip_neighbor_add_del_t *mp;
9167   u32 sw_if_index;
9168   u8 sw_if_index_set = 0;
9169   u8 is_add = 1;
9170   u8 is_static = 0;
9171   u8 is_no_fib_entry = 0;
9172   u8 mac_address[6];
9173   u8 mac_set = 0;
9174   u8 v4_address_set = 0;
9175   u8 v6_address_set = 0;
9176   ip4_address_t v4address;
9177   ip6_address_t v6address;
9178   int ret;
9179
9180   memset (mac_address, 0, sizeof (mac_address));
9181
9182   /* Parse args required to build the message */
9183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9184     {
9185       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9186         {
9187           mac_set = 1;
9188         }
9189       else if (unformat (i, "del"))
9190         is_add = 0;
9191       else
9192         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9193         sw_if_index_set = 1;
9194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9195         sw_if_index_set = 1;
9196       else if (unformat (i, "is_static"))
9197         is_static = 1;
9198       else if (unformat (i, "no-fib-entry"))
9199         is_no_fib_entry = 1;
9200       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9201         v4_address_set = 1;
9202       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9203         v6_address_set = 1;
9204       else
9205         {
9206           clib_warning ("parse error '%U'", format_unformat_error, i);
9207           return -99;
9208         }
9209     }
9210
9211   if (sw_if_index_set == 0)
9212     {
9213       errmsg ("missing interface name or sw_if_index");
9214       return -99;
9215     }
9216   if (v4_address_set && v6_address_set)
9217     {
9218       errmsg ("both v4 and v6 addresses set");
9219       return -99;
9220     }
9221   if (!v4_address_set && !v6_address_set)
9222     {
9223       errmsg ("no address set");
9224       return -99;
9225     }
9226
9227   /* Construct the API message */
9228   M (IP_NEIGHBOR_ADD_DEL, mp);
9229
9230   mp->sw_if_index = ntohl (sw_if_index);
9231   mp->is_add = is_add;
9232   mp->is_static = is_static;
9233   mp->is_no_adj_fib = is_no_fib_entry;
9234   if (mac_set)
9235     clib_memcpy (mp->mac_address, mac_address, 6);
9236   if (v6_address_set)
9237     {
9238       mp->is_ipv6 = 1;
9239       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9240     }
9241   else
9242     {
9243       /* mp->is_ipv6 = 0; via memset in M macro above */
9244       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9245     }
9246
9247   /* send it... */
9248   S (mp);
9249
9250   /* Wait for a reply, return good/bad news  */
9251   W (ret);
9252   return ret;
9253 }
9254
9255 static int
9256 api_create_vlan_subif (vat_main_t * vam)
9257 {
9258   unformat_input_t *i = vam->input;
9259   vl_api_create_vlan_subif_t *mp;
9260   u32 sw_if_index;
9261   u8 sw_if_index_set = 0;
9262   u32 vlan_id;
9263   u8 vlan_id_set = 0;
9264   int ret;
9265
9266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9267     {
9268       if (unformat (i, "sw_if_index %d", &sw_if_index))
9269         sw_if_index_set = 1;
9270       else
9271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9272         sw_if_index_set = 1;
9273       else if (unformat (i, "vlan %d", &vlan_id))
9274         vlan_id_set = 1;
9275       else
9276         {
9277           clib_warning ("parse error '%U'", format_unformat_error, i);
9278           return -99;
9279         }
9280     }
9281
9282   if (sw_if_index_set == 0)
9283     {
9284       errmsg ("missing interface name or sw_if_index");
9285       return -99;
9286     }
9287
9288   if (vlan_id_set == 0)
9289     {
9290       errmsg ("missing vlan_id");
9291       return -99;
9292     }
9293   M (CREATE_VLAN_SUBIF, mp);
9294
9295   mp->sw_if_index = ntohl (sw_if_index);
9296   mp->vlan_id = ntohl (vlan_id);
9297
9298   S (mp);
9299   W (ret);
9300   return ret;
9301 }
9302
9303 #define foreach_create_subif_bit                \
9304 _(no_tags)                                      \
9305 _(one_tag)                                      \
9306 _(two_tags)                                     \
9307 _(dot1ad)                                       \
9308 _(exact_match)                                  \
9309 _(default_sub)                                  \
9310 _(outer_vlan_id_any)                            \
9311 _(inner_vlan_id_any)
9312
9313 static int
9314 api_create_subif (vat_main_t * vam)
9315 {
9316   unformat_input_t *i = vam->input;
9317   vl_api_create_subif_t *mp;
9318   u32 sw_if_index;
9319   u8 sw_if_index_set = 0;
9320   u32 sub_id;
9321   u8 sub_id_set = 0;
9322   u32 no_tags = 0;
9323   u32 one_tag = 0;
9324   u32 two_tags = 0;
9325   u32 dot1ad = 0;
9326   u32 exact_match = 0;
9327   u32 default_sub = 0;
9328   u32 outer_vlan_id_any = 0;
9329   u32 inner_vlan_id_any = 0;
9330   u32 tmp;
9331   u16 outer_vlan_id = 0;
9332   u16 inner_vlan_id = 0;
9333   int ret;
9334
9335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9336     {
9337       if (unformat (i, "sw_if_index %d", &sw_if_index))
9338         sw_if_index_set = 1;
9339       else
9340         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9341         sw_if_index_set = 1;
9342       else if (unformat (i, "sub_id %d", &sub_id))
9343         sub_id_set = 1;
9344       else if (unformat (i, "outer_vlan_id %d", &tmp))
9345         outer_vlan_id = tmp;
9346       else if (unformat (i, "inner_vlan_id %d", &tmp))
9347         inner_vlan_id = tmp;
9348
9349 #define _(a) else if (unformat (i, #a)) a = 1 ;
9350       foreach_create_subif_bit
9351 #undef _
9352         else
9353         {
9354           clib_warning ("parse error '%U'", format_unformat_error, i);
9355           return -99;
9356         }
9357     }
9358
9359   if (sw_if_index_set == 0)
9360     {
9361       errmsg ("missing interface name or sw_if_index");
9362       return -99;
9363     }
9364
9365   if (sub_id_set == 0)
9366     {
9367       errmsg ("missing sub_id");
9368       return -99;
9369     }
9370   M (CREATE_SUBIF, mp);
9371
9372   mp->sw_if_index = ntohl (sw_if_index);
9373   mp->sub_id = ntohl (sub_id);
9374
9375 #define _(a) mp->a = a;
9376   foreach_create_subif_bit;
9377 #undef _
9378
9379   mp->outer_vlan_id = ntohs (outer_vlan_id);
9380   mp->inner_vlan_id = ntohs (inner_vlan_id);
9381
9382   S (mp);
9383   W (ret);
9384   return ret;
9385 }
9386
9387 static int
9388 api_oam_add_del (vat_main_t * vam)
9389 {
9390   unformat_input_t *i = vam->input;
9391   vl_api_oam_add_del_t *mp;
9392   u32 vrf_id = 0;
9393   u8 is_add = 1;
9394   ip4_address_t src, dst;
9395   u8 src_set = 0;
9396   u8 dst_set = 0;
9397   int ret;
9398
9399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9400     {
9401       if (unformat (i, "vrf %d", &vrf_id))
9402         ;
9403       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9404         src_set = 1;
9405       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9406         dst_set = 1;
9407       else if (unformat (i, "del"))
9408         is_add = 0;
9409       else
9410         {
9411           clib_warning ("parse error '%U'", format_unformat_error, i);
9412           return -99;
9413         }
9414     }
9415
9416   if (src_set == 0)
9417     {
9418       errmsg ("missing src addr");
9419       return -99;
9420     }
9421
9422   if (dst_set == 0)
9423     {
9424       errmsg ("missing dst addr");
9425       return -99;
9426     }
9427
9428   M (OAM_ADD_DEL, mp);
9429
9430   mp->vrf_id = ntohl (vrf_id);
9431   mp->is_add = is_add;
9432   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9433   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9434
9435   S (mp);
9436   W (ret);
9437   return ret;
9438 }
9439
9440 static int
9441 api_reset_fib (vat_main_t * vam)
9442 {
9443   unformat_input_t *i = vam->input;
9444   vl_api_reset_fib_t *mp;
9445   u32 vrf_id = 0;
9446   u8 is_ipv6 = 0;
9447   u8 vrf_id_set = 0;
9448
9449   int ret;
9450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9451     {
9452       if (unformat (i, "vrf %d", &vrf_id))
9453         vrf_id_set = 1;
9454       else if (unformat (i, "ipv6"))
9455         is_ipv6 = 1;
9456       else
9457         {
9458           clib_warning ("parse error '%U'", format_unformat_error, i);
9459           return -99;
9460         }
9461     }
9462
9463   if (vrf_id_set == 0)
9464     {
9465       errmsg ("missing vrf id");
9466       return -99;
9467     }
9468
9469   M (RESET_FIB, mp);
9470
9471   mp->vrf_id = ntohl (vrf_id);
9472   mp->is_ipv6 = is_ipv6;
9473
9474   S (mp);
9475   W (ret);
9476   return ret;
9477 }
9478
9479 static int
9480 api_dhcp_proxy_config (vat_main_t * vam)
9481 {
9482   unformat_input_t *i = vam->input;
9483   vl_api_dhcp_proxy_config_t *mp;
9484   u32 rx_vrf_id = 0;
9485   u32 server_vrf_id = 0;
9486   u8 is_add = 1;
9487   u8 v4_address_set = 0;
9488   u8 v6_address_set = 0;
9489   ip4_address_t v4address;
9490   ip6_address_t v6address;
9491   u8 v4_src_address_set = 0;
9492   u8 v6_src_address_set = 0;
9493   ip4_address_t v4srcaddress;
9494   ip6_address_t v6srcaddress;
9495   int ret;
9496
9497   /* Parse args required to build the message */
9498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9499     {
9500       if (unformat (i, "del"))
9501         is_add = 0;
9502       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9503         ;
9504       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9505         ;
9506       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9507         v4_address_set = 1;
9508       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9509         v6_address_set = 1;
9510       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9511         v4_src_address_set = 1;
9512       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9513         v6_src_address_set = 1;
9514       else
9515         break;
9516     }
9517
9518   if (v4_address_set && v6_address_set)
9519     {
9520       errmsg ("both v4 and v6 server addresses set");
9521       return -99;
9522     }
9523   if (!v4_address_set && !v6_address_set)
9524     {
9525       errmsg ("no server addresses set");
9526       return -99;
9527     }
9528
9529   if (v4_src_address_set && v6_src_address_set)
9530     {
9531       errmsg ("both v4 and v6  src addresses set");
9532       return -99;
9533     }
9534   if (!v4_src_address_set && !v6_src_address_set)
9535     {
9536       errmsg ("no src addresses set");
9537       return -99;
9538     }
9539
9540   if (!(v4_src_address_set && v4_address_set) &&
9541       !(v6_src_address_set && v6_address_set))
9542     {
9543       errmsg ("no matching server and src addresses set");
9544       return -99;
9545     }
9546
9547   /* Construct the API message */
9548   M (DHCP_PROXY_CONFIG, mp);
9549
9550   mp->is_add = is_add;
9551   mp->rx_vrf_id = ntohl (rx_vrf_id);
9552   mp->server_vrf_id = ntohl (server_vrf_id);
9553   if (v6_address_set)
9554     {
9555       mp->is_ipv6 = 1;
9556       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9557       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9558     }
9559   else
9560     {
9561       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9562       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9563     }
9564
9565   /* send it... */
9566   S (mp);
9567
9568   /* Wait for a reply, return good/bad news  */
9569   W (ret);
9570   return ret;
9571 }
9572
9573 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9574 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9575
9576 static void
9577 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9578 {
9579   vat_main_t *vam = &vat_main;
9580   u32 i, count = mp->count;
9581   vl_api_dhcp_server_t *s;
9582
9583   if (mp->is_ipv6)
9584     print (vam->ofp,
9585            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9586            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9587            ntohl (mp->rx_vrf_id),
9588            format_ip6_address, mp->dhcp_src_address,
9589            mp->vss_type, mp->vss_vpn_ascii_id,
9590            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9591   else
9592     print (vam->ofp,
9593            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9594            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9595            ntohl (mp->rx_vrf_id),
9596            format_ip4_address, mp->dhcp_src_address,
9597            mp->vss_type, mp->vss_vpn_ascii_id,
9598            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9599
9600   for (i = 0; i < count; i++)
9601     {
9602       s = &mp->servers[i];
9603
9604       if (mp->is_ipv6)
9605         print (vam->ofp,
9606                " Server Table-ID %d, Server Address %U",
9607                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9608       else
9609         print (vam->ofp,
9610                " Server Table-ID %d, Server Address %U",
9611                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9612     }
9613 }
9614
9615 static void vl_api_dhcp_proxy_details_t_handler_json
9616   (vl_api_dhcp_proxy_details_t * mp)
9617 {
9618   vat_main_t *vam = &vat_main;
9619   vat_json_node_t *node = NULL;
9620   u32 i, count = mp->count;
9621   struct in_addr ip4;
9622   struct in6_addr ip6;
9623   vl_api_dhcp_server_t *s;
9624
9625   if (VAT_JSON_ARRAY != vam->json_tree.type)
9626     {
9627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9628       vat_json_init_array (&vam->json_tree);
9629     }
9630   node = vat_json_array_add (&vam->json_tree);
9631
9632   vat_json_init_object (node);
9633   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9634   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9635                              sizeof (mp->vss_type));
9636   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9637                                    mp->vss_vpn_ascii_id);
9638   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9639   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9640
9641   if (mp->is_ipv6)
9642     {
9643       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9644       vat_json_object_add_ip6 (node, "src_address", ip6);
9645     }
9646   else
9647     {
9648       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9649       vat_json_object_add_ip4 (node, "src_address", ip4);
9650     }
9651
9652   for (i = 0; i < count; i++)
9653     {
9654       s = &mp->servers[i];
9655
9656       vat_json_object_add_uint (node, "server-table-id",
9657                                 ntohl (s->server_vrf_id));
9658
9659       if (mp->is_ipv6)
9660         {
9661           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9662           vat_json_object_add_ip4 (node, "src_address", ip4);
9663         }
9664       else
9665         {
9666           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9667           vat_json_object_add_ip6 (node, "server_address", ip6);
9668         }
9669     }
9670 }
9671
9672 static int
9673 api_dhcp_proxy_dump (vat_main_t * vam)
9674 {
9675   unformat_input_t *i = vam->input;
9676   vl_api_control_ping_t *mp_ping;
9677   vl_api_dhcp_proxy_dump_t *mp;
9678   u8 is_ipv6 = 0;
9679   int ret;
9680
9681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9682     {
9683       if (unformat (i, "ipv6"))
9684         is_ipv6 = 1;
9685       else
9686         {
9687           clib_warning ("parse error '%U'", format_unformat_error, i);
9688           return -99;
9689         }
9690     }
9691
9692   M (DHCP_PROXY_DUMP, mp);
9693
9694   mp->is_ip6 = is_ipv6;
9695   S (mp);
9696
9697   /* Use a control ping for synchronization */
9698   MPING (CONTROL_PING, mp_ping);
9699   S (mp_ping);
9700
9701   W (ret);
9702   return ret;
9703 }
9704
9705 static int
9706 api_dhcp_proxy_set_vss (vat_main_t * vam)
9707 {
9708   unformat_input_t *i = vam->input;
9709   vl_api_dhcp_proxy_set_vss_t *mp;
9710   u8 is_ipv6 = 0;
9711   u8 is_add = 1;
9712   u32 tbl_id = ~0;
9713   u8 vss_type = VSS_TYPE_DEFAULT;
9714   u8 *vpn_ascii_id = 0;
9715   u32 oui = 0;
9716   u32 fib_id = 0;
9717   int ret;
9718
9719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9720     {
9721       if (unformat (i, "tbl_id %d", &tbl_id))
9722         ;
9723       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9724         vss_type = VSS_TYPE_ASCII;
9725       else if (unformat (i, "fib_id %d", &fib_id))
9726         vss_type = VSS_TYPE_VPN_ID;
9727       else if (unformat (i, "oui %d", &oui))
9728         vss_type = VSS_TYPE_VPN_ID;
9729       else if (unformat (i, "ipv6"))
9730         is_ipv6 = 1;
9731       else if (unformat (i, "del"))
9732         is_add = 0;
9733       else
9734         break;
9735     }
9736
9737   if (tbl_id == ~0)
9738     {
9739       errmsg ("missing tbl_id ");
9740       vec_free (vpn_ascii_id);
9741       return -99;
9742     }
9743
9744   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9745     {
9746       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9747       vec_free (vpn_ascii_id);
9748       return -99;
9749     }
9750
9751   M (DHCP_PROXY_SET_VSS, mp);
9752   mp->tbl_id = ntohl (tbl_id);
9753   mp->vss_type = vss_type;
9754   if (vpn_ascii_id)
9755     {
9756       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9757       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9758     }
9759   mp->vpn_index = ntohl (fib_id);
9760   mp->oui = ntohl (oui);
9761   mp->is_ipv6 = is_ipv6;
9762   mp->is_add = is_add;
9763
9764   S (mp);
9765   W (ret);
9766
9767   vec_free (vpn_ascii_id);
9768   return ret;
9769 }
9770
9771 static int
9772 api_dhcp_client_config (vat_main_t * vam)
9773 {
9774   unformat_input_t *i = vam->input;
9775   vl_api_dhcp_client_config_t *mp;
9776   u32 sw_if_index;
9777   u8 sw_if_index_set = 0;
9778   u8 is_add = 1;
9779   u8 *hostname = 0;
9780   u8 disable_event = 0;
9781   int ret;
9782
9783   /* Parse args required to build the message */
9784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9785     {
9786       if (unformat (i, "del"))
9787         is_add = 0;
9788       else
9789         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9790         sw_if_index_set = 1;
9791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9792         sw_if_index_set = 1;
9793       else if (unformat (i, "hostname %s", &hostname))
9794         ;
9795       else if (unformat (i, "disable_event"))
9796         disable_event = 1;
9797       else
9798         break;
9799     }
9800
9801   if (sw_if_index_set == 0)
9802     {
9803       errmsg ("missing interface name or sw_if_index");
9804       return -99;
9805     }
9806
9807   if (vec_len (hostname) > 63)
9808     {
9809       errmsg ("hostname too long");
9810     }
9811   vec_add1 (hostname, 0);
9812
9813   /* Construct the API message */
9814   M (DHCP_CLIENT_CONFIG, mp);
9815
9816   mp->sw_if_index = htonl (sw_if_index);
9817   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9818   vec_free (hostname);
9819   mp->is_add = is_add;
9820   mp->want_dhcp_event = disable_event ? 0 : 1;
9821   mp->pid = htonl (getpid ());
9822
9823   /* send it... */
9824   S (mp);
9825
9826   /* Wait for a reply, return good/bad news  */
9827   W (ret);
9828   return ret;
9829 }
9830
9831 static int
9832 api_set_ip_flow_hash (vat_main_t * vam)
9833 {
9834   unformat_input_t *i = vam->input;
9835   vl_api_set_ip_flow_hash_t *mp;
9836   u32 vrf_id = 0;
9837   u8 is_ipv6 = 0;
9838   u8 vrf_id_set = 0;
9839   u8 src = 0;
9840   u8 dst = 0;
9841   u8 sport = 0;
9842   u8 dport = 0;
9843   u8 proto = 0;
9844   u8 reverse = 0;
9845   int ret;
9846
9847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9848     {
9849       if (unformat (i, "vrf %d", &vrf_id))
9850         vrf_id_set = 1;
9851       else if (unformat (i, "ipv6"))
9852         is_ipv6 = 1;
9853       else if (unformat (i, "src"))
9854         src = 1;
9855       else if (unformat (i, "dst"))
9856         dst = 1;
9857       else if (unformat (i, "sport"))
9858         sport = 1;
9859       else if (unformat (i, "dport"))
9860         dport = 1;
9861       else if (unformat (i, "proto"))
9862         proto = 1;
9863       else if (unformat (i, "reverse"))
9864         reverse = 1;
9865
9866       else
9867         {
9868           clib_warning ("parse error '%U'", format_unformat_error, i);
9869           return -99;
9870         }
9871     }
9872
9873   if (vrf_id_set == 0)
9874     {
9875       errmsg ("missing vrf id");
9876       return -99;
9877     }
9878
9879   M (SET_IP_FLOW_HASH, mp);
9880   mp->src = src;
9881   mp->dst = dst;
9882   mp->sport = sport;
9883   mp->dport = dport;
9884   mp->proto = proto;
9885   mp->reverse = reverse;
9886   mp->vrf_id = ntohl (vrf_id);
9887   mp->is_ipv6 = is_ipv6;
9888
9889   S (mp);
9890   W (ret);
9891   return ret;
9892 }
9893
9894 static int
9895 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9896 {
9897   unformat_input_t *i = vam->input;
9898   vl_api_sw_interface_ip6_enable_disable_t *mp;
9899   u32 sw_if_index;
9900   u8 sw_if_index_set = 0;
9901   u8 enable = 0;
9902   int ret;
9903
9904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9905     {
9906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9907         sw_if_index_set = 1;
9908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9909         sw_if_index_set = 1;
9910       else if (unformat (i, "enable"))
9911         enable = 1;
9912       else if (unformat (i, "disable"))
9913         enable = 0;
9914       else
9915         {
9916           clib_warning ("parse error '%U'", format_unformat_error, i);
9917           return -99;
9918         }
9919     }
9920
9921   if (sw_if_index_set == 0)
9922     {
9923       errmsg ("missing interface name or sw_if_index");
9924       return -99;
9925     }
9926
9927   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9928
9929   mp->sw_if_index = ntohl (sw_if_index);
9930   mp->enable = enable;
9931
9932   S (mp);
9933   W (ret);
9934   return ret;
9935 }
9936
9937 static int
9938 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9939 {
9940   unformat_input_t *i = vam->input;
9941   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9942   u32 sw_if_index;
9943   u8 sw_if_index_set = 0;
9944   u8 v6_address_set = 0;
9945   ip6_address_t v6address;
9946   int ret;
9947
9948   /* Parse args required to build the message */
9949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9950     {
9951       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9952         sw_if_index_set = 1;
9953       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9954         sw_if_index_set = 1;
9955       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9956         v6_address_set = 1;
9957       else
9958         break;
9959     }
9960
9961   if (sw_if_index_set == 0)
9962     {
9963       errmsg ("missing interface name or sw_if_index");
9964       return -99;
9965     }
9966   if (!v6_address_set)
9967     {
9968       errmsg ("no address set");
9969       return -99;
9970     }
9971
9972   /* Construct the API message */
9973   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9974
9975   mp->sw_if_index = ntohl (sw_if_index);
9976   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9977
9978   /* send it... */
9979   S (mp);
9980
9981   /* Wait for a reply, return good/bad news  */
9982   W (ret);
9983   return ret;
9984 }
9985
9986 static int
9987 api_ip6nd_proxy_add_del (vat_main_t * vam)
9988 {
9989   unformat_input_t *i = vam->input;
9990   vl_api_ip6nd_proxy_add_del_t *mp;
9991   u32 sw_if_index = ~0;
9992   u8 v6_address_set = 0;
9993   ip6_address_t v6address;
9994   u8 is_del = 0;
9995   int ret;
9996
9997   /* Parse args required to build the message */
9998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9999     {
10000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10001         ;
10002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10003         ;
10004       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10005         v6_address_set = 1;
10006       if (unformat (i, "del"))
10007         is_del = 1;
10008       else
10009         {
10010           clib_warning ("parse error '%U'", format_unformat_error, i);
10011           return -99;
10012         }
10013     }
10014
10015   if (sw_if_index == ~0)
10016     {
10017       errmsg ("missing interface name or sw_if_index");
10018       return -99;
10019     }
10020   if (!v6_address_set)
10021     {
10022       errmsg ("no address set");
10023       return -99;
10024     }
10025
10026   /* Construct the API message */
10027   M (IP6ND_PROXY_ADD_DEL, mp);
10028
10029   mp->is_del = is_del;
10030   mp->sw_if_index = ntohl (sw_if_index);
10031   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10032
10033   /* send it... */
10034   S (mp);
10035
10036   /* Wait for a reply, return good/bad news  */
10037   W (ret);
10038   return ret;
10039 }
10040
10041 static int
10042 api_ip6nd_proxy_dump (vat_main_t * vam)
10043 {
10044   vl_api_ip6nd_proxy_dump_t *mp;
10045   vl_api_control_ping_t *mp_ping;
10046   int ret;
10047
10048   M (IP6ND_PROXY_DUMP, mp);
10049
10050   S (mp);
10051
10052   /* Use a control ping for synchronization */
10053   MPING (CONTROL_PING, mp_ping);
10054   S (mp_ping);
10055
10056   W (ret);
10057   return ret;
10058 }
10059
10060 static void vl_api_ip6nd_proxy_details_t_handler
10061   (vl_api_ip6nd_proxy_details_t * mp)
10062 {
10063   vat_main_t *vam = &vat_main;
10064
10065   print (vam->ofp, "host %U sw_if_index %d",
10066          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10067 }
10068
10069 static void vl_api_ip6nd_proxy_details_t_handler_json
10070   (vl_api_ip6nd_proxy_details_t * mp)
10071 {
10072   vat_main_t *vam = &vat_main;
10073   struct in6_addr ip6;
10074   vat_json_node_t *node = NULL;
10075
10076   if (VAT_JSON_ARRAY != vam->json_tree.type)
10077     {
10078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10079       vat_json_init_array (&vam->json_tree);
10080     }
10081   node = vat_json_array_add (&vam->json_tree);
10082
10083   vat_json_init_object (node);
10084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10085
10086   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10087   vat_json_object_add_ip6 (node, "host", ip6);
10088 }
10089
10090 static int
10091 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10092 {
10093   unformat_input_t *i = vam->input;
10094   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10095   u32 sw_if_index;
10096   u8 sw_if_index_set = 0;
10097   u32 address_length = 0;
10098   u8 v6_address_set = 0;
10099   ip6_address_t v6address;
10100   u8 use_default = 0;
10101   u8 no_advertise = 0;
10102   u8 off_link = 0;
10103   u8 no_autoconfig = 0;
10104   u8 no_onlink = 0;
10105   u8 is_no = 0;
10106   u32 val_lifetime = 0;
10107   u32 pref_lifetime = 0;
10108   int ret;
10109
10110   /* Parse args required to build the message */
10111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10112     {
10113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10114         sw_if_index_set = 1;
10115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10116         sw_if_index_set = 1;
10117       else if (unformat (i, "%U/%d",
10118                          unformat_ip6_address, &v6address, &address_length))
10119         v6_address_set = 1;
10120       else if (unformat (i, "val_life %d", &val_lifetime))
10121         ;
10122       else if (unformat (i, "pref_life %d", &pref_lifetime))
10123         ;
10124       else if (unformat (i, "def"))
10125         use_default = 1;
10126       else if (unformat (i, "noadv"))
10127         no_advertise = 1;
10128       else if (unformat (i, "offl"))
10129         off_link = 1;
10130       else if (unformat (i, "noauto"))
10131         no_autoconfig = 1;
10132       else if (unformat (i, "nolink"))
10133         no_onlink = 1;
10134       else if (unformat (i, "isno"))
10135         is_no = 1;
10136       else
10137         {
10138           clib_warning ("parse error '%U'", format_unformat_error, i);
10139           return -99;
10140         }
10141     }
10142
10143   if (sw_if_index_set == 0)
10144     {
10145       errmsg ("missing interface name or sw_if_index");
10146       return -99;
10147     }
10148   if (!v6_address_set)
10149     {
10150       errmsg ("no address set");
10151       return -99;
10152     }
10153
10154   /* Construct the API message */
10155   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10156
10157   mp->sw_if_index = ntohl (sw_if_index);
10158   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10159   mp->address_length = address_length;
10160   mp->use_default = use_default;
10161   mp->no_advertise = no_advertise;
10162   mp->off_link = off_link;
10163   mp->no_autoconfig = no_autoconfig;
10164   mp->no_onlink = no_onlink;
10165   mp->is_no = is_no;
10166   mp->val_lifetime = ntohl (val_lifetime);
10167   mp->pref_lifetime = ntohl (pref_lifetime);
10168
10169   /* send it... */
10170   S (mp);
10171
10172   /* Wait for a reply, return good/bad news  */
10173   W (ret);
10174   return ret;
10175 }
10176
10177 static int
10178 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10179 {
10180   unformat_input_t *i = vam->input;
10181   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10182   u32 sw_if_index;
10183   u8 sw_if_index_set = 0;
10184   u8 suppress = 0;
10185   u8 managed = 0;
10186   u8 other = 0;
10187   u8 ll_option = 0;
10188   u8 send_unicast = 0;
10189   u8 cease = 0;
10190   u8 is_no = 0;
10191   u8 default_router = 0;
10192   u32 max_interval = 0;
10193   u32 min_interval = 0;
10194   u32 lifetime = 0;
10195   u32 initial_count = 0;
10196   u32 initial_interval = 0;
10197   int ret;
10198
10199
10200   /* Parse args required to build the message */
10201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10202     {
10203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10204         sw_if_index_set = 1;
10205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10206         sw_if_index_set = 1;
10207       else if (unformat (i, "maxint %d", &max_interval))
10208         ;
10209       else if (unformat (i, "minint %d", &min_interval))
10210         ;
10211       else if (unformat (i, "life %d", &lifetime))
10212         ;
10213       else if (unformat (i, "count %d", &initial_count))
10214         ;
10215       else if (unformat (i, "interval %d", &initial_interval))
10216         ;
10217       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10218         suppress = 1;
10219       else if (unformat (i, "managed"))
10220         managed = 1;
10221       else if (unformat (i, "other"))
10222         other = 1;
10223       else if (unformat (i, "ll"))
10224         ll_option = 1;
10225       else if (unformat (i, "send"))
10226         send_unicast = 1;
10227       else if (unformat (i, "cease"))
10228         cease = 1;
10229       else if (unformat (i, "isno"))
10230         is_no = 1;
10231       else if (unformat (i, "def"))
10232         default_router = 1;
10233       else
10234         {
10235           clib_warning ("parse error '%U'", format_unformat_error, i);
10236           return -99;
10237         }
10238     }
10239
10240   if (sw_if_index_set == 0)
10241     {
10242       errmsg ("missing interface name or sw_if_index");
10243       return -99;
10244     }
10245
10246   /* Construct the API message */
10247   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10248
10249   mp->sw_if_index = ntohl (sw_if_index);
10250   mp->max_interval = ntohl (max_interval);
10251   mp->min_interval = ntohl (min_interval);
10252   mp->lifetime = ntohl (lifetime);
10253   mp->initial_count = ntohl (initial_count);
10254   mp->initial_interval = ntohl (initial_interval);
10255   mp->suppress = suppress;
10256   mp->managed = managed;
10257   mp->other = other;
10258   mp->ll_option = ll_option;
10259   mp->send_unicast = send_unicast;
10260   mp->cease = cease;
10261   mp->is_no = is_no;
10262   mp->default_router = default_router;
10263
10264   /* send it... */
10265   S (mp);
10266
10267   /* Wait for a reply, return good/bad news  */
10268   W (ret);
10269   return ret;
10270 }
10271
10272 static int
10273 api_set_arp_neighbor_limit (vat_main_t * vam)
10274 {
10275   unformat_input_t *i = vam->input;
10276   vl_api_set_arp_neighbor_limit_t *mp;
10277   u32 arp_nbr_limit;
10278   u8 limit_set = 0;
10279   u8 is_ipv6 = 0;
10280   int ret;
10281
10282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10283     {
10284       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10285         limit_set = 1;
10286       else if (unformat (i, "ipv6"))
10287         is_ipv6 = 1;
10288       else
10289         {
10290           clib_warning ("parse error '%U'", format_unformat_error, i);
10291           return -99;
10292         }
10293     }
10294
10295   if (limit_set == 0)
10296     {
10297       errmsg ("missing limit value");
10298       return -99;
10299     }
10300
10301   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10302
10303   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10304   mp->is_ipv6 = is_ipv6;
10305
10306   S (mp);
10307   W (ret);
10308   return ret;
10309 }
10310
10311 static int
10312 api_l2_patch_add_del (vat_main_t * vam)
10313 {
10314   unformat_input_t *i = vam->input;
10315   vl_api_l2_patch_add_del_t *mp;
10316   u32 rx_sw_if_index;
10317   u8 rx_sw_if_index_set = 0;
10318   u32 tx_sw_if_index;
10319   u8 tx_sw_if_index_set = 0;
10320   u8 is_add = 1;
10321   int ret;
10322
10323   /* Parse args required to build the message */
10324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10325     {
10326       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10327         rx_sw_if_index_set = 1;
10328       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10329         tx_sw_if_index_set = 1;
10330       else if (unformat (i, "rx"))
10331         {
10332           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10333             {
10334               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10335                             &rx_sw_if_index))
10336                 rx_sw_if_index_set = 1;
10337             }
10338           else
10339             break;
10340         }
10341       else if (unformat (i, "tx"))
10342         {
10343           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10344             {
10345               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10346                             &tx_sw_if_index))
10347                 tx_sw_if_index_set = 1;
10348             }
10349           else
10350             break;
10351         }
10352       else if (unformat (i, "del"))
10353         is_add = 0;
10354       else
10355         break;
10356     }
10357
10358   if (rx_sw_if_index_set == 0)
10359     {
10360       errmsg ("missing rx interface name or rx_sw_if_index");
10361       return -99;
10362     }
10363
10364   if (tx_sw_if_index_set == 0)
10365     {
10366       errmsg ("missing tx interface name or tx_sw_if_index");
10367       return -99;
10368     }
10369
10370   M (L2_PATCH_ADD_DEL, mp);
10371
10372   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10373   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10374   mp->is_add = is_add;
10375
10376   S (mp);
10377   W (ret);
10378   return ret;
10379 }
10380
10381 u8 is_del;
10382 u8 localsid_addr[16];
10383 u8 end_psp;
10384 u8 behavior;
10385 u32 sw_if_index;
10386 u32 vlan_index;
10387 u32 fib_table;
10388 u8 nh_addr[16];
10389
10390 static int
10391 api_sr_localsid_add_del (vat_main_t * vam)
10392 {
10393   unformat_input_t *i = vam->input;
10394   vl_api_sr_localsid_add_del_t *mp;
10395
10396   u8 is_del;
10397   ip6_address_t localsid;
10398   u8 end_psp = 0;
10399   u8 behavior = ~0;
10400   u32 sw_if_index;
10401   u32 fib_table = ~(u32) 0;
10402   ip6_address_t next_hop;
10403
10404   bool nexthop_set = 0;
10405
10406   int ret;
10407
10408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (i, "del"))
10411         is_del = 1;
10412       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10413       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10414         nexthop_set = 1;
10415       else if (unformat (i, "behavior %u", &behavior));
10416       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10417       else if (unformat (i, "fib-table %u", &fib_table));
10418       else if (unformat (i, "end.psp %u", &behavior));
10419       else
10420         break;
10421     }
10422
10423   M (SR_LOCALSID_ADD_DEL, mp);
10424
10425   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10426   if (nexthop_set)
10427     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10428   mp->behavior = behavior;
10429   mp->sw_if_index = ntohl (sw_if_index);
10430   mp->fib_table = ntohl (fib_table);
10431   mp->end_psp = end_psp;
10432   mp->is_del = is_del;
10433
10434   S (mp);
10435   W (ret);
10436   return ret;
10437 }
10438
10439 static int
10440 api_ioam_enable (vat_main_t * vam)
10441 {
10442   unformat_input_t *input = vam->input;
10443   vl_api_ioam_enable_t *mp;
10444   u32 id = 0;
10445   int has_trace_option = 0;
10446   int has_pot_option = 0;
10447   int has_seqno_option = 0;
10448   int has_analyse_option = 0;
10449   int ret;
10450
10451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10452     {
10453       if (unformat (input, "trace"))
10454         has_trace_option = 1;
10455       else if (unformat (input, "pot"))
10456         has_pot_option = 1;
10457       else if (unformat (input, "seqno"))
10458         has_seqno_option = 1;
10459       else if (unformat (input, "analyse"))
10460         has_analyse_option = 1;
10461       else
10462         break;
10463     }
10464   M (IOAM_ENABLE, mp);
10465   mp->id = htons (id);
10466   mp->seqno = has_seqno_option;
10467   mp->analyse = has_analyse_option;
10468   mp->pot_enable = has_pot_option;
10469   mp->trace_enable = has_trace_option;
10470
10471   S (mp);
10472   W (ret);
10473   return ret;
10474 }
10475
10476
10477 static int
10478 api_ioam_disable (vat_main_t * vam)
10479 {
10480   vl_api_ioam_disable_t *mp;
10481   int ret;
10482
10483   M (IOAM_DISABLE, mp);
10484   S (mp);
10485   W (ret);
10486   return ret;
10487 }
10488
10489 #define foreach_tcp_proto_field                 \
10490 _(src_port)                                     \
10491 _(dst_port)
10492
10493 #define foreach_udp_proto_field                 \
10494 _(src_port)                                     \
10495 _(dst_port)
10496
10497 #define foreach_ip4_proto_field                 \
10498 _(src_address)                                  \
10499 _(dst_address)                                  \
10500 _(tos)                                          \
10501 _(length)                                       \
10502 _(fragment_id)                                  \
10503 _(ttl)                                          \
10504 _(protocol)                                     \
10505 _(checksum)
10506
10507 typedef struct
10508 {
10509   u16 src_port, dst_port;
10510 } tcpudp_header_t;
10511
10512 #if VPP_API_TEST_BUILTIN == 0
10513 uword
10514 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10515 {
10516   u8 **maskp = va_arg (*args, u8 **);
10517   u8 *mask = 0;
10518   u8 found_something = 0;
10519   tcp_header_t *tcp;
10520
10521 #define _(a) u8 a=0;
10522   foreach_tcp_proto_field;
10523 #undef _
10524
10525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10526     {
10527       if (0);
10528 #define _(a) else if (unformat (input, #a)) a=1;
10529       foreach_tcp_proto_field
10530 #undef _
10531         else
10532         break;
10533     }
10534
10535 #define _(a) found_something += a;
10536   foreach_tcp_proto_field;
10537 #undef _
10538
10539   if (found_something == 0)
10540     return 0;
10541
10542   vec_validate (mask, sizeof (*tcp) - 1);
10543
10544   tcp = (tcp_header_t *) mask;
10545
10546 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10547   foreach_tcp_proto_field;
10548 #undef _
10549
10550   *maskp = mask;
10551   return 1;
10552 }
10553
10554 uword
10555 unformat_udp_mask (unformat_input_t * input, va_list * args)
10556 {
10557   u8 **maskp = va_arg (*args, u8 **);
10558   u8 *mask = 0;
10559   u8 found_something = 0;
10560   udp_header_t *udp;
10561
10562 #define _(a) u8 a=0;
10563   foreach_udp_proto_field;
10564 #undef _
10565
10566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10567     {
10568       if (0);
10569 #define _(a) else if (unformat (input, #a)) a=1;
10570       foreach_udp_proto_field
10571 #undef _
10572         else
10573         break;
10574     }
10575
10576 #define _(a) found_something += a;
10577   foreach_udp_proto_field;
10578 #undef _
10579
10580   if (found_something == 0)
10581     return 0;
10582
10583   vec_validate (mask, sizeof (*udp) - 1);
10584
10585   udp = (udp_header_t *) mask;
10586
10587 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10588   foreach_udp_proto_field;
10589 #undef _
10590
10591   *maskp = mask;
10592   return 1;
10593 }
10594
10595 uword
10596 unformat_l4_mask (unformat_input_t * input, va_list * args)
10597 {
10598   u8 **maskp = va_arg (*args, u8 **);
10599   u16 src_port = 0, dst_port = 0;
10600   tcpudp_header_t *tcpudp;
10601
10602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10603     {
10604       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10605         return 1;
10606       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10607         return 1;
10608       else if (unformat (input, "src_port"))
10609         src_port = 0xFFFF;
10610       else if (unformat (input, "dst_port"))
10611         dst_port = 0xFFFF;
10612       else
10613         return 0;
10614     }
10615
10616   if (!src_port && !dst_port)
10617     return 0;
10618
10619   u8 *mask = 0;
10620   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10621
10622   tcpudp = (tcpudp_header_t *) mask;
10623   tcpudp->src_port = src_port;
10624   tcpudp->dst_port = dst_port;
10625
10626   *maskp = mask;
10627
10628   return 1;
10629 }
10630
10631 uword
10632 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10633 {
10634   u8 **maskp = va_arg (*args, u8 **);
10635   u8 *mask = 0;
10636   u8 found_something = 0;
10637   ip4_header_t *ip;
10638
10639 #define _(a) u8 a=0;
10640   foreach_ip4_proto_field;
10641 #undef _
10642   u8 version = 0;
10643   u8 hdr_length = 0;
10644
10645
10646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10647     {
10648       if (unformat (input, "version"))
10649         version = 1;
10650       else if (unformat (input, "hdr_length"))
10651         hdr_length = 1;
10652       else if (unformat (input, "src"))
10653         src_address = 1;
10654       else if (unformat (input, "dst"))
10655         dst_address = 1;
10656       else if (unformat (input, "proto"))
10657         protocol = 1;
10658
10659 #define _(a) else if (unformat (input, #a)) a=1;
10660       foreach_ip4_proto_field
10661 #undef _
10662         else
10663         break;
10664     }
10665
10666 #define _(a) found_something += a;
10667   foreach_ip4_proto_field;
10668 #undef _
10669
10670   if (found_something == 0)
10671     return 0;
10672
10673   vec_validate (mask, sizeof (*ip) - 1);
10674
10675   ip = (ip4_header_t *) mask;
10676
10677 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10678   foreach_ip4_proto_field;
10679 #undef _
10680
10681   ip->ip_version_and_header_length = 0;
10682
10683   if (version)
10684     ip->ip_version_and_header_length |= 0xF0;
10685
10686   if (hdr_length)
10687     ip->ip_version_and_header_length |= 0x0F;
10688
10689   *maskp = mask;
10690   return 1;
10691 }
10692
10693 #define foreach_ip6_proto_field                 \
10694 _(src_address)                                  \
10695 _(dst_address)                                  \
10696 _(payload_length)                               \
10697 _(hop_limit)                                    \
10698 _(protocol)
10699
10700 uword
10701 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10702 {
10703   u8 **maskp = va_arg (*args, u8 **);
10704   u8 *mask = 0;
10705   u8 found_something = 0;
10706   ip6_header_t *ip;
10707   u32 ip_version_traffic_class_and_flow_label;
10708
10709 #define _(a) u8 a=0;
10710   foreach_ip6_proto_field;
10711 #undef _
10712   u8 version = 0;
10713   u8 traffic_class = 0;
10714   u8 flow_label = 0;
10715
10716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10717     {
10718       if (unformat (input, "version"))
10719         version = 1;
10720       else if (unformat (input, "traffic-class"))
10721         traffic_class = 1;
10722       else if (unformat (input, "flow-label"))
10723         flow_label = 1;
10724       else if (unformat (input, "src"))
10725         src_address = 1;
10726       else if (unformat (input, "dst"))
10727         dst_address = 1;
10728       else if (unformat (input, "proto"))
10729         protocol = 1;
10730
10731 #define _(a) else if (unformat (input, #a)) a=1;
10732       foreach_ip6_proto_field
10733 #undef _
10734         else
10735         break;
10736     }
10737
10738 #define _(a) found_something += a;
10739   foreach_ip6_proto_field;
10740 #undef _
10741
10742   if (found_something == 0)
10743     return 0;
10744
10745   vec_validate (mask, sizeof (*ip) - 1);
10746
10747   ip = (ip6_header_t *) mask;
10748
10749 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10750   foreach_ip6_proto_field;
10751 #undef _
10752
10753   ip_version_traffic_class_and_flow_label = 0;
10754
10755   if (version)
10756     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10757
10758   if (traffic_class)
10759     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10760
10761   if (flow_label)
10762     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10763
10764   ip->ip_version_traffic_class_and_flow_label =
10765     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10766
10767   *maskp = mask;
10768   return 1;
10769 }
10770
10771 uword
10772 unformat_l3_mask (unformat_input_t * input, va_list * args)
10773 {
10774   u8 **maskp = va_arg (*args, u8 **);
10775
10776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10777     {
10778       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10779         return 1;
10780       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10781         return 1;
10782       else
10783         break;
10784     }
10785   return 0;
10786 }
10787
10788 uword
10789 unformat_l2_mask (unformat_input_t * input, va_list * args)
10790 {
10791   u8 **maskp = va_arg (*args, u8 **);
10792   u8 *mask = 0;
10793   u8 src = 0;
10794   u8 dst = 0;
10795   u8 proto = 0;
10796   u8 tag1 = 0;
10797   u8 tag2 = 0;
10798   u8 ignore_tag1 = 0;
10799   u8 ignore_tag2 = 0;
10800   u8 cos1 = 0;
10801   u8 cos2 = 0;
10802   u8 dot1q = 0;
10803   u8 dot1ad = 0;
10804   int len = 14;
10805
10806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (input, "src"))
10809         src = 1;
10810       else if (unformat (input, "dst"))
10811         dst = 1;
10812       else if (unformat (input, "proto"))
10813         proto = 1;
10814       else if (unformat (input, "tag1"))
10815         tag1 = 1;
10816       else if (unformat (input, "tag2"))
10817         tag2 = 1;
10818       else if (unformat (input, "ignore-tag1"))
10819         ignore_tag1 = 1;
10820       else if (unformat (input, "ignore-tag2"))
10821         ignore_tag2 = 1;
10822       else if (unformat (input, "cos1"))
10823         cos1 = 1;
10824       else if (unformat (input, "cos2"))
10825         cos2 = 1;
10826       else if (unformat (input, "dot1q"))
10827         dot1q = 1;
10828       else if (unformat (input, "dot1ad"))
10829         dot1ad = 1;
10830       else
10831         break;
10832     }
10833   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10834        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10835     return 0;
10836
10837   if (tag1 || ignore_tag1 || cos1 || dot1q)
10838     len = 18;
10839   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10840     len = 22;
10841
10842   vec_validate (mask, len - 1);
10843
10844   if (dst)
10845     memset (mask, 0xff, 6);
10846
10847   if (src)
10848     memset (mask + 6, 0xff, 6);
10849
10850   if (tag2 || dot1ad)
10851     {
10852       /* inner vlan tag */
10853       if (tag2)
10854         {
10855           mask[19] = 0xff;
10856           mask[18] = 0x0f;
10857         }
10858       if (cos2)
10859         mask[18] |= 0xe0;
10860       if (proto)
10861         mask[21] = mask[20] = 0xff;
10862       if (tag1)
10863         {
10864           mask[15] = 0xff;
10865           mask[14] = 0x0f;
10866         }
10867       if (cos1)
10868         mask[14] |= 0xe0;
10869       *maskp = mask;
10870       return 1;
10871     }
10872   if (tag1 | dot1q)
10873     {
10874       if (tag1)
10875         {
10876           mask[15] = 0xff;
10877           mask[14] = 0x0f;
10878         }
10879       if (cos1)
10880         mask[14] |= 0xe0;
10881       if (proto)
10882         mask[16] = mask[17] = 0xff;
10883
10884       *maskp = mask;
10885       return 1;
10886     }
10887   if (cos2)
10888     mask[18] |= 0xe0;
10889   if (cos1)
10890     mask[14] |= 0xe0;
10891   if (proto)
10892     mask[12] = mask[13] = 0xff;
10893
10894   *maskp = mask;
10895   return 1;
10896 }
10897
10898 uword
10899 unformat_classify_mask (unformat_input_t * input, va_list * args)
10900 {
10901   u8 **maskp = va_arg (*args, u8 **);
10902   u32 *skipp = va_arg (*args, u32 *);
10903   u32 *matchp = va_arg (*args, u32 *);
10904   u32 match;
10905   u8 *mask = 0;
10906   u8 *l2 = 0;
10907   u8 *l3 = 0;
10908   u8 *l4 = 0;
10909   int i;
10910
10911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10912     {
10913       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10914         ;
10915       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10916         ;
10917       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10918         ;
10919       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10920         ;
10921       else
10922         break;
10923     }
10924
10925   if (l4 && !l3)
10926     {
10927       vec_free (mask);
10928       vec_free (l2);
10929       vec_free (l4);
10930       return 0;
10931     }
10932
10933   if (mask || l2 || l3 || l4)
10934     {
10935       if (l2 || l3 || l4)
10936         {
10937           /* "With a free Ethernet header in every package" */
10938           if (l2 == 0)
10939             vec_validate (l2, 13);
10940           mask = l2;
10941           if (vec_len (l3))
10942             {
10943               vec_append (mask, l3);
10944               vec_free (l3);
10945             }
10946           if (vec_len (l4))
10947             {
10948               vec_append (mask, l4);
10949               vec_free (l4);
10950             }
10951         }
10952
10953       /* Scan forward looking for the first significant mask octet */
10954       for (i = 0; i < vec_len (mask); i++)
10955         if (mask[i])
10956           break;
10957
10958       /* compute (skip, match) params */
10959       *skipp = i / sizeof (u32x4);
10960       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10961
10962       /* Pad mask to an even multiple of the vector size */
10963       while (vec_len (mask) % sizeof (u32x4))
10964         vec_add1 (mask, 0);
10965
10966       match = vec_len (mask) / sizeof (u32x4);
10967
10968       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10969         {
10970           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10971           if (*tmp || *(tmp + 1))
10972             break;
10973           match--;
10974         }
10975       if (match == 0)
10976         clib_warning ("BUG: match 0");
10977
10978       _vec_len (mask) = match * sizeof (u32x4);
10979
10980       *matchp = match;
10981       *maskp = mask;
10982
10983       return 1;
10984     }
10985
10986   return 0;
10987 }
10988 #endif /* VPP_API_TEST_BUILTIN */
10989
10990 #define foreach_l2_next                         \
10991 _(drop, DROP)                                   \
10992 _(ethernet, ETHERNET_INPUT)                     \
10993 _(ip4, IP4_INPUT)                               \
10994 _(ip6, IP6_INPUT)
10995
10996 uword
10997 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10998 {
10999   u32 *miss_next_indexp = va_arg (*args, u32 *);
11000   u32 next_index = 0;
11001   u32 tmp;
11002
11003 #define _(n,N) \
11004   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11005   foreach_l2_next;
11006 #undef _
11007
11008   if (unformat (input, "%d", &tmp))
11009     {
11010       next_index = tmp;
11011       goto out;
11012     }
11013
11014   return 0;
11015
11016 out:
11017   *miss_next_indexp = next_index;
11018   return 1;
11019 }
11020
11021 #define foreach_ip_next                         \
11022 _(drop, DROP)                                   \
11023 _(local, LOCAL)                                 \
11024 _(rewrite, REWRITE)
11025
11026 uword
11027 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11028 {
11029   u32 *miss_next_indexp = va_arg (*args, u32 *);
11030   u32 next_index = 0;
11031   u32 tmp;
11032
11033 #define _(n,N) \
11034   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11035   foreach_ip_next;
11036 #undef _
11037
11038   if (unformat (input, "%d", &tmp))
11039     {
11040       next_index = tmp;
11041       goto out;
11042     }
11043
11044   return 0;
11045
11046 out:
11047   *miss_next_indexp = next_index;
11048   return 1;
11049 }
11050
11051 #define foreach_acl_next                        \
11052 _(deny, DENY)
11053
11054 uword
11055 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11056 {
11057   u32 *miss_next_indexp = va_arg (*args, u32 *);
11058   u32 next_index = 0;
11059   u32 tmp;
11060
11061 #define _(n,N) \
11062   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11063   foreach_acl_next;
11064 #undef _
11065
11066   if (unformat (input, "permit"))
11067     {
11068       next_index = ~0;
11069       goto out;
11070     }
11071   else if (unformat (input, "%d", &tmp))
11072     {
11073       next_index = tmp;
11074       goto out;
11075     }
11076
11077   return 0;
11078
11079 out:
11080   *miss_next_indexp = next_index;
11081   return 1;
11082 }
11083
11084 uword
11085 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11086 {
11087   u32 *r = va_arg (*args, u32 *);
11088
11089   if (unformat (input, "conform-color"))
11090     *r = POLICE_CONFORM;
11091   else if (unformat (input, "exceed-color"))
11092     *r = POLICE_EXCEED;
11093   else
11094     return 0;
11095
11096   return 1;
11097 }
11098
11099 static int
11100 api_classify_add_del_table (vat_main_t * vam)
11101 {
11102   unformat_input_t *i = vam->input;
11103   vl_api_classify_add_del_table_t *mp;
11104
11105   u32 nbuckets = 2;
11106   u32 skip = ~0;
11107   u32 match = ~0;
11108   int is_add = 1;
11109   int del_chain = 0;
11110   u32 table_index = ~0;
11111   u32 next_table_index = ~0;
11112   u32 miss_next_index = ~0;
11113   u32 memory_size = 32 << 20;
11114   u8 *mask = 0;
11115   u32 current_data_flag = 0;
11116   int current_data_offset = 0;
11117   int ret;
11118
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "del"))
11122         is_add = 0;
11123       else if (unformat (i, "del-chain"))
11124         {
11125           is_add = 0;
11126           del_chain = 1;
11127         }
11128       else if (unformat (i, "buckets %d", &nbuckets))
11129         ;
11130       else if (unformat (i, "memory_size %d", &memory_size))
11131         ;
11132       else if (unformat (i, "skip %d", &skip))
11133         ;
11134       else if (unformat (i, "match %d", &match))
11135         ;
11136       else if (unformat (i, "table %d", &table_index))
11137         ;
11138       else if (unformat (i, "mask %U", unformat_classify_mask,
11139                          &mask, &skip, &match))
11140         ;
11141       else if (unformat (i, "next-table %d", &next_table_index))
11142         ;
11143       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11144                          &miss_next_index))
11145         ;
11146       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11147                          &miss_next_index))
11148         ;
11149       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11150                          &miss_next_index))
11151         ;
11152       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11153         ;
11154       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11155         ;
11156       else
11157         break;
11158     }
11159
11160   if (is_add && mask == 0)
11161     {
11162       errmsg ("Mask required");
11163       return -99;
11164     }
11165
11166   if (is_add && skip == ~0)
11167     {
11168       errmsg ("skip count required");
11169       return -99;
11170     }
11171
11172   if (is_add && match == ~0)
11173     {
11174       errmsg ("match count required");
11175       return -99;
11176     }
11177
11178   if (!is_add && table_index == ~0)
11179     {
11180       errmsg ("table index required for delete");
11181       return -99;
11182     }
11183
11184   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11185
11186   mp->is_add = is_add;
11187   mp->del_chain = del_chain;
11188   mp->table_index = ntohl (table_index);
11189   mp->nbuckets = ntohl (nbuckets);
11190   mp->memory_size = ntohl (memory_size);
11191   mp->skip_n_vectors = ntohl (skip);
11192   mp->match_n_vectors = ntohl (match);
11193   mp->next_table_index = ntohl (next_table_index);
11194   mp->miss_next_index = ntohl (miss_next_index);
11195   mp->current_data_flag = ntohl (current_data_flag);
11196   mp->current_data_offset = ntohl (current_data_offset);
11197   clib_memcpy (mp->mask, mask, vec_len (mask));
11198
11199   vec_free (mask);
11200
11201   S (mp);
11202   W (ret);
11203   return ret;
11204 }
11205
11206 #if VPP_API_TEST_BUILTIN == 0
11207 uword
11208 unformat_l4_match (unformat_input_t * input, va_list * args)
11209 {
11210   u8 **matchp = va_arg (*args, u8 **);
11211
11212   u8 *proto_header = 0;
11213   int src_port = 0;
11214   int dst_port = 0;
11215
11216   tcpudp_header_t h;
11217
11218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11219     {
11220       if (unformat (input, "src_port %d", &src_port))
11221         ;
11222       else if (unformat (input, "dst_port %d", &dst_port))
11223         ;
11224       else
11225         return 0;
11226     }
11227
11228   h.src_port = clib_host_to_net_u16 (src_port);
11229   h.dst_port = clib_host_to_net_u16 (dst_port);
11230   vec_validate (proto_header, sizeof (h) - 1);
11231   memcpy (proto_header, &h, sizeof (h));
11232
11233   *matchp = proto_header;
11234
11235   return 1;
11236 }
11237
11238 uword
11239 unformat_ip4_match (unformat_input_t * input, va_list * args)
11240 {
11241   u8 **matchp = va_arg (*args, u8 **);
11242   u8 *match = 0;
11243   ip4_header_t *ip;
11244   int version = 0;
11245   u32 version_val;
11246   int hdr_length = 0;
11247   u32 hdr_length_val;
11248   int src = 0, dst = 0;
11249   ip4_address_t src_val, dst_val;
11250   int proto = 0;
11251   u32 proto_val;
11252   int tos = 0;
11253   u32 tos_val;
11254   int length = 0;
11255   u32 length_val;
11256   int fragment_id = 0;
11257   u32 fragment_id_val;
11258   int ttl = 0;
11259   int ttl_val;
11260   int checksum = 0;
11261   u32 checksum_val;
11262
11263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11264     {
11265       if (unformat (input, "version %d", &version_val))
11266         version = 1;
11267       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11268         hdr_length = 1;
11269       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11270         src = 1;
11271       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11272         dst = 1;
11273       else if (unformat (input, "proto %d", &proto_val))
11274         proto = 1;
11275       else if (unformat (input, "tos %d", &tos_val))
11276         tos = 1;
11277       else if (unformat (input, "length %d", &length_val))
11278         length = 1;
11279       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11280         fragment_id = 1;
11281       else if (unformat (input, "ttl %d", &ttl_val))
11282         ttl = 1;
11283       else if (unformat (input, "checksum %d", &checksum_val))
11284         checksum = 1;
11285       else
11286         break;
11287     }
11288
11289   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11290       + ttl + checksum == 0)
11291     return 0;
11292
11293   /*
11294    * Aligned because we use the real comparison functions
11295    */
11296   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11297
11298   ip = (ip4_header_t *) match;
11299
11300   /* These are realistically matched in practice */
11301   if (src)
11302     ip->src_address.as_u32 = src_val.as_u32;
11303
11304   if (dst)
11305     ip->dst_address.as_u32 = dst_val.as_u32;
11306
11307   if (proto)
11308     ip->protocol = proto_val;
11309
11310
11311   /* These are not, but they're included for completeness */
11312   if (version)
11313     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11314
11315   if (hdr_length)
11316     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11317
11318   if (tos)
11319     ip->tos = tos_val;
11320
11321   if (length)
11322     ip->length = clib_host_to_net_u16 (length_val);
11323
11324   if (ttl)
11325     ip->ttl = ttl_val;
11326
11327   if (checksum)
11328     ip->checksum = clib_host_to_net_u16 (checksum_val);
11329
11330   *matchp = match;
11331   return 1;
11332 }
11333
11334 uword
11335 unformat_ip6_match (unformat_input_t * input, va_list * args)
11336 {
11337   u8 **matchp = va_arg (*args, u8 **);
11338   u8 *match = 0;
11339   ip6_header_t *ip;
11340   int version = 0;
11341   u32 version_val;
11342   u8 traffic_class = 0;
11343   u32 traffic_class_val = 0;
11344   u8 flow_label = 0;
11345   u8 flow_label_val;
11346   int src = 0, dst = 0;
11347   ip6_address_t src_val, dst_val;
11348   int proto = 0;
11349   u32 proto_val;
11350   int payload_length = 0;
11351   u32 payload_length_val;
11352   int hop_limit = 0;
11353   int hop_limit_val;
11354   u32 ip_version_traffic_class_and_flow_label;
11355
11356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11357     {
11358       if (unformat (input, "version %d", &version_val))
11359         version = 1;
11360       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11361         traffic_class = 1;
11362       else if (unformat (input, "flow_label %d", &flow_label_val))
11363         flow_label = 1;
11364       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11365         src = 1;
11366       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11367         dst = 1;
11368       else if (unformat (input, "proto %d", &proto_val))
11369         proto = 1;
11370       else if (unformat (input, "payload_length %d", &payload_length_val))
11371         payload_length = 1;
11372       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11373         hop_limit = 1;
11374       else
11375         break;
11376     }
11377
11378   if (version + traffic_class + flow_label + src + dst + proto +
11379       payload_length + hop_limit == 0)
11380     return 0;
11381
11382   /*
11383    * Aligned because we use the real comparison functions
11384    */
11385   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11386
11387   ip = (ip6_header_t *) match;
11388
11389   if (src)
11390     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11391
11392   if (dst)
11393     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11394
11395   if (proto)
11396     ip->protocol = proto_val;
11397
11398   ip_version_traffic_class_and_flow_label = 0;
11399
11400   if (version)
11401     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11402
11403   if (traffic_class)
11404     ip_version_traffic_class_and_flow_label |=
11405       (traffic_class_val & 0xFF) << 20;
11406
11407   if (flow_label)
11408     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11409
11410   ip->ip_version_traffic_class_and_flow_label =
11411     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11412
11413   if (payload_length)
11414     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11415
11416   if (hop_limit)
11417     ip->hop_limit = hop_limit_val;
11418
11419   *matchp = match;
11420   return 1;
11421 }
11422
11423 uword
11424 unformat_l3_match (unformat_input_t * input, va_list * args)
11425 {
11426   u8 **matchp = va_arg (*args, u8 **);
11427
11428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11429     {
11430       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11431         return 1;
11432       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11433         return 1;
11434       else
11435         break;
11436     }
11437   return 0;
11438 }
11439
11440 uword
11441 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11442 {
11443   u8 *tagp = va_arg (*args, u8 *);
11444   u32 tag;
11445
11446   if (unformat (input, "%d", &tag))
11447     {
11448       tagp[0] = (tag >> 8) & 0x0F;
11449       tagp[1] = tag & 0xFF;
11450       return 1;
11451     }
11452
11453   return 0;
11454 }
11455
11456 uword
11457 unformat_l2_match (unformat_input_t * input, va_list * args)
11458 {
11459   u8 **matchp = va_arg (*args, u8 **);
11460   u8 *match = 0;
11461   u8 src = 0;
11462   u8 src_val[6];
11463   u8 dst = 0;
11464   u8 dst_val[6];
11465   u8 proto = 0;
11466   u16 proto_val;
11467   u8 tag1 = 0;
11468   u8 tag1_val[2];
11469   u8 tag2 = 0;
11470   u8 tag2_val[2];
11471   int len = 14;
11472   u8 ignore_tag1 = 0;
11473   u8 ignore_tag2 = 0;
11474   u8 cos1 = 0;
11475   u8 cos2 = 0;
11476   u32 cos1_val = 0;
11477   u32 cos2_val = 0;
11478
11479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11480     {
11481       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11482         src = 1;
11483       else
11484         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11485         dst = 1;
11486       else if (unformat (input, "proto %U",
11487                          unformat_ethernet_type_host_byte_order, &proto_val))
11488         proto = 1;
11489       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11490         tag1 = 1;
11491       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11492         tag2 = 1;
11493       else if (unformat (input, "ignore-tag1"))
11494         ignore_tag1 = 1;
11495       else if (unformat (input, "ignore-tag2"))
11496         ignore_tag2 = 1;
11497       else if (unformat (input, "cos1 %d", &cos1_val))
11498         cos1 = 1;
11499       else if (unformat (input, "cos2 %d", &cos2_val))
11500         cos2 = 1;
11501       else
11502         break;
11503     }
11504   if ((src + dst + proto + tag1 + tag2 +
11505        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11506     return 0;
11507
11508   if (tag1 || ignore_tag1 || cos1)
11509     len = 18;
11510   if (tag2 || ignore_tag2 || cos2)
11511     len = 22;
11512
11513   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11514
11515   if (dst)
11516     clib_memcpy (match, dst_val, 6);
11517
11518   if (src)
11519     clib_memcpy (match + 6, src_val, 6);
11520
11521   if (tag2)
11522     {
11523       /* inner vlan tag */
11524       match[19] = tag2_val[1];
11525       match[18] = tag2_val[0];
11526       if (cos2)
11527         match[18] |= (cos2_val & 0x7) << 5;
11528       if (proto)
11529         {
11530           match[21] = proto_val & 0xff;
11531           match[20] = proto_val >> 8;
11532         }
11533       if (tag1)
11534         {
11535           match[15] = tag1_val[1];
11536           match[14] = tag1_val[0];
11537         }
11538       if (cos1)
11539         match[14] |= (cos1_val & 0x7) << 5;
11540       *matchp = match;
11541       return 1;
11542     }
11543   if (tag1)
11544     {
11545       match[15] = tag1_val[1];
11546       match[14] = tag1_val[0];
11547       if (proto)
11548         {
11549           match[17] = proto_val & 0xff;
11550           match[16] = proto_val >> 8;
11551         }
11552       if (cos1)
11553         match[14] |= (cos1_val & 0x7) << 5;
11554
11555       *matchp = match;
11556       return 1;
11557     }
11558   if (cos2)
11559     match[18] |= (cos2_val & 0x7) << 5;
11560   if (cos1)
11561     match[14] |= (cos1_val & 0x7) << 5;
11562   if (proto)
11563     {
11564       match[13] = proto_val & 0xff;
11565       match[12] = proto_val >> 8;
11566     }
11567
11568   *matchp = match;
11569   return 1;
11570 }
11571 #endif
11572
11573 uword
11574 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11575 {
11576   u8 **matchp = va_arg (*args, u8 **);
11577   u32 skip_n_vectors = va_arg (*args, u32);
11578   u32 match_n_vectors = va_arg (*args, u32);
11579
11580   u8 *match = 0;
11581   u8 *l2 = 0;
11582   u8 *l3 = 0;
11583   u8 *l4 = 0;
11584
11585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (input, "hex %U", unformat_hex_string, &match))
11588         ;
11589       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11590         ;
11591       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11592         ;
11593       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11594         ;
11595       else
11596         break;
11597     }
11598
11599   if (l4 && !l3)
11600     {
11601       vec_free (match);
11602       vec_free (l2);
11603       vec_free (l4);
11604       return 0;
11605     }
11606
11607   if (match || l2 || l3 || l4)
11608     {
11609       if (l2 || l3 || l4)
11610         {
11611           /* "Win a free Ethernet header in every packet" */
11612           if (l2 == 0)
11613             vec_validate_aligned (l2, 13, sizeof (u32x4));
11614           match = l2;
11615           if (vec_len (l3))
11616             {
11617               vec_append_aligned (match, l3, sizeof (u32x4));
11618               vec_free (l3);
11619             }
11620           if (vec_len (l4))
11621             {
11622               vec_append_aligned (match, l4, sizeof (u32x4));
11623               vec_free (l4);
11624             }
11625         }
11626
11627       /* Make sure the vector is big enough even if key is all 0's */
11628       vec_validate_aligned
11629         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11630          sizeof (u32x4));
11631
11632       /* Set size, include skipped vectors */
11633       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11634
11635       *matchp = match;
11636
11637       return 1;
11638     }
11639
11640   return 0;
11641 }
11642
11643 static int
11644 api_classify_add_del_session (vat_main_t * vam)
11645 {
11646   unformat_input_t *i = vam->input;
11647   vl_api_classify_add_del_session_t *mp;
11648   int is_add = 1;
11649   u32 table_index = ~0;
11650   u32 hit_next_index = ~0;
11651   u32 opaque_index = ~0;
11652   u8 *match = 0;
11653   i32 advance = 0;
11654   u32 skip_n_vectors = 0;
11655   u32 match_n_vectors = 0;
11656   u32 action = 0;
11657   u32 metadata = 0;
11658   int ret;
11659
11660   /*
11661    * Warning: you have to supply skip_n and match_n
11662    * because the API client cant simply look at the classify
11663    * table object.
11664    */
11665
11666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11667     {
11668       if (unformat (i, "del"))
11669         is_add = 0;
11670       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11671                          &hit_next_index))
11672         ;
11673       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11674                          &hit_next_index))
11675         ;
11676       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11677                          &hit_next_index))
11678         ;
11679       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11680         ;
11681       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11682         ;
11683       else if (unformat (i, "opaque-index %d", &opaque_index))
11684         ;
11685       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11686         ;
11687       else if (unformat (i, "match_n %d", &match_n_vectors))
11688         ;
11689       else if (unformat (i, "match %U", api_unformat_classify_match,
11690                          &match, skip_n_vectors, match_n_vectors))
11691         ;
11692       else if (unformat (i, "advance %d", &advance))
11693         ;
11694       else if (unformat (i, "table-index %d", &table_index))
11695         ;
11696       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11697         action = 1;
11698       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11699         action = 2;
11700       else if (unformat (i, "action %d", &action))
11701         ;
11702       else if (unformat (i, "metadata %d", &metadata))
11703         ;
11704       else
11705         break;
11706     }
11707
11708   if (table_index == ~0)
11709     {
11710       errmsg ("Table index required");
11711       return -99;
11712     }
11713
11714   if (is_add && match == 0)
11715     {
11716       errmsg ("Match value required");
11717       return -99;
11718     }
11719
11720   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11721
11722   mp->is_add = is_add;
11723   mp->table_index = ntohl (table_index);
11724   mp->hit_next_index = ntohl (hit_next_index);
11725   mp->opaque_index = ntohl (opaque_index);
11726   mp->advance = ntohl (advance);
11727   mp->action = action;
11728   mp->metadata = ntohl (metadata);
11729   clib_memcpy (mp->match, match, vec_len (match));
11730   vec_free (match);
11731
11732   S (mp);
11733   W (ret);
11734   return ret;
11735 }
11736
11737 static int
11738 api_classify_set_interface_ip_table (vat_main_t * vam)
11739 {
11740   unformat_input_t *i = vam->input;
11741   vl_api_classify_set_interface_ip_table_t *mp;
11742   u32 sw_if_index;
11743   int sw_if_index_set;
11744   u32 table_index = ~0;
11745   u8 is_ipv6 = 0;
11746   int ret;
11747
11748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11749     {
11750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11751         sw_if_index_set = 1;
11752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11753         sw_if_index_set = 1;
11754       else if (unformat (i, "table %d", &table_index))
11755         ;
11756       else
11757         {
11758           clib_warning ("parse error '%U'", format_unformat_error, i);
11759           return -99;
11760         }
11761     }
11762
11763   if (sw_if_index_set == 0)
11764     {
11765       errmsg ("missing interface name or sw_if_index");
11766       return -99;
11767     }
11768
11769
11770   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11771
11772   mp->sw_if_index = ntohl (sw_if_index);
11773   mp->table_index = ntohl (table_index);
11774   mp->is_ipv6 = is_ipv6;
11775
11776   S (mp);
11777   W (ret);
11778   return ret;
11779 }
11780
11781 static int
11782 api_classify_set_interface_l2_tables (vat_main_t * vam)
11783 {
11784   unformat_input_t *i = vam->input;
11785   vl_api_classify_set_interface_l2_tables_t *mp;
11786   u32 sw_if_index;
11787   int sw_if_index_set;
11788   u32 ip4_table_index = ~0;
11789   u32 ip6_table_index = ~0;
11790   u32 other_table_index = ~0;
11791   u32 is_input = 1;
11792   int ret;
11793
11794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11795     {
11796       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11797         sw_if_index_set = 1;
11798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11799         sw_if_index_set = 1;
11800       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11801         ;
11802       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11803         ;
11804       else if (unformat (i, "other-table %d", &other_table_index))
11805         ;
11806       else if (unformat (i, "is-input %d", &is_input))
11807         ;
11808       else
11809         {
11810           clib_warning ("parse error '%U'", format_unformat_error, i);
11811           return -99;
11812         }
11813     }
11814
11815   if (sw_if_index_set == 0)
11816     {
11817       errmsg ("missing interface name or sw_if_index");
11818       return -99;
11819     }
11820
11821
11822   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11823
11824   mp->sw_if_index = ntohl (sw_if_index);
11825   mp->ip4_table_index = ntohl (ip4_table_index);
11826   mp->ip6_table_index = ntohl (ip6_table_index);
11827   mp->other_table_index = ntohl (other_table_index);
11828   mp->is_input = (u8) is_input;
11829
11830   S (mp);
11831   W (ret);
11832   return ret;
11833 }
11834
11835 static int
11836 api_set_ipfix_exporter (vat_main_t * vam)
11837 {
11838   unformat_input_t *i = vam->input;
11839   vl_api_set_ipfix_exporter_t *mp;
11840   ip4_address_t collector_address;
11841   u8 collector_address_set = 0;
11842   u32 collector_port = ~0;
11843   ip4_address_t src_address;
11844   u8 src_address_set = 0;
11845   u32 vrf_id = ~0;
11846   u32 path_mtu = ~0;
11847   u32 template_interval = ~0;
11848   u8 udp_checksum = 0;
11849   int ret;
11850
11851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11852     {
11853       if (unformat (i, "collector_address %U", unformat_ip4_address,
11854                     &collector_address))
11855         collector_address_set = 1;
11856       else if (unformat (i, "collector_port %d", &collector_port))
11857         ;
11858       else if (unformat (i, "src_address %U", unformat_ip4_address,
11859                          &src_address))
11860         src_address_set = 1;
11861       else if (unformat (i, "vrf_id %d", &vrf_id))
11862         ;
11863       else if (unformat (i, "path_mtu %d", &path_mtu))
11864         ;
11865       else if (unformat (i, "template_interval %d", &template_interval))
11866         ;
11867       else if (unformat (i, "udp_checksum"))
11868         udp_checksum = 1;
11869       else
11870         break;
11871     }
11872
11873   if (collector_address_set == 0)
11874     {
11875       errmsg ("collector_address required");
11876       return -99;
11877     }
11878
11879   if (src_address_set == 0)
11880     {
11881       errmsg ("src_address required");
11882       return -99;
11883     }
11884
11885   M (SET_IPFIX_EXPORTER, mp);
11886
11887   memcpy (mp->collector_address, collector_address.data,
11888           sizeof (collector_address.data));
11889   mp->collector_port = htons ((u16) collector_port);
11890   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11891   mp->vrf_id = htonl (vrf_id);
11892   mp->path_mtu = htonl (path_mtu);
11893   mp->template_interval = htonl (template_interval);
11894   mp->udp_checksum = udp_checksum;
11895
11896   S (mp);
11897   W (ret);
11898   return ret;
11899 }
11900
11901 static int
11902 api_set_ipfix_classify_stream (vat_main_t * vam)
11903 {
11904   unformat_input_t *i = vam->input;
11905   vl_api_set_ipfix_classify_stream_t *mp;
11906   u32 domain_id = 0;
11907   u32 src_port = UDP_DST_PORT_ipfix;
11908   int ret;
11909
11910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11911     {
11912       if (unformat (i, "domain %d", &domain_id))
11913         ;
11914       else if (unformat (i, "src_port %d", &src_port))
11915         ;
11916       else
11917         {
11918           errmsg ("unknown input `%U'", format_unformat_error, i);
11919           return -99;
11920         }
11921     }
11922
11923   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11924
11925   mp->domain_id = htonl (domain_id);
11926   mp->src_port = htons ((u16) src_port);
11927
11928   S (mp);
11929   W (ret);
11930   return ret;
11931 }
11932
11933 static int
11934 api_ipfix_classify_table_add_del (vat_main_t * vam)
11935 {
11936   unformat_input_t *i = vam->input;
11937   vl_api_ipfix_classify_table_add_del_t *mp;
11938   int is_add = -1;
11939   u32 classify_table_index = ~0;
11940   u8 ip_version = 0;
11941   u8 transport_protocol = 255;
11942   int ret;
11943
11944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (i, "add"))
11947         is_add = 1;
11948       else if (unformat (i, "del"))
11949         is_add = 0;
11950       else if (unformat (i, "table %d", &classify_table_index))
11951         ;
11952       else if (unformat (i, "ip4"))
11953         ip_version = 4;
11954       else if (unformat (i, "ip6"))
11955         ip_version = 6;
11956       else if (unformat (i, "tcp"))
11957         transport_protocol = 6;
11958       else if (unformat (i, "udp"))
11959         transport_protocol = 17;
11960       else
11961         {
11962           errmsg ("unknown input `%U'", format_unformat_error, i);
11963           return -99;
11964         }
11965     }
11966
11967   if (is_add == -1)
11968     {
11969       errmsg ("expecting: add|del");
11970       return -99;
11971     }
11972   if (classify_table_index == ~0)
11973     {
11974       errmsg ("classifier table not specified");
11975       return -99;
11976     }
11977   if (ip_version == 0)
11978     {
11979       errmsg ("IP version not specified");
11980       return -99;
11981     }
11982
11983   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11984
11985   mp->is_add = is_add;
11986   mp->table_id = htonl (classify_table_index);
11987   mp->ip_version = ip_version;
11988   mp->transport_protocol = transport_protocol;
11989
11990   S (mp);
11991   W (ret);
11992   return ret;
11993 }
11994
11995 static int
11996 api_get_node_index (vat_main_t * vam)
11997 {
11998   unformat_input_t *i = vam->input;
11999   vl_api_get_node_index_t *mp;
12000   u8 *name = 0;
12001   int ret;
12002
12003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12004     {
12005       if (unformat (i, "node %s", &name))
12006         ;
12007       else
12008         break;
12009     }
12010   if (name == 0)
12011     {
12012       errmsg ("node name required");
12013       return -99;
12014     }
12015   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12016     {
12017       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12018       return -99;
12019     }
12020
12021   M (GET_NODE_INDEX, mp);
12022   clib_memcpy (mp->node_name, name, vec_len (name));
12023   vec_free (name);
12024
12025   S (mp);
12026   W (ret);
12027   return ret;
12028 }
12029
12030 static int
12031 api_get_next_index (vat_main_t * vam)
12032 {
12033   unformat_input_t *i = vam->input;
12034   vl_api_get_next_index_t *mp;
12035   u8 *node_name = 0, *next_node_name = 0;
12036   int ret;
12037
12038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12039     {
12040       if (unformat (i, "node-name %s", &node_name))
12041         ;
12042       else if (unformat (i, "next-node-name %s", &next_node_name))
12043         break;
12044     }
12045
12046   if (node_name == 0)
12047     {
12048       errmsg ("node name required");
12049       return -99;
12050     }
12051   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12052     {
12053       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12054       return -99;
12055     }
12056
12057   if (next_node_name == 0)
12058     {
12059       errmsg ("next node name required");
12060       return -99;
12061     }
12062   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12063     {
12064       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12065       return -99;
12066     }
12067
12068   M (GET_NEXT_INDEX, mp);
12069   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12070   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12071   vec_free (node_name);
12072   vec_free (next_node_name);
12073
12074   S (mp);
12075   W (ret);
12076   return ret;
12077 }
12078
12079 static int
12080 api_add_node_next (vat_main_t * vam)
12081 {
12082   unformat_input_t *i = vam->input;
12083   vl_api_add_node_next_t *mp;
12084   u8 *name = 0;
12085   u8 *next = 0;
12086   int ret;
12087
12088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12089     {
12090       if (unformat (i, "node %s", &name))
12091         ;
12092       else if (unformat (i, "next %s", &next))
12093         ;
12094       else
12095         break;
12096     }
12097   if (name == 0)
12098     {
12099       errmsg ("node name required");
12100       return -99;
12101     }
12102   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12103     {
12104       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12105       return -99;
12106     }
12107   if (next == 0)
12108     {
12109       errmsg ("next node required");
12110       return -99;
12111     }
12112   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12113     {
12114       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12115       return -99;
12116     }
12117
12118   M (ADD_NODE_NEXT, mp);
12119   clib_memcpy (mp->node_name, name, vec_len (name));
12120   clib_memcpy (mp->next_name, next, vec_len (next));
12121   vec_free (name);
12122   vec_free (next);
12123
12124   S (mp);
12125   W (ret);
12126   return ret;
12127 }
12128
12129 static int
12130 api_l2tpv3_create_tunnel (vat_main_t * vam)
12131 {
12132   unformat_input_t *i = vam->input;
12133   ip6_address_t client_address, our_address;
12134   int client_address_set = 0;
12135   int our_address_set = 0;
12136   u32 local_session_id = 0;
12137   u32 remote_session_id = 0;
12138   u64 local_cookie = 0;
12139   u64 remote_cookie = 0;
12140   u8 l2_sublayer_present = 0;
12141   vl_api_l2tpv3_create_tunnel_t *mp;
12142   int ret;
12143
12144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12145     {
12146       if (unformat (i, "client_address %U", unformat_ip6_address,
12147                     &client_address))
12148         client_address_set = 1;
12149       else if (unformat (i, "our_address %U", unformat_ip6_address,
12150                          &our_address))
12151         our_address_set = 1;
12152       else if (unformat (i, "local_session_id %d", &local_session_id))
12153         ;
12154       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12155         ;
12156       else if (unformat (i, "local_cookie %lld", &local_cookie))
12157         ;
12158       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12159         ;
12160       else if (unformat (i, "l2-sublayer-present"))
12161         l2_sublayer_present = 1;
12162       else
12163         break;
12164     }
12165
12166   if (client_address_set == 0)
12167     {
12168       errmsg ("client_address required");
12169       return -99;
12170     }
12171
12172   if (our_address_set == 0)
12173     {
12174       errmsg ("our_address required");
12175       return -99;
12176     }
12177
12178   M (L2TPV3_CREATE_TUNNEL, mp);
12179
12180   clib_memcpy (mp->client_address, client_address.as_u8,
12181                sizeof (mp->client_address));
12182
12183   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12184
12185   mp->local_session_id = ntohl (local_session_id);
12186   mp->remote_session_id = ntohl (remote_session_id);
12187   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12188   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12189   mp->l2_sublayer_present = l2_sublayer_present;
12190   mp->is_ipv6 = 1;
12191
12192   S (mp);
12193   W (ret);
12194   return ret;
12195 }
12196
12197 static int
12198 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12199 {
12200   unformat_input_t *i = vam->input;
12201   u32 sw_if_index;
12202   u8 sw_if_index_set = 0;
12203   u64 new_local_cookie = 0;
12204   u64 new_remote_cookie = 0;
12205   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12206   int ret;
12207
12208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12209     {
12210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12211         sw_if_index_set = 1;
12212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12213         sw_if_index_set = 1;
12214       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12215         ;
12216       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12217         ;
12218       else
12219         break;
12220     }
12221
12222   if (sw_if_index_set == 0)
12223     {
12224       errmsg ("missing interface name or sw_if_index");
12225       return -99;
12226     }
12227
12228   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12229
12230   mp->sw_if_index = ntohl (sw_if_index);
12231   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12232   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12233
12234   S (mp);
12235   W (ret);
12236   return ret;
12237 }
12238
12239 static int
12240 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12241 {
12242   unformat_input_t *i = vam->input;
12243   vl_api_l2tpv3_interface_enable_disable_t *mp;
12244   u32 sw_if_index;
12245   u8 sw_if_index_set = 0;
12246   u8 enable_disable = 1;
12247   int ret;
12248
12249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12250     {
12251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12252         sw_if_index_set = 1;
12253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12254         sw_if_index_set = 1;
12255       else if (unformat (i, "enable"))
12256         enable_disable = 1;
12257       else if (unformat (i, "disable"))
12258         enable_disable = 0;
12259       else
12260         break;
12261     }
12262
12263   if (sw_if_index_set == 0)
12264     {
12265       errmsg ("missing interface name or sw_if_index");
12266       return -99;
12267     }
12268
12269   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12270
12271   mp->sw_if_index = ntohl (sw_if_index);
12272   mp->enable_disable = enable_disable;
12273
12274   S (mp);
12275   W (ret);
12276   return ret;
12277 }
12278
12279 static int
12280 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12281 {
12282   unformat_input_t *i = vam->input;
12283   vl_api_l2tpv3_set_lookup_key_t *mp;
12284   u8 key = ~0;
12285   int ret;
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "lookup_v6_src"))
12290         key = L2T_LOOKUP_SRC_ADDRESS;
12291       else if (unformat (i, "lookup_v6_dst"))
12292         key = L2T_LOOKUP_DST_ADDRESS;
12293       else if (unformat (i, "lookup_session_id"))
12294         key = L2T_LOOKUP_SESSION_ID;
12295       else
12296         break;
12297     }
12298
12299   if (key == (u8) ~ 0)
12300     {
12301       errmsg ("l2tp session lookup key unset");
12302       return -99;
12303     }
12304
12305   M (L2TPV3_SET_LOOKUP_KEY, mp);
12306
12307   mp->key = key;
12308
12309   S (mp);
12310   W (ret);
12311   return ret;
12312 }
12313
12314 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12315   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12316 {
12317   vat_main_t *vam = &vat_main;
12318
12319   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12320          format_ip6_address, mp->our_address,
12321          format_ip6_address, mp->client_address,
12322          clib_net_to_host_u32 (mp->sw_if_index));
12323
12324   print (vam->ofp,
12325          "   local cookies %016llx %016llx remote cookie %016llx",
12326          clib_net_to_host_u64 (mp->local_cookie[0]),
12327          clib_net_to_host_u64 (mp->local_cookie[1]),
12328          clib_net_to_host_u64 (mp->remote_cookie));
12329
12330   print (vam->ofp, "   local session-id %d remote session-id %d",
12331          clib_net_to_host_u32 (mp->local_session_id),
12332          clib_net_to_host_u32 (mp->remote_session_id));
12333
12334   print (vam->ofp, "   l2 specific sublayer %s\n",
12335          mp->l2_sublayer_present ? "preset" : "absent");
12336
12337 }
12338
12339 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12340   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12341 {
12342   vat_main_t *vam = &vat_main;
12343   vat_json_node_t *node = NULL;
12344   struct in6_addr addr;
12345
12346   if (VAT_JSON_ARRAY != vam->json_tree.type)
12347     {
12348       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12349       vat_json_init_array (&vam->json_tree);
12350     }
12351   node = vat_json_array_add (&vam->json_tree);
12352
12353   vat_json_init_object (node);
12354
12355   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12356   vat_json_object_add_ip6 (node, "our_address", addr);
12357   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12358   vat_json_object_add_ip6 (node, "client_address", addr);
12359
12360   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12361   vat_json_init_array (lc);
12362   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12363   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12364   vat_json_object_add_uint (node, "remote_cookie",
12365                             clib_net_to_host_u64 (mp->remote_cookie));
12366
12367   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12368   vat_json_object_add_uint (node, "local_session_id",
12369                             clib_net_to_host_u32 (mp->local_session_id));
12370   vat_json_object_add_uint (node, "remote_session_id",
12371                             clib_net_to_host_u32 (mp->remote_session_id));
12372   vat_json_object_add_string_copy (node, "l2_sublayer",
12373                                    mp->l2_sublayer_present ? (u8 *) "present"
12374                                    : (u8 *) "absent");
12375 }
12376
12377 static int
12378 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12379 {
12380   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12381   vl_api_control_ping_t *mp_ping;
12382   int ret;
12383
12384   /* Get list of l2tpv3-tunnel interfaces */
12385   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12386   S (mp);
12387
12388   /* Use a control ping for synchronization */
12389   MPING (CONTROL_PING, mp_ping);
12390   S (mp_ping);
12391
12392   W (ret);
12393   return ret;
12394 }
12395
12396
12397 static void vl_api_sw_interface_tap_details_t_handler
12398   (vl_api_sw_interface_tap_details_t * mp)
12399 {
12400   vat_main_t *vam = &vat_main;
12401
12402   print (vam->ofp, "%-16s %d",
12403          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12404 }
12405
12406 static void vl_api_sw_interface_tap_details_t_handler_json
12407   (vl_api_sw_interface_tap_details_t * mp)
12408 {
12409   vat_main_t *vam = &vat_main;
12410   vat_json_node_t *node = NULL;
12411
12412   if (VAT_JSON_ARRAY != vam->json_tree.type)
12413     {
12414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12415       vat_json_init_array (&vam->json_tree);
12416     }
12417   node = vat_json_array_add (&vam->json_tree);
12418
12419   vat_json_init_object (node);
12420   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12421   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12422 }
12423
12424 static int
12425 api_sw_interface_tap_dump (vat_main_t * vam)
12426 {
12427   vl_api_sw_interface_tap_dump_t *mp;
12428   vl_api_control_ping_t *mp_ping;
12429   int ret;
12430
12431   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12432   /* Get list of tap interfaces */
12433   M (SW_INTERFACE_TAP_DUMP, mp);
12434   S (mp);
12435
12436   /* Use a control ping for synchronization */
12437   MPING (CONTROL_PING, mp_ping);
12438   S (mp_ping);
12439
12440   W (ret);
12441   return ret;
12442 }
12443
12444 static void vl_api_sw_interface_tap_v2_details_t_handler
12445   (vl_api_sw_interface_tap_v2_details_t * mp)
12446 {
12447   vat_main_t *vam = &vat_main;
12448
12449   print (vam->ofp, "%-16s %d",
12450          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12451 }
12452
12453 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12454   (vl_api_sw_interface_tap_v2_details_t * mp)
12455 {
12456   vat_main_t *vam = &vat_main;
12457   vat_json_node_t *node = NULL;
12458
12459   if (VAT_JSON_ARRAY != vam->json_tree.type)
12460     {
12461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12462       vat_json_init_array (&vam->json_tree);
12463     }
12464   node = vat_json_array_add (&vam->json_tree);
12465
12466   vat_json_init_object (node);
12467   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12468   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12469 }
12470
12471 static int
12472 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12473 {
12474   vl_api_sw_interface_tap_v2_dump_t *mp;
12475   vl_api_control_ping_t *mp_ping;
12476   int ret;
12477
12478   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12479   /* Get list of tap interfaces */
12480   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12481   S (mp);
12482
12483   /* Use a control ping for synchronization */
12484   MPING (CONTROL_PING, mp_ping);
12485   S (mp_ping);
12486
12487   W (ret);
12488   return ret;
12489 }
12490
12491 static uword unformat_vxlan_decap_next
12492   (unformat_input_t * input, va_list * args)
12493 {
12494   u32 *result = va_arg (*args, u32 *);
12495   u32 tmp;
12496
12497   if (unformat (input, "l2"))
12498     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12499   else if (unformat (input, "%d", &tmp))
12500     *result = tmp;
12501   else
12502     return 0;
12503   return 1;
12504 }
12505
12506 static int
12507 api_vxlan_add_del_tunnel (vat_main_t * vam)
12508 {
12509   unformat_input_t *line_input = vam->input;
12510   vl_api_vxlan_add_del_tunnel_t *mp;
12511   ip46_address_t src, dst;
12512   u8 is_add = 1;
12513   u8 ipv4_set = 0, ipv6_set = 0;
12514   u8 src_set = 0;
12515   u8 dst_set = 0;
12516   u8 grp_set = 0;
12517   u32 mcast_sw_if_index = ~0;
12518   u32 encap_vrf_id = 0;
12519   u32 decap_next_index = ~0;
12520   u32 vni = 0;
12521   int ret;
12522
12523   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12524   memset (&src, 0, sizeof src);
12525   memset (&dst, 0, sizeof dst);
12526
12527   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (line_input, "del"))
12530         is_add = 0;
12531       else
12532         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12533         {
12534           ipv4_set = 1;
12535           src_set = 1;
12536         }
12537       else
12538         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12539         {
12540           ipv4_set = 1;
12541           dst_set = 1;
12542         }
12543       else
12544         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12545         {
12546           ipv6_set = 1;
12547           src_set = 1;
12548         }
12549       else
12550         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12551         {
12552           ipv6_set = 1;
12553           dst_set = 1;
12554         }
12555       else if (unformat (line_input, "group %U %U",
12556                          unformat_ip4_address, &dst.ip4,
12557                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12558         {
12559           grp_set = dst_set = 1;
12560           ipv4_set = 1;
12561         }
12562       else if (unformat (line_input, "group %U",
12563                          unformat_ip4_address, &dst.ip4))
12564         {
12565           grp_set = dst_set = 1;
12566           ipv4_set = 1;
12567         }
12568       else if (unformat (line_input, "group %U %U",
12569                          unformat_ip6_address, &dst.ip6,
12570                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12571         {
12572           grp_set = dst_set = 1;
12573           ipv6_set = 1;
12574         }
12575       else if (unformat (line_input, "group %U",
12576                          unformat_ip6_address, &dst.ip6))
12577         {
12578           grp_set = dst_set = 1;
12579           ipv6_set = 1;
12580         }
12581       else
12582         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12583         ;
12584       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12585         ;
12586       else if (unformat (line_input, "decap-next %U",
12587                          unformat_vxlan_decap_next, &decap_next_index))
12588         ;
12589       else if (unformat (line_input, "vni %d", &vni))
12590         ;
12591       else
12592         {
12593           errmsg ("parse error '%U'", format_unformat_error, line_input);
12594           return -99;
12595         }
12596     }
12597
12598   if (src_set == 0)
12599     {
12600       errmsg ("tunnel src address not specified");
12601       return -99;
12602     }
12603   if (dst_set == 0)
12604     {
12605       errmsg ("tunnel dst address not specified");
12606       return -99;
12607     }
12608
12609   if (grp_set && !ip46_address_is_multicast (&dst))
12610     {
12611       errmsg ("tunnel group address not multicast");
12612       return -99;
12613     }
12614   if (grp_set && mcast_sw_if_index == ~0)
12615     {
12616       errmsg ("tunnel nonexistent multicast device");
12617       return -99;
12618     }
12619   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12620     {
12621       errmsg ("tunnel dst address must be unicast");
12622       return -99;
12623     }
12624
12625
12626   if (ipv4_set && ipv6_set)
12627     {
12628       errmsg ("both IPv4 and IPv6 addresses specified");
12629       return -99;
12630     }
12631
12632   if ((vni == 0) || (vni >> 24))
12633     {
12634       errmsg ("vni not specified or out of range");
12635       return -99;
12636     }
12637
12638   M (VXLAN_ADD_DEL_TUNNEL, mp);
12639
12640   if (ipv6_set)
12641     {
12642       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12643       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12644     }
12645   else
12646     {
12647       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12648       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12649     }
12650   mp->encap_vrf_id = ntohl (encap_vrf_id);
12651   mp->decap_next_index = ntohl (decap_next_index);
12652   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12653   mp->vni = ntohl (vni);
12654   mp->is_add = is_add;
12655   mp->is_ipv6 = ipv6_set;
12656
12657   S (mp);
12658   W (ret);
12659   return ret;
12660 }
12661
12662 static void vl_api_vxlan_tunnel_details_t_handler
12663   (vl_api_vxlan_tunnel_details_t * mp)
12664 {
12665   vat_main_t *vam = &vat_main;
12666   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12667   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12668
12669   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12670          ntohl (mp->sw_if_index),
12671          format_ip46_address, &src, IP46_TYPE_ANY,
12672          format_ip46_address, &dst, IP46_TYPE_ANY,
12673          ntohl (mp->encap_vrf_id),
12674          ntohl (mp->decap_next_index), ntohl (mp->vni),
12675          ntohl (mp->mcast_sw_if_index));
12676 }
12677
12678 static void vl_api_vxlan_tunnel_details_t_handler_json
12679   (vl_api_vxlan_tunnel_details_t * mp)
12680 {
12681   vat_main_t *vam = &vat_main;
12682   vat_json_node_t *node = NULL;
12683
12684   if (VAT_JSON_ARRAY != vam->json_tree.type)
12685     {
12686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12687       vat_json_init_array (&vam->json_tree);
12688     }
12689   node = vat_json_array_add (&vam->json_tree);
12690
12691   vat_json_init_object (node);
12692   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12693   if (mp->is_ipv6)
12694     {
12695       struct in6_addr ip6;
12696
12697       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12698       vat_json_object_add_ip6 (node, "src_address", ip6);
12699       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12700       vat_json_object_add_ip6 (node, "dst_address", ip6);
12701     }
12702   else
12703     {
12704       struct in_addr ip4;
12705
12706       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12707       vat_json_object_add_ip4 (node, "src_address", ip4);
12708       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12709       vat_json_object_add_ip4 (node, "dst_address", ip4);
12710     }
12711   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12712   vat_json_object_add_uint (node, "decap_next_index",
12713                             ntohl (mp->decap_next_index));
12714   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12715   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12716   vat_json_object_add_uint (node, "mcast_sw_if_index",
12717                             ntohl (mp->mcast_sw_if_index));
12718 }
12719
12720 static int
12721 api_vxlan_tunnel_dump (vat_main_t * vam)
12722 {
12723   unformat_input_t *i = vam->input;
12724   vl_api_vxlan_tunnel_dump_t *mp;
12725   vl_api_control_ping_t *mp_ping;
12726   u32 sw_if_index;
12727   u8 sw_if_index_set = 0;
12728   int ret;
12729
12730   /* Parse args required to build the message */
12731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12732     {
12733       if (unformat (i, "sw_if_index %d", &sw_if_index))
12734         sw_if_index_set = 1;
12735       else
12736         break;
12737     }
12738
12739   if (sw_if_index_set == 0)
12740     {
12741       sw_if_index = ~0;
12742     }
12743
12744   if (!vam->json_output)
12745     {
12746       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12747              "sw_if_index", "src_address", "dst_address",
12748              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12749     }
12750
12751   /* Get list of vxlan-tunnel interfaces */
12752   M (VXLAN_TUNNEL_DUMP, mp);
12753
12754   mp->sw_if_index = htonl (sw_if_index);
12755
12756   S (mp);
12757
12758   /* Use a control ping for synchronization */
12759   MPING (CONTROL_PING, mp_ping);
12760   S (mp_ping);
12761
12762   W (ret);
12763   return ret;
12764 }
12765
12766 static uword unformat_geneve_decap_next
12767   (unformat_input_t * input, va_list * args)
12768 {
12769   u32 *result = va_arg (*args, u32 *);
12770   u32 tmp;
12771
12772   if (unformat (input, "l2"))
12773     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12774   else if (unformat (input, "%d", &tmp))
12775     *result = tmp;
12776   else
12777     return 0;
12778   return 1;
12779 }
12780
12781 static int
12782 api_geneve_add_del_tunnel (vat_main_t * vam)
12783 {
12784   unformat_input_t *line_input = vam->input;
12785   vl_api_geneve_add_del_tunnel_t *mp;
12786   ip46_address_t src, dst;
12787   u8 is_add = 1;
12788   u8 ipv4_set = 0, ipv6_set = 0;
12789   u8 src_set = 0;
12790   u8 dst_set = 0;
12791   u8 grp_set = 0;
12792   u32 mcast_sw_if_index = ~0;
12793   u32 encap_vrf_id = 0;
12794   u32 decap_next_index = ~0;
12795   u32 vni = 0;
12796   int ret;
12797
12798   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12799   memset (&src, 0, sizeof src);
12800   memset (&dst, 0, sizeof dst);
12801
12802   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12803     {
12804       if (unformat (line_input, "del"))
12805         is_add = 0;
12806       else
12807         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12808         {
12809           ipv4_set = 1;
12810           src_set = 1;
12811         }
12812       else
12813         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12814         {
12815           ipv4_set = 1;
12816           dst_set = 1;
12817         }
12818       else
12819         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12820         {
12821           ipv6_set = 1;
12822           src_set = 1;
12823         }
12824       else
12825         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12826         {
12827           ipv6_set = 1;
12828           dst_set = 1;
12829         }
12830       else if (unformat (line_input, "group %U %U",
12831                          unformat_ip4_address, &dst.ip4,
12832                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12833         {
12834           grp_set = dst_set = 1;
12835           ipv4_set = 1;
12836         }
12837       else if (unformat (line_input, "group %U",
12838                          unformat_ip4_address, &dst.ip4))
12839         {
12840           grp_set = dst_set = 1;
12841           ipv4_set = 1;
12842         }
12843       else if (unformat (line_input, "group %U %U",
12844                          unformat_ip6_address, &dst.ip6,
12845                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12846         {
12847           grp_set = dst_set = 1;
12848           ipv6_set = 1;
12849         }
12850       else if (unformat (line_input, "group %U",
12851                          unformat_ip6_address, &dst.ip6))
12852         {
12853           grp_set = dst_set = 1;
12854           ipv6_set = 1;
12855         }
12856       else
12857         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12858         ;
12859       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12860         ;
12861       else if (unformat (line_input, "decap-next %U",
12862                          unformat_geneve_decap_next, &decap_next_index))
12863         ;
12864       else if (unformat (line_input, "vni %d", &vni))
12865         ;
12866       else
12867         {
12868           errmsg ("parse error '%U'", format_unformat_error, line_input);
12869           return -99;
12870         }
12871     }
12872
12873   if (src_set == 0)
12874     {
12875       errmsg ("tunnel src address not specified");
12876       return -99;
12877     }
12878   if (dst_set == 0)
12879     {
12880       errmsg ("tunnel dst address not specified");
12881       return -99;
12882     }
12883
12884   if (grp_set && !ip46_address_is_multicast (&dst))
12885     {
12886       errmsg ("tunnel group address not multicast");
12887       return -99;
12888     }
12889   if (grp_set && mcast_sw_if_index == ~0)
12890     {
12891       errmsg ("tunnel nonexistent multicast device");
12892       return -99;
12893     }
12894   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12895     {
12896       errmsg ("tunnel dst address must be unicast");
12897       return -99;
12898     }
12899
12900
12901   if (ipv4_set && ipv6_set)
12902     {
12903       errmsg ("both IPv4 and IPv6 addresses specified");
12904       return -99;
12905     }
12906
12907   if ((vni == 0) || (vni >> 24))
12908     {
12909       errmsg ("vni not specified or out of range");
12910       return -99;
12911     }
12912
12913   M (GENEVE_ADD_DEL_TUNNEL, mp);
12914
12915   if (ipv6_set)
12916     {
12917       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12918       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12919     }
12920   else
12921     {
12922       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12923       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12924     }
12925   mp->encap_vrf_id = ntohl (encap_vrf_id);
12926   mp->decap_next_index = ntohl (decap_next_index);
12927   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12928   mp->vni = ntohl (vni);
12929   mp->is_add = is_add;
12930   mp->is_ipv6 = ipv6_set;
12931
12932   S (mp);
12933   W (ret);
12934   return ret;
12935 }
12936
12937 static void vl_api_geneve_tunnel_details_t_handler
12938   (vl_api_geneve_tunnel_details_t * mp)
12939 {
12940   vat_main_t *vam = &vat_main;
12941   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12942   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12943
12944   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12945          ntohl (mp->sw_if_index),
12946          format_ip46_address, &src, IP46_TYPE_ANY,
12947          format_ip46_address, &dst, IP46_TYPE_ANY,
12948          ntohl (mp->encap_vrf_id),
12949          ntohl (mp->decap_next_index), ntohl (mp->vni),
12950          ntohl (mp->mcast_sw_if_index));
12951 }
12952
12953 static void vl_api_geneve_tunnel_details_t_handler_json
12954   (vl_api_geneve_tunnel_details_t * mp)
12955 {
12956   vat_main_t *vam = &vat_main;
12957   vat_json_node_t *node = NULL;
12958
12959   if (VAT_JSON_ARRAY != vam->json_tree.type)
12960     {
12961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12962       vat_json_init_array (&vam->json_tree);
12963     }
12964   node = vat_json_array_add (&vam->json_tree);
12965
12966   vat_json_init_object (node);
12967   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12968   if (mp->is_ipv6)
12969     {
12970       struct in6_addr ip6;
12971
12972       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12973       vat_json_object_add_ip6 (node, "src_address", ip6);
12974       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12975       vat_json_object_add_ip6 (node, "dst_address", ip6);
12976     }
12977   else
12978     {
12979       struct in_addr ip4;
12980
12981       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12982       vat_json_object_add_ip4 (node, "src_address", ip4);
12983       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12984       vat_json_object_add_ip4 (node, "dst_address", ip4);
12985     }
12986   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12987   vat_json_object_add_uint (node, "decap_next_index",
12988                             ntohl (mp->decap_next_index));
12989   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12990   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12991   vat_json_object_add_uint (node, "mcast_sw_if_index",
12992                             ntohl (mp->mcast_sw_if_index));
12993 }
12994
12995 static int
12996 api_geneve_tunnel_dump (vat_main_t * vam)
12997 {
12998   unformat_input_t *i = vam->input;
12999   vl_api_geneve_tunnel_dump_t *mp;
13000   vl_api_control_ping_t *mp_ping;
13001   u32 sw_if_index;
13002   u8 sw_if_index_set = 0;
13003   int ret;
13004
13005   /* Parse args required to build the message */
13006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13007     {
13008       if (unformat (i, "sw_if_index %d", &sw_if_index))
13009         sw_if_index_set = 1;
13010       else
13011         break;
13012     }
13013
13014   if (sw_if_index_set == 0)
13015     {
13016       sw_if_index = ~0;
13017     }
13018
13019   if (!vam->json_output)
13020     {
13021       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13022              "sw_if_index", "local_address", "remote_address",
13023              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13024     }
13025
13026   /* Get list of geneve-tunnel interfaces */
13027   M (GENEVE_TUNNEL_DUMP, mp);
13028
13029   mp->sw_if_index = htonl (sw_if_index);
13030
13031   S (mp);
13032
13033   /* Use a control ping for synchronization */
13034   M (CONTROL_PING, mp_ping);
13035   S (mp_ping);
13036
13037   W (ret);
13038   return ret;
13039 }
13040
13041 static int
13042 api_gre_add_del_tunnel (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_gre_add_del_tunnel_t *mp;
13046   ip4_address_t src4, dst4;
13047   ip6_address_t src6, dst6;
13048   u8 is_add = 1;
13049   u8 ipv4_set = 0;
13050   u8 ipv6_set = 0;
13051   u8 teb = 0;
13052   u8 src_set = 0;
13053   u8 dst_set = 0;
13054   u32 outer_fib_id = 0;
13055   int ret;
13056
13057   memset (&src4, 0, sizeof src4);
13058   memset (&dst4, 0, sizeof dst4);
13059   memset (&src6, 0, sizeof src6);
13060   memset (&dst6, 0, sizeof dst6);
13061
13062   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (line_input, "del"))
13065         is_add = 0;
13066       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13067         {
13068           src_set = 1;
13069           ipv4_set = 1;
13070         }
13071       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13072         {
13073           dst_set = 1;
13074           ipv4_set = 1;
13075         }
13076       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13077         {
13078           src_set = 1;
13079           ipv6_set = 1;
13080         }
13081       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13082         {
13083           dst_set = 1;
13084           ipv6_set = 1;
13085         }
13086       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13087         ;
13088       else if (unformat (line_input, "teb"))
13089         teb = 1;
13090       else
13091         {
13092           errmsg ("parse error '%U'", format_unformat_error, line_input);
13093           return -99;
13094         }
13095     }
13096
13097   if (src_set == 0)
13098     {
13099       errmsg ("tunnel src address not specified");
13100       return -99;
13101     }
13102   if (dst_set == 0)
13103     {
13104       errmsg ("tunnel dst address not specified");
13105       return -99;
13106     }
13107   if (ipv4_set && ipv6_set)
13108     {
13109       errmsg ("both IPv4 and IPv6 addresses specified");
13110       return -99;
13111     }
13112
13113
13114   M (GRE_ADD_DEL_TUNNEL, mp);
13115
13116   if (ipv4_set)
13117     {
13118       clib_memcpy (&mp->src_address, &src4, 4);
13119       clib_memcpy (&mp->dst_address, &dst4, 4);
13120     }
13121   else
13122     {
13123       clib_memcpy (&mp->src_address, &src6, 16);
13124       clib_memcpy (&mp->dst_address, &dst6, 16);
13125     }
13126   mp->outer_fib_id = ntohl (outer_fib_id);
13127   mp->is_add = is_add;
13128   mp->teb = teb;
13129   mp->is_ipv6 = ipv6_set;
13130
13131   S (mp);
13132   W (ret);
13133   return ret;
13134 }
13135
13136 static void vl_api_gre_tunnel_details_t_handler
13137   (vl_api_gre_tunnel_details_t * mp)
13138 {
13139   vat_main_t *vam = &vat_main;
13140   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13141   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13142
13143   print (vam->ofp, "%11d%24U%24U%6d%14d",
13144          ntohl (mp->sw_if_index),
13145          format_ip46_address, &src, IP46_TYPE_ANY,
13146          format_ip46_address, &dst, IP46_TYPE_ANY,
13147          mp->teb, ntohl (mp->outer_fib_id));
13148 }
13149
13150 static void vl_api_gre_tunnel_details_t_handler_json
13151   (vl_api_gre_tunnel_details_t * mp)
13152 {
13153   vat_main_t *vam = &vat_main;
13154   vat_json_node_t *node = NULL;
13155   struct in_addr ip4;
13156   struct in6_addr ip6;
13157
13158   if (VAT_JSON_ARRAY != vam->json_tree.type)
13159     {
13160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13161       vat_json_init_array (&vam->json_tree);
13162     }
13163   node = vat_json_array_add (&vam->json_tree);
13164
13165   vat_json_init_object (node);
13166   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13167   if (!mp->is_ipv6)
13168     {
13169       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13170       vat_json_object_add_ip4 (node, "src_address", ip4);
13171       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13172       vat_json_object_add_ip4 (node, "dst_address", ip4);
13173     }
13174   else
13175     {
13176       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13177       vat_json_object_add_ip6 (node, "src_address", ip6);
13178       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13179       vat_json_object_add_ip6 (node, "dst_address", ip6);
13180     }
13181   vat_json_object_add_uint (node, "teb", mp->teb);
13182   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13183   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13184 }
13185
13186 static int
13187 api_gre_tunnel_dump (vat_main_t * vam)
13188 {
13189   unformat_input_t *i = vam->input;
13190   vl_api_gre_tunnel_dump_t *mp;
13191   vl_api_control_ping_t *mp_ping;
13192   u32 sw_if_index;
13193   u8 sw_if_index_set = 0;
13194   int ret;
13195
13196   /* Parse args required to build the message */
13197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13198     {
13199       if (unformat (i, "sw_if_index %d", &sw_if_index))
13200         sw_if_index_set = 1;
13201       else
13202         break;
13203     }
13204
13205   if (sw_if_index_set == 0)
13206     {
13207       sw_if_index = ~0;
13208     }
13209
13210   if (!vam->json_output)
13211     {
13212       print (vam->ofp, "%11s%24s%24s%6s%14s",
13213              "sw_if_index", "src_address", "dst_address", "teb",
13214              "outer_fib_id");
13215     }
13216
13217   /* Get list of gre-tunnel interfaces */
13218   M (GRE_TUNNEL_DUMP, mp);
13219
13220   mp->sw_if_index = htonl (sw_if_index);
13221
13222   S (mp);
13223
13224   /* Use a control ping for synchronization */
13225   MPING (CONTROL_PING, mp_ping);
13226   S (mp_ping);
13227
13228   W (ret);
13229   return ret;
13230 }
13231
13232 static int
13233 api_l2_fib_clear_table (vat_main_t * vam)
13234 {
13235 //  unformat_input_t * i = vam->input;
13236   vl_api_l2_fib_clear_table_t *mp;
13237   int ret;
13238
13239   M (L2_FIB_CLEAR_TABLE, mp);
13240
13241   S (mp);
13242   W (ret);
13243   return ret;
13244 }
13245
13246 static int
13247 api_l2_interface_efp_filter (vat_main_t * vam)
13248 {
13249   unformat_input_t *i = vam->input;
13250   vl_api_l2_interface_efp_filter_t *mp;
13251   u32 sw_if_index;
13252   u8 enable = 1;
13253   u8 sw_if_index_set = 0;
13254   int ret;
13255
13256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13257     {
13258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13259         sw_if_index_set = 1;
13260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13261         sw_if_index_set = 1;
13262       else if (unformat (i, "enable"))
13263         enable = 1;
13264       else if (unformat (i, "disable"))
13265         enable = 0;
13266       else
13267         {
13268           clib_warning ("parse error '%U'", format_unformat_error, i);
13269           return -99;
13270         }
13271     }
13272
13273   if (sw_if_index_set == 0)
13274     {
13275       errmsg ("missing sw_if_index");
13276       return -99;
13277     }
13278
13279   M (L2_INTERFACE_EFP_FILTER, mp);
13280
13281   mp->sw_if_index = ntohl (sw_if_index);
13282   mp->enable_disable = enable;
13283
13284   S (mp);
13285   W (ret);
13286   return ret;
13287 }
13288
13289 #define foreach_vtr_op                          \
13290 _("disable",  L2_VTR_DISABLED)                  \
13291 _("push-1",  L2_VTR_PUSH_1)                     \
13292 _("push-2",  L2_VTR_PUSH_2)                     \
13293 _("pop-1",  L2_VTR_POP_1)                       \
13294 _("pop-2",  L2_VTR_POP_2)                       \
13295 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13296 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13297 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13298 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13299
13300 static int
13301 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13302 {
13303   unformat_input_t *i = vam->input;
13304   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13305   u32 sw_if_index;
13306   u8 sw_if_index_set = 0;
13307   u8 vtr_op_set = 0;
13308   u32 vtr_op = 0;
13309   u32 push_dot1q = 1;
13310   u32 tag1 = ~0;
13311   u32 tag2 = ~0;
13312   int ret;
13313
13314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13315     {
13316       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13317         sw_if_index_set = 1;
13318       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13319         sw_if_index_set = 1;
13320       else if (unformat (i, "vtr_op %d", &vtr_op))
13321         vtr_op_set = 1;
13322 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13323       foreach_vtr_op
13324 #undef _
13325         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13326         ;
13327       else if (unformat (i, "tag1 %d", &tag1))
13328         ;
13329       else if (unformat (i, "tag2 %d", &tag2))
13330         ;
13331       else
13332         {
13333           clib_warning ("parse error '%U'", format_unformat_error, i);
13334           return -99;
13335         }
13336     }
13337
13338   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13339     {
13340       errmsg ("missing vtr operation or sw_if_index");
13341       return -99;
13342     }
13343
13344   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13345   mp->sw_if_index = ntohl (sw_if_index);
13346   mp->vtr_op = ntohl (vtr_op);
13347   mp->push_dot1q = ntohl (push_dot1q);
13348   mp->tag1 = ntohl (tag1);
13349   mp->tag2 = ntohl (tag2);
13350
13351   S (mp);
13352   W (ret);
13353   return ret;
13354 }
13355
13356 static int
13357 api_create_vhost_user_if (vat_main_t * vam)
13358 {
13359   unformat_input_t *i = vam->input;
13360   vl_api_create_vhost_user_if_t *mp;
13361   u8 *file_name;
13362   u8 is_server = 0;
13363   u8 file_name_set = 0;
13364   u32 custom_dev_instance = ~0;
13365   u8 hwaddr[6];
13366   u8 use_custom_mac = 0;
13367   u8 *tag = 0;
13368   int ret;
13369
13370   /* Shut up coverity */
13371   memset (hwaddr, 0, sizeof (hwaddr));
13372
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "socket %s", &file_name))
13376         {
13377           file_name_set = 1;
13378         }
13379       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13380         ;
13381       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13382         use_custom_mac = 1;
13383       else if (unformat (i, "server"))
13384         is_server = 1;
13385       else if (unformat (i, "tag %s", &tag))
13386         ;
13387       else
13388         break;
13389     }
13390
13391   if (file_name_set == 0)
13392     {
13393       errmsg ("missing socket file name");
13394       return -99;
13395     }
13396
13397   if (vec_len (file_name) > 255)
13398     {
13399       errmsg ("socket file name too long");
13400       return -99;
13401     }
13402   vec_add1 (file_name, 0);
13403
13404   M (CREATE_VHOST_USER_IF, mp);
13405
13406   mp->is_server = is_server;
13407   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13408   vec_free (file_name);
13409   if (custom_dev_instance != ~0)
13410     {
13411       mp->renumber = 1;
13412       mp->custom_dev_instance = ntohl (custom_dev_instance);
13413     }
13414   mp->use_custom_mac = use_custom_mac;
13415   clib_memcpy (mp->mac_address, hwaddr, 6);
13416   if (tag)
13417     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13418   vec_free (tag);
13419
13420   S (mp);
13421   W (ret);
13422   return ret;
13423 }
13424
13425 static int
13426 api_modify_vhost_user_if (vat_main_t * vam)
13427 {
13428   unformat_input_t *i = vam->input;
13429   vl_api_modify_vhost_user_if_t *mp;
13430   u8 *file_name;
13431   u8 is_server = 0;
13432   u8 file_name_set = 0;
13433   u32 custom_dev_instance = ~0;
13434   u8 sw_if_index_set = 0;
13435   u32 sw_if_index = (u32) ~ 0;
13436   int ret;
13437
13438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13439     {
13440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13441         sw_if_index_set = 1;
13442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13443         sw_if_index_set = 1;
13444       else if (unformat (i, "socket %s", &file_name))
13445         {
13446           file_name_set = 1;
13447         }
13448       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13449         ;
13450       else if (unformat (i, "server"))
13451         is_server = 1;
13452       else
13453         break;
13454     }
13455
13456   if (sw_if_index_set == 0)
13457     {
13458       errmsg ("missing sw_if_index or interface name");
13459       return -99;
13460     }
13461
13462   if (file_name_set == 0)
13463     {
13464       errmsg ("missing socket file name");
13465       return -99;
13466     }
13467
13468   if (vec_len (file_name) > 255)
13469     {
13470       errmsg ("socket file name too long");
13471       return -99;
13472     }
13473   vec_add1 (file_name, 0);
13474
13475   M (MODIFY_VHOST_USER_IF, mp);
13476
13477   mp->sw_if_index = ntohl (sw_if_index);
13478   mp->is_server = is_server;
13479   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13480   vec_free (file_name);
13481   if (custom_dev_instance != ~0)
13482     {
13483       mp->renumber = 1;
13484       mp->custom_dev_instance = ntohl (custom_dev_instance);
13485     }
13486
13487   S (mp);
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static int
13493 api_delete_vhost_user_if (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_delete_vhost_user_if_t *mp;
13497   u32 sw_if_index = ~0;
13498   u8 sw_if_index_set = 0;
13499   int ret;
13500
13501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13502     {
13503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13504         sw_if_index_set = 1;
13505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13506         sw_if_index_set = 1;
13507       else
13508         break;
13509     }
13510
13511   if (sw_if_index_set == 0)
13512     {
13513       errmsg ("missing sw_if_index or interface name");
13514       return -99;
13515     }
13516
13517
13518   M (DELETE_VHOST_USER_IF, mp);
13519
13520   mp->sw_if_index = ntohl (sw_if_index);
13521
13522   S (mp);
13523   W (ret);
13524   return ret;
13525 }
13526
13527 static void vl_api_sw_interface_vhost_user_details_t_handler
13528   (vl_api_sw_interface_vhost_user_details_t * mp)
13529 {
13530   vat_main_t *vam = &vat_main;
13531
13532   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13533          (char *) mp->interface_name,
13534          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13535          clib_net_to_host_u64 (mp->features), mp->is_server,
13536          ntohl (mp->num_regions), (char *) mp->sock_filename);
13537   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13538 }
13539
13540 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13541   (vl_api_sw_interface_vhost_user_details_t * mp)
13542 {
13543   vat_main_t *vam = &vat_main;
13544   vat_json_node_t *node = NULL;
13545
13546   if (VAT_JSON_ARRAY != vam->json_tree.type)
13547     {
13548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13549       vat_json_init_array (&vam->json_tree);
13550     }
13551   node = vat_json_array_add (&vam->json_tree);
13552
13553   vat_json_init_object (node);
13554   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13555   vat_json_object_add_string_copy (node, "interface_name",
13556                                    mp->interface_name);
13557   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13558                             ntohl (mp->virtio_net_hdr_sz));
13559   vat_json_object_add_uint (node, "features",
13560                             clib_net_to_host_u64 (mp->features));
13561   vat_json_object_add_uint (node, "is_server", mp->is_server);
13562   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13563   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13564   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13565 }
13566
13567 static int
13568 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13569 {
13570   vl_api_sw_interface_vhost_user_dump_t *mp;
13571   vl_api_control_ping_t *mp_ping;
13572   int ret;
13573   print (vam->ofp,
13574          "Interface name            idx hdr_sz features server regions filename");
13575
13576   /* Get list of vhost-user interfaces */
13577   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13578   S (mp);
13579
13580   /* Use a control ping for synchronization */
13581   MPING (CONTROL_PING, mp_ping);
13582   S (mp_ping);
13583
13584   W (ret);
13585   return ret;
13586 }
13587
13588 static int
13589 api_show_version (vat_main_t * vam)
13590 {
13591   vl_api_show_version_t *mp;
13592   int ret;
13593
13594   M (SHOW_VERSION, mp);
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601
13602 static int
13603 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13604 {
13605   unformat_input_t *line_input = vam->input;
13606   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13607   ip4_address_t local4, remote4;
13608   ip6_address_t local6, remote6;
13609   u8 is_add = 1;
13610   u8 ipv4_set = 0, ipv6_set = 0;
13611   u8 local_set = 0;
13612   u8 remote_set = 0;
13613   u8 grp_set = 0;
13614   u32 mcast_sw_if_index = ~0;
13615   u32 encap_vrf_id = 0;
13616   u32 decap_vrf_id = 0;
13617   u8 protocol = ~0;
13618   u32 vni;
13619   u8 vni_set = 0;
13620   int ret;
13621
13622   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13623   memset (&local4, 0, sizeof local4);
13624   memset (&remote4, 0, sizeof remote4);
13625   memset (&local6, 0, sizeof local6);
13626   memset (&remote6, 0, sizeof remote6);
13627
13628   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13629     {
13630       if (unformat (line_input, "del"))
13631         is_add = 0;
13632       else if (unformat (line_input, "local %U",
13633                          unformat_ip4_address, &local4))
13634         {
13635           local_set = 1;
13636           ipv4_set = 1;
13637         }
13638       else if (unformat (line_input, "remote %U",
13639                          unformat_ip4_address, &remote4))
13640         {
13641           remote_set = 1;
13642           ipv4_set = 1;
13643         }
13644       else if (unformat (line_input, "local %U",
13645                          unformat_ip6_address, &local6))
13646         {
13647           local_set = 1;
13648           ipv6_set = 1;
13649         }
13650       else if (unformat (line_input, "remote %U",
13651                          unformat_ip6_address, &remote6))
13652         {
13653           remote_set = 1;
13654           ipv6_set = 1;
13655         }
13656       else if (unformat (line_input, "group %U %U",
13657                          unformat_ip4_address, &remote4,
13658                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13659         {
13660           grp_set = remote_set = 1;
13661           ipv4_set = 1;
13662         }
13663       else if (unformat (line_input, "group %U",
13664                          unformat_ip4_address, &remote4))
13665         {
13666           grp_set = remote_set = 1;
13667           ipv4_set = 1;
13668         }
13669       else if (unformat (line_input, "group %U %U",
13670                          unformat_ip6_address, &remote6,
13671                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13672         {
13673           grp_set = remote_set = 1;
13674           ipv6_set = 1;
13675         }
13676       else if (unformat (line_input, "group %U",
13677                          unformat_ip6_address, &remote6))
13678         {
13679           grp_set = remote_set = 1;
13680           ipv6_set = 1;
13681         }
13682       else
13683         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13684         ;
13685       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13686         ;
13687       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13688         ;
13689       else if (unformat (line_input, "vni %d", &vni))
13690         vni_set = 1;
13691       else if (unformat (line_input, "next-ip4"))
13692         protocol = 1;
13693       else if (unformat (line_input, "next-ip6"))
13694         protocol = 2;
13695       else if (unformat (line_input, "next-ethernet"))
13696         protocol = 3;
13697       else if (unformat (line_input, "next-nsh"))
13698         protocol = 4;
13699       else
13700         {
13701           errmsg ("parse error '%U'", format_unformat_error, line_input);
13702           return -99;
13703         }
13704     }
13705
13706   if (local_set == 0)
13707     {
13708       errmsg ("tunnel local address not specified");
13709       return -99;
13710     }
13711   if (remote_set == 0)
13712     {
13713       errmsg ("tunnel remote address not specified");
13714       return -99;
13715     }
13716   if (grp_set && mcast_sw_if_index == ~0)
13717     {
13718       errmsg ("tunnel nonexistent multicast device");
13719       return -99;
13720     }
13721   if (ipv4_set && ipv6_set)
13722     {
13723       errmsg ("both IPv4 and IPv6 addresses specified");
13724       return -99;
13725     }
13726
13727   if (vni_set == 0)
13728     {
13729       errmsg ("vni not specified");
13730       return -99;
13731     }
13732
13733   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13734
13735
13736   if (ipv6_set)
13737     {
13738       clib_memcpy (&mp->local, &local6, sizeof (local6));
13739       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13740     }
13741   else
13742     {
13743       clib_memcpy (&mp->local, &local4, sizeof (local4));
13744       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13745     }
13746
13747   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13748   mp->encap_vrf_id = ntohl (encap_vrf_id);
13749   mp->decap_vrf_id = ntohl (decap_vrf_id);
13750   mp->protocol = protocol;
13751   mp->vni = ntohl (vni);
13752   mp->is_add = is_add;
13753   mp->is_ipv6 = ipv6_set;
13754
13755   S (mp);
13756   W (ret);
13757   return ret;
13758 }
13759
13760 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13761   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13762 {
13763   vat_main_t *vam = &vat_main;
13764   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13765   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13766
13767   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13768          ntohl (mp->sw_if_index),
13769          format_ip46_address, &local, IP46_TYPE_ANY,
13770          format_ip46_address, &remote, IP46_TYPE_ANY,
13771          ntohl (mp->vni), mp->protocol,
13772          ntohl (mp->mcast_sw_if_index),
13773          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13774 }
13775
13776
13777 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13778   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13779 {
13780   vat_main_t *vam = &vat_main;
13781   vat_json_node_t *node = NULL;
13782   struct in_addr ip4;
13783   struct in6_addr ip6;
13784
13785   if (VAT_JSON_ARRAY != vam->json_tree.type)
13786     {
13787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13788       vat_json_init_array (&vam->json_tree);
13789     }
13790   node = vat_json_array_add (&vam->json_tree);
13791
13792   vat_json_init_object (node);
13793   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13794   if (mp->is_ipv6)
13795     {
13796       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13797       vat_json_object_add_ip6 (node, "local", ip6);
13798       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13799       vat_json_object_add_ip6 (node, "remote", ip6);
13800     }
13801   else
13802     {
13803       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13804       vat_json_object_add_ip4 (node, "local", ip4);
13805       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13806       vat_json_object_add_ip4 (node, "remote", ip4);
13807     }
13808   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13809   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13810   vat_json_object_add_uint (node, "mcast_sw_if_index",
13811                             ntohl (mp->mcast_sw_if_index));
13812   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13813   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13814   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13815 }
13816
13817 static int
13818 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13819 {
13820   unformat_input_t *i = vam->input;
13821   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13822   vl_api_control_ping_t *mp_ping;
13823   u32 sw_if_index;
13824   u8 sw_if_index_set = 0;
13825   int ret;
13826
13827   /* Parse args required to build the message */
13828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13829     {
13830       if (unformat (i, "sw_if_index %d", &sw_if_index))
13831         sw_if_index_set = 1;
13832       else
13833         break;
13834     }
13835
13836   if (sw_if_index_set == 0)
13837     {
13838       sw_if_index = ~0;
13839     }
13840
13841   if (!vam->json_output)
13842     {
13843       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13844              "sw_if_index", "local", "remote", "vni",
13845              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13846     }
13847
13848   /* Get list of vxlan-tunnel interfaces */
13849   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13850
13851   mp->sw_if_index = htonl (sw_if_index);
13852
13853   S (mp);
13854
13855   /* Use a control ping for synchronization */
13856   MPING (CONTROL_PING, mp_ping);
13857   S (mp_ping);
13858
13859   W (ret);
13860   return ret;
13861 }
13862
13863 static void vl_api_l2_fib_table_details_t_handler
13864   (vl_api_l2_fib_table_details_t * mp)
13865 {
13866   vat_main_t *vam = &vat_main;
13867
13868   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13869          "       %d       %d     %d",
13870          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13871          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13872          mp->bvi_mac);
13873 }
13874
13875 static void vl_api_l2_fib_table_details_t_handler_json
13876   (vl_api_l2_fib_table_details_t * mp)
13877 {
13878   vat_main_t *vam = &vat_main;
13879   vat_json_node_t *node = NULL;
13880
13881   if (VAT_JSON_ARRAY != vam->json_tree.type)
13882     {
13883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13884       vat_json_init_array (&vam->json_tree);
13885     }
13886   node = vat_json_array_add (&vam->json_tree);
13887
13888   vat_json_init_object (node);
13889   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13890   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13891   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13892   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13893   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13894   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13895 }
13896
13897 static int
13898 api_l2_fib_table_dump (vat_main_t * vam)
13899 {
13900   unformat_input_t *i = vam->input;
13901   vl_api_l2_fib_table_dump_t *mp;
13902   vl_api_control_ping_t *mp_ping;
13903   u32 bd_id;
13904   u8 bd_id_set = 0;
13905   int ret;
13906
13907   /* Parse args required to build the message */
13908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13909     {
13910       if (unformat (i, "bd_id %d", &bd_id))
13911         bd_id_set = 1;
13912       else
13913         break;
13914     }
13915
13916   if (bd_id_set == 0)
13917     {
13918       errmsg ("missing bridge domain");
13919       return -99;
13920     }
13921
13922   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13923
13924   /* Get list of l2 fib entries */
13925   M (L2_FIB_TABLE_DUMP, mp);
13926
13927   mp->bd_id = ntohl (bd_id);
13928   S (mp);
13929
13930   /* Use a control ping for synchronization */
13931   MPING (CONTROL_PING, mp_ping);
13932   S (mp_ping);
13933
13934   W (ret);
13935   return ret;
13936 }
13937
13938
13939 static int
13940 api_interface_name_renumber (vat_main_t * vam)
13941 {
13942   unformat_input_t *line_input = vam->input;
13943   vl_api_interface_name_renumber_t *mp;
13944   u32 sw_if_index = ~0;
13945   u32 new_show_dev_instance = ~0;
13946   int ret;
13947
13948   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13949     {
13950       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13951                     &sw_if_index))
13952         ;
13953       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13954         ;
13955       else if (unformat (line_input, "new_show_dev_instance %d",
13956                          &new_show_dev_instance))
13957         ;
13958       else
13959         break;
13960     }
13961
13962   if (sw_if_index == ~0)
13963     {
13964       errmsg ("missing interface name or sw_if_index");
13965       return -99;
13966     }
13967
13968   if (new_show_dev_instance == ~0)
13969     {
13970       errmsg ("missing new_show_dev_instance");
13971       return -99;
13972     }
13973
13974   M (INTERFACE_NAME_RENUMBER, mp);
13975
13976   mp->sw_if_index = ntohl (sw_if_index);
13977   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13978
13979   S (mp);
13980   W (ret);
13981   return ret;
13982 }
13983
13984 static int
13985 api_want_ip4_arp_events (vat_main_t * vam)
13986 {
13987   unformat_input_t *line_input = vam->input;
13988   vl_api_want_ip4_arp_events_t *mp;
13989   ip4_address_t address;
13990   int address_set = 0;
13991   u32 enable_disable = 1;
13992   int ret;
13993
13994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13995     {
13996       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13997         address_set = 1;
13998       else if (unformat (line_input, "del"))
13999         enable_disable = 0;
14000       else
14001         break;
14002     }
14003
14004   if (address_set == 0)
14005     {
14006       errmsg ("missing addresses");
14007       return -99;
14008     }
14009
14010   M (WANT_IP4_ARP_EVENTS, mp);
14011   mp->enable_disable = enable_disable;
14012   mp->pid = htonl (getpid ());
14013   mp->address = address.as_u32;
14014
14015   S (mp);
14016   W (ret);
14017   return ret;
14018 }
14019
14020 static int
14021 api_want_ip6_nd_events (vat_main_t * vam)
14022 {
14023   unformat_input_t *line_input = vam->input;
14024   vl_api_want_ip6_nd_events_t *mp;
14025   ip6_address_t address;
14026   int address_set = 0;
14027   u32 enable_disable = 1;
14028   int ret;
14029
14030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14033         address_set = 1;
14034       else if (unformat (line_input, "del"))
14035         enable_disable = 0;
14036       else
14037         break;
14038     }
14039
14040   if (address_set == 0)
14041     {
14042       errmsg ("missing addresses");
14043       return -99;
14044     }
14045
14046   M (WANT_IP6_ND_EVENTS, mp);
14047   mp->enable_disable = enable_disable;
14048   mp->pid = htonl (getpid ());
14049   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14050
14051   S (mp);
14052   W (ret);
14053   return ret;
14054 }
14055
14056 static int
14057 api_want_l2_macs_events (vat_main_t * vam)
14058 {
14059   unformat_input_t *line_input = vam->input;
14060   vl_api_want_l2_macs_events_t *mp;
14061   u8 enable_disable = 1;
14062   u32 scan_delay = 0;
14063   u32 max_macs_in_event = 0;
14064   u32 learn_limit = 0;
14065   int ret;
14066
14067   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (line_input, "learn-limit %d", &learn_limit))
14070         ;
14071       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14072         ;
14073       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14074         ;
14075       else if (unformat (line_input, "disable"))
14076         enable_disable = 0;
14077       else
14078         break;
14079     }
14080
14081   M (WANT_L2_MACS_EVENTS, mp);
14082   mp->enable_disable = enable_disable;
14083   mp->pid = htonl (getpid ());
14084   mp->learn_limit = htonl (learn_limit);
14085   mp->scan_delay = (u8) scan_delay;
14086   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14087   S (mp);
14088   W (ret);
14089   return ret;
14090 }
14091
14092 static int
14093 api_input_acl_set_interface (vat_main_t * vam)
14094 {
14095   unformat_input_t *i = vam->input;
14096   vl_api_input_acl_set_interface_t *mp;
14097   u32 sw_if_index;
14098   int sw_if_index_set;
14099   u32 ip4_table_index = ~0;
14100   u32 ip6_table_index = ~0;
14101   u32 l2_table_index = ~0;
14102   u8 is_add = 1;
14103   int ret;
14104
14105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14108         sw_if_index_set = 1;
14109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14110         sw_if_index_set = 1;
14111       else if (unformat (i, "del"))
14112         is_add = 0;
14113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14114         ;
14115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14116         ;
14117       else if (unformat (i, "l2-table %d", &l2_table_index))
14118         ;
14119       else
14120         {
14121           clib_warning ("parse error '%U'", format_unformat_error, i);
14122           return -99;
14123         }
14124     }
14125
14126   if (sw_if_index_set == 0)
14127     {
14128       errmsg ("missing interface name or sw_if_index");
14129       return -99;
14130     }
14131
14132   M (INPUT_ACL_SET_INTERFACE, mp);
14133
14134   mp->sw_if_index = ntohl (sw_if_index);
14135   mp->ip4_table_index = ntohl (ip4_table_index);
14136   mp->ip6_table_index = ntohl (ip6_table_index);
14137   mp->l2_table_index = ntohl (l2_table_index);
14138   mp->is_add = is_add;
14139
14140   S (mp);
14141   W (ret);
14142   return ret;
14143 }
14144
14145 static int
14146 api_ip_address_dump (vat_main_t * vam)
14147 {
14148   unformat_input_t *i = vam->input;
14149   vl_api_ip_address_dump_t *mp;
14150   vl_api_control_ping_t *mp_ping;
14151   u32 sw_if_index = ~0;
14152   u8 sw_if_index_set = 0;
14153   u8 ipv4_set = 0;
14154   u8 ipv6_set = 0;
14155   int ret;
14156
14157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14158     {
14159       if (unformat (i, "sw_if_index %d", &sw_if_index))
14160         sw_if_index_set = 1;
14161       else
14162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14163         sw_if_index_set = 1;
14164       else if (unformat (i, "ipv4"))
14165         ipv4_set = 1;
14166       else if (unformat (i, "ipv6"))
14167         ipv6_set = 1;
14168       else
14169         break;
14170     }
14171
14172   if (ipv4_set && ipv6_set)
14173     {
14174       errmsg ("ipv4 and ipv6 flags cannot be both set");
14175       return -99;
14176     }
14177
14178   if ((!ipv4_set) && (!ipv6_set))
14179     {
14180       errmsg ("no ipv4 nor ipv6 flag set");
14181       return -99;
14182     }
14183
14184   if (sw_if_index_set == 0)
14185     {
14186       errmsg ("missing interface name or sw_if_index");
14187       return -99;
14188     }
14189
14190   vam->current_sw_if_index = sw_if_index;
14191   vam->is_ipv6 = ipv6_set;
14192
14193   M (IP_ADDRESS_DUMP, mp);
14194   mp->sw_if_index = ntohl (sw_if_index);
14195   mp->is_ipv6 = ipv6_set;
14196   S (mp);
14197
14198   /* Use a control ping for synchronization */
14199   MPING (CONTROL_PING, mp_ping);
14200   S (mp_ping);
14201
14202   W (ret);
14203   return ret;
14204 }
14205
14206 static int
14207 api_ip_dump (vat_main_t * vam)
14208 {
14209   vl_api_ip_dump_t *mp;
14210   vl_api_control_ping_t *mp_ping;
14211   unformat_input_t *in = vam->input;
14212   int ipv4_set = 0;
14213   int ipv6_set = 0;
14214   int is_ipv6;
14215   int i;
14216   int ret;
14217
14218   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (in, "ipv4"))
14221         ipv4_set = 1;
14222       else if (unformat (in, "ipv6"))
14223         ipv6_set = 1;
14224       else
14225         break;
14226     }
14227
14228   if (ipv4_set && ipv6_set)
14229     {
14230       errmsg ("ipv4 and ipv6 flags cannot be both set");
14231       return -99;
14232     }
14233
14234   if ((!ipv4_set) && (!ipv6_set))
14235     {
14236       errmsg ("no ipv4 nor ipv6 flag set");
14237       return -99;
14238     }
14239
14240   is_ipv6 = ipv6_set;
14241   vam->is_ipv6 = is_ipv6;
14242
14243   /* free old data */
14244   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14245     {
14246       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14247     }
14248   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14249
14250   M (IP_DUMP, mp);
14251   mp->is_ipv6 = ipv6_set;
14252   S (mp);
14253
14254   /* Use a control ping for synchronization */
14255   MPING (CONTROL_PING, mp_ping);
14256   S (mp_ping);
14257
14258   W (ret);
14259   return ret;
14260 }
14261
14262 static int
14263 api_ipsec_spd_add_del (vat_main_t * vam)
14264 {
14265   unformat_input_t *i = vam->input;
14266   vl_api_ipsec_spd_add_del_t *mp;
14267   u32 spd_id = ~0;
14268   u8 is_add = 1;
14269   int ret;
14270
14271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14272     {
14273       if (unformat (i, "spd_id %d", &spd_id))
14274         ;
14275       else if (unformat (i, "del"))
14276         is_add = 0;
14277       else
14278         {
14279           clib_warning ("parse error '%U'", format_unformat_error, i);
14280           return -99;
14281         }
14282     }
14283   if (spd_id == ~0)
14284     {
14285       errmsg ("spd_id must be set");
14286       return -99;
14287     }
14288
14289   M (IPSEC_SPD_ADD_DEL, mp);
14290
14291   mp->spd_id = ntohl (spd_id);
14292   mp->is_add = is_add;
14293
14294   S (mp);
14295   W (ret);
14296   return ret;
14297 }
14298
14299 static int
14300 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14301 {
14302   unformat_input_t *i = vam->input;
14303   vl_api_ipsec_interface_add_del_spd_t *mp;
14304   u32 sw_if_index;
14305   u8 sw_if_index_set = 0;
14306   u32 spd_id = (u32) ~ 0;
14307   u8 is_add = 1;
14308   int ret;
14309
14310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14311     {
14312       if (unformat (i, "del"))
14313         is_add = 0;
14314       else if (unformat (i, "spd_id %d", &spd_id))
14315         ;
14316       else
14317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14318         sw_if_index_set = 1;
14319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14320         sw_if_index_set = 1;
14321       else
14322         {
14323           clib_warning ("parse error '%U'", format_unformat_error, i);
14324           return -99;
14325         }
14326
14327     }
14328
14329   if (spd_id == (u32) ~ 0)
14330     {
14331       errmsg ("spd_id must be set");
14332       return -99;
14333     }
14334
14335   if (sw_if_index_set == 0)
14336     {
14337       errmsg ("missing interface name or sw_if_index");
14338       return -99;
14339     }
14340
14341   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14342
14343   mp->spd_id = ntohl (spd_id);
14344   mp->sw_if_index = ntohl (sw_if_index);
14345   mp->is_add = is_add;
14346
14347   S (mp);
14348   W (ret);
14349   return ret;
14350 }
14351
14352 static int
14353 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14354 {
14355   unformat_input_t *i = vam->input;
14356   vl_api_ipsec_spd_add_del_entry_t *mp;
14357   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14358   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14359   i32 priority = 0;
14360   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14361   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14362   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14363   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14364   int ret;
14365
14366   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14367   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14368   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14369   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14370   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14371   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14372
14373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14374     {
14375       if (unformat (i, "del"))
14376         is_add = 0;
14377       if (unformat (i, "outbound"))
14378         is_outbound = 1;
14379       if (unformat (i, "inbound"))
14380         is_outbound = 0;
14381       else if (unformat (i, "spd_id %d", &spd_id))
14382         ;
14383       else if (unformat (i, "sa_id %d", &sa_id))
14384         ;
14385       else if (unformat (i, "priority %d", &priority))
14386         ;
14387       else if (unformat (i, "protocol %d", &protocol))
14388         ;
14389       else if (unformat (i, "lport_start %d", &lport_start))
14390         ;
14391       else if (unformat (i, "lport_stop %d", &lport_stop))
14392         ;
14393       else if (unformat (i, "rport_start %d", &rport_start))
14394         ;
14395       else if (unformat (i, "rport_stop %d", &rport_stop))
14396         ;
14397       else
14398         if (unformat
14399             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14400         {
14401           is_ipv6 = 0;
14402           is_ip_any = 0;
14403         }
14404       else
14405         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14406         {
14407           is_ipv6 = 0;
14408           is_ip_any = 0;
14409         }
14410       else
14411         if (unformat
14412             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14413         {
14414           is_ipv6 = 0;
14415           is_ip_any = 0;
14416         }
14417       else
14418         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14419         {
14420           is_ipv6 = 0;
14421           is_ip_any = 0;
14422         }
14423       else
14424         if (unformat
14425             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14426         {
14427           is_ipv6 = 1;
14428           is_ip_any = 0;
14429         }
14430       else
14431         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14432         {
14433           is_ipv6 = 1;
14434           is_ip_any = 0;
14435         }
14436       else
14437         if (unformat
14438             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14439         {
14440           is_ipv6 = 1;
14441           is_ip_any = 0;
14442         }
14443       else
14444         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14445         {
14446           is_ipv6 = 1;
14447           is_ip_any = 0;
14448         }
14449       else
14450         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14451         {
14452           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14453             {
14454               clib_warning ("unsupported action: 'resolve'");
14455               return -99;
14456             }
14457         }
14458       else
14459         {
14460           clib_warning ("parse error '%U'", format_unformat_error, i);
14461           return -99;
14462         }
14463
14464     }
14465
14466   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14467
14468   mp->spd_id = ntohl (spd_id);
14469   mp->priority = ntohl (priority);
14470   mp->is_outbound = is_outbound;
14471
14472   mp->is_ipv6 = is_ipv6;
14473   if (is_ipv6 || is_ip_any)
14474     {
14475       clib_memcpy (mp->remote_address_start, &raddr6_start,
14476                    sizeof (ip6_address_t));
14477       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14478                    sizeof (ip6_address_t));
14479       clib_memcpy (mp->local_address_start, &laddr6_start,
14480                    sizeof (ip6_address_t));
14481       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14482                    sizeof (ip6_address_t));
14483     }
14484   else
14485     {
14486       clib_memcpy (mp->remote_address_start, &raddr4_start,
14487                    sizeof (ip4_address_t));
14488       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14489                    sizeof (ip4_address_t));
14490       clib_memcpy (mp->local_address_start, &laddr4_start,
14491                    sizeof (ip4_address_t));
14492       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14493                    sizeof (ip4_address_t));
14494     }
14495   mp->protocol = (u8) protocol;
14496   mp->local_port_start = ntohs ((u16) lport_start);
14497   mp->local_port_stop = ntohs ((u16) lport_stop);
14498   mp->remote_port_start = ntohs ((u16) rport_start);
14499   mp->remote_port_stop = ntohs ((u16) rport_stop);
14500   mp->policy = (u8) policy;
14501   mp->sa_id = ntohl (sa_id);
14502   mp->is_add = is_add;
14503   mp->is_ip_any = is_ip_any;
14504   S (mp);
14505   W (ret);
14506   return ret;
14507 }
14508
14509 static int
14510 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14511 {
14512   unformat_input_t *i = vam->input;
14513   vl_api_ipsec_sad_add_del_entry_t *mp;
14514   u32 sad_id = 0, spi = 0;
14515   u8 *ck = 0, *ik = 0;
14516   u8 is_add = 1;
14517
14518   u8 protocol = IPSEC_PROTOCOL_AH;
14519   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14520   u32 crypto_alg = 0, integ_alg = 0;
14521   ip4_address_t tun_src4;
14522   ip4_address_t tun_dst4;
14523   ip6_address_t tun_src6;
14524   ip6_address_t tun_dst6;
14525   int ret;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "del"))
14530         is_add = 0;
14531       else if (unformat (i, "sad_id %d", &sad_id))
14532         ;
14533       else if (unformat (i, "spi %d", &spi))
14534         ;
14535       else if (unformat (i, "esp"))
14536         protocol = IPSEC_PROTOCOL_ESP;
14537       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14538         {
14539           is_tunnel = 1;
14540           is_tunnel_ipv6 = 0;
14541         }
14542       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14543         {
14544           is_tunnel = 1;
14545           is_tunnel_ipv6 = 0;
14546         }
14547       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14548         {
14549           is_tunnel = 1;
14550           is_tunnel_ipv6 = 1;
14551         }
14552       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14553         {
14554           is_tunnel = 1;
14555           is_tunnel_ipv6 = 1;
14556         }
14557       else
14558         if (unformat
14559             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14560         {
14561           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14562               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14563             {
14564               clib_warning ("unsupported crypto-alg: '%U'",
14565                             format_ipsec_crypto_alg, crypto_alg);
14566               return -99;
14567             }
14568         }
14569       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14570         ;
14571       else
14572         if (unformat
14573             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14574         {
14575           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14576               integ_alg >= IPSEC_INTEG_N_ALG)
14577             {
14578               clib_warning ("unsupported integ-alg: '%U'",
14579                             format_ipsec_integ_alg, integ_alg);
14580               return -99;
14581             }
14582         }
14583       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14584         ;
14585       else
14586         {
14587           clib_warning ("parse error '%U'", format_unformat_error, i);
14588           return -99;
14589         }
14590
14591     }
14592
14593   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14594
14595   mp->sad_id = ntohl (sad_id);
14596   mp->is_add = is_add;
14597   mp->protocol = protocol;
14598   mp->spi = ntohl (spi);
14599   mp->is_tunnel = is_tunnel;
14600   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14601   mp->crypto_algorithm = crypto_alg;
14602   mp->integrity_algorithm = integ_alg;
14603   mp->crypto_key_length = vec_len (ck);
14604   mp->integrity_key_length = vec_len (ik);
14605
14606   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14607     mp->crypto_key_length = sizeof (mp->crypto_key);
14608
14609   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14610     mp->integrity_key_length = sizeof (mp->integrity_key);
14611
14612   if (ck)
14613     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14614   if (ik)
14615     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14616
14617   if (is_tunnel)
14618     {
14619       if (is_tunnel_ipv6)
14620         {
14621           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14622                        sizeof (ip6_address_t));
14623           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14624                        sizeof (ip6_address_t));
14625         }
14626       else
14627         {
14628           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14629                        sizeof (ip4_address_t));
14630           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14631                        sizeof (ip4_address_t));
14632         }
14633     }
14634
14635   S (mp);
14636   W (ret);
14637   return ret;
14638 }
14639
14640 static int
14641 api_ipsec_sa_set_key (vat_main_t * vam)
14642 {
14643   unformat_input_t *i = vam->input;
14644   vl_api_ipsec_sa_set_key_t *mp;
14645   u32 sa_id;
14646   u8 *ck = 0, *ik = 0;
14647   int ret;
14648
14649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (i, "sa_id %d", &sa_id))
14652         ;
14653       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14654         ;
14655       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14656         ;
14657       else
14658         {
14659           clib_warning ("parse error '%U'", format_unformat_error, i);
14660           return -99;
14661         }
14662     }
14663
14664   M (IPSEC_SA_SET_KEY, mp);
14665
14666   mp->sa_id = ntohl (sa_id);
14667   mp->crypto_key_length = vec_len (ck);
14668   mp->integrity_key_length = vec_len (ik);
14669
14670   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14671     mp->crypto_key_length = sizeof (mp->crypto_key);
14672
14673   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14674     mp->integrity_key_length = sizeof (mp->integrity_key);
14675
14676   if (ck)
14677     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14678   if (ik)
14679     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14680
14681   S (mp);
14682   W (ret);
14683   return ret;
14684 }
14685
14686 static int
14687 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14688 {
14689   unformat_input_t *i = vam->input;
14690   vl_api_ipsec_tunnel_if_add_del_t *mp;
14691   u32 local_spi = 0, remote_spi = 0;
14692   u32 crypto_alg = 0, integ_alg = 0;
14693   u8 *lck = NULL, *rck = NULL;
14694   u8 *lik = NULL, *rik = NULL;
14695   ip4_address_t local_ip = { {0} };
14696   ip4_address_t remote_ip = { {0} };
14697   u8 is_add = 1;
14698   u8 esn = 0;
14699   u8 anti_replay = 0;
14700   int ret;
14701
14702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14703     {
14704       if (unformat (i, "del"))
14705         is_add = 0;
14706       else if (unformat (i, "esn"))
14707         esn = 1;
14708       else if (unformat (i, "anti_replay"))
14709         anti_replay = 1;
14710       else if (unformat (i, "local_spi %d", &local_spi))
14711         ;
14712       else if (unformat (i, "remote_spi %d", &remote_spi))
14713         ;
14714       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14715         ;
14716       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14717         ;
14718       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14719         ;
14720       else
14721         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14722         ;
14723       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14724         ;
14725       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14726         ;
14727       else
14728         if (unformat
14729             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14730         {
14731           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14732               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14733             {
14734               errmsg ("unsupported crypto-alg: '%U'\n",
14735                       format_ipsec_crypto_alg, crypto_alg);
14736               return -99;
14737             }
14738         }
14739       else
14740         if (unformat
14741             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14742         {
14743           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14744               integ_alg >= IPSEC_INTEG_N_ALG)
14745             {
14746               errmsg ("unsupported integ-alg: '%U'\n",
14747                       format_ipsec_integ_alg, integ_alg);
14748               return -99;
14749             }
14750         }
14751       else
14752         {
14753           errmsg ("parse error '%U'\n", format_unformat_error, i);
14754           return -99;
14755         }
14756     }
14757
14758   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14759
14760   mp->is_add = is_add;
14761   mp->esn = esn;
14762   mp->anti_replay = anti_replay;
14763
14764   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14765   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14766
14767   mp->local_spi = htonl (local_spi);
14768   mp->remote_spi = htonl (remote_spi);
14769   mp->crypto_alg = (u8) crypto_alg;
14770
14771   mp->local_crypto_key_len = 0;
14772   if (lck)
14773     {
14774       mp->local_crypto_key_len = vec_len (lck);
14775       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14776         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14777       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14778     }
14779
14780   mp->remote_crypto_key_len = 0;
14781   if (rck)
14782     {
14783       mp->remote_crypto_key_len = vec_len (rck);
14784       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14785         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14786       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14787     }
14788
14789   mp->integ_alg = (u8) integ_alg;
14790
14791   mp->local_integ_key_len = 0;
14792   if (lik)
14793     {
14794       mp->local_integ_key_len = vec_len (lik);
14795       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14796         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14797       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14798     }
14799
14800   mp->remote_integ_key_len = 0;
14801   if (rik)
14802     {
14803       mp->remote_integ_key_len = vec_len (rik);
14804       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14805         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14806       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14807     }
14808
14809   S (mp);
14810   W (ret);
14811   return ret;
14812 }
14813
14814 static void
14815 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14816 {
14817   vat_main_t *vam = &vat_main;
14818
14819   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14820          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14821          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14822          "tunnel_src_addr %U tunnel_dst_addr %U "
14823          "salt %u seq_outbound %lu last_seq_inbound %lu "
14824          "replay_window %lu total_data_size %lu\n",
14825          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14826          mp->protocol,
14827          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14828          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14829          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14830          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14831          mp->tunnel_src_addr,
14832          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14833          mp->tunnel_dst_addr,
14834          ntohl (mp->salt),
14835          clib_net_to_host_u64 (mp->seq_outbound),
14836          clib_net_to_host_u64 (mp->last_seq_inbound),
14837          clib_net_to_host_u64 (mp->replay_window),
14838          clib_net_to_host_u64 (mp->total_data_size));
14839 }
14840
14841 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14842 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14843
14844 static void vl_api_ipsec_sa_details_t_handler_json
14845   (vl_api_ipsec_sa_details_t * mp)
14846 {
14847   vat_main_t *vam = &vat_main;
14848   vat_json_node_t *node = NULL;
14849   struct in_addr src_ip4, dst_ip4;
14850   struct in6_addr src_ip6, dst_ip6;
14851
14852   if (VAT_JSON_ARRAY != vam->json_tree.type)
14853     {
14854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14855       vat_json_init_array (&vam->json_tree);
14856     }
14857   node = vat_json_array_add (&vam->json_tree);
14858
14859   vat_json_init_object (node);
14860   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14862   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14863   vat_json_object_add_uint (node, "proto", mp->protocol);
14864   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14865   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14866   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14867   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14868   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14869   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14870   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14871                              mp->crypto_key_len);
14872   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14873                              mp->integ_key_len);
14874   if (mp->is_tunnel_ip6)
14875     {
14876       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14877       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14878       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14879       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14880     }
14881   else
14882     {
14883       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14884       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14885       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14886       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14887     }
14888   vat_json_object_add_uint (node, "replay_window",
14889                             clib_net_to_host_u64 (mp->replay_window));
14890   vat_json_object_add_uint (node, "total_data_size",
14891                             clib_net_to_host_u64 (mp->total_data_size));
14892
14893 }
14894
14895 static int
14896 api_ipsec_sa_dump (vat_main_t * vam)
14897 {
14898   unformat_input_t *i = vam->input;
14899   vl_api_ipsec_sa_dump_t *mp;
14900   vl_api_control_ping_t *mp_ping;
14901   u32 sa_id = ~0;
14902   int ret;
14903
14904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14905     {
14906       if (unformat (i, "sa_id %d", &sa_id))
14907         ;
14908       else
14909         {
14910           clib_warning ("parse error '%U'", format_unformat_error, i);
14911           return -99;
14912         }
14913     }
14914
14915   M (IPSEC_SA_DUMP, mp);
14916
14917   mp->sa_id = ntohl (sa_id);
14918
14919   S (mp);
14920
14921   /* Use a control ping for synchronization */
14922   M (CONTROL_PING, mp_ping);
14923   S (mp_ping);
14924
14925   W (ret);
14926   return ret;
14927 }
14928
14929 static int
14930 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14931 {
14932   unformat_input_t *i = vam->input;
14933   vl_api_ipsec_tunnel_if_set_key_t *mp;
14934   u32 sw_if_index = ~0;
14935   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14936   u8 *key = 0;
14937   u32 alg = ~0;
14938   int ret;
14939
14940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14941     {
14942       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14943         ;
14944       else
14945         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14946         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14947       else
14948         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14949         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14950       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14951         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14952       else
14953         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14954         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14955       else if (unformat (i, "%U", unformat_hex_string, &key))
14956         ;
14957       else
14958         {
14959           clib_warning ("parse error '%U'", format_unformat_error, i);
14960           return -99;
14961         }
14962     }
14963
14964   if (sw_if_index == ~0)
14965     {
14966       errmsg ("interface must be specified");
14967       return -99;
14968     }
14969
14970   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14971     {
14972       errmsg ("key type must be specified");
14973       return -99;
14974     }
14975
14976   if (alg == ~0)
14977     {
14978       errmsg ("algorithm must be specified");
14979       return -99;
14980     }
14981
14982   if (vec_len (key) == 0)
14983     {
14984       errmsg ("key must be specified");
14985       return -99;
14986     }
14987
14988   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14989
14990   mp->sw_if_index = htonl (sw_if_index);
14991   mp->alg = alg;
14992   mp->key_type = key_type;
14993   mp->key_len = vec_len (key);
14994   clib_memcpy (mp->key, key, vec_len (key));
14995
14996   S (mp);
14997   W (ret);
14998
14999   return ret;
15000 }
15001
15002 static int
15003 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15004 {
15005   unformat_input_t *i = vam->input;
15006   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15007   u32 sw_if_index = ~0;
15008   u32 sa_id = ~0;
15009   u8 is_outbound = (u8) ~ 0;
15010   int ret;
15011
15012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15013     {
15014       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15015         ;
15016       else if (unformat (i, "sa_id %d", &sa_id))
15017         ;
15018       else if (unformat (i, "outbound"))
15019         is_outbound = 1;
15020       else if (unformat (i, "inbound"))
15021         is_outbound = 0;
15022       else
15023         {
15024           clib_warning ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027     }
15028
15029   if (sw_if_index == ~0)
15030     {
15031       errmsg ("interface must be specified");
15032       return -99;
15033     }
15034
15035   if (sa_id == ~0)
15036     {
15037       errmsg ("SA ID must be specified");
15038       return -99;
15039     }
15040
15041   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15042
15043   mp->sw_if_index = htonl (sw_if_index);
15044   mp->sa_id = htonl (sa_id);
15045   mp->is_outbound = is_outbound;
15046
15047   S (mp);
15048   W (ret);
15049
15050   return ret;
15051 }
15052
15053 static int
15054 api_ikev2_profile_add_del (vat_main_t * vam)
15055 {
15056   unformat_input_t *i = vam->input;
15057   vl_api_ikev2_profile_add_del_t *mp;
15058   u8 is_add = 1;
15059   u8 *name = 0;
15060   int ret;
15061
15062   const char *valid_chars = "a-zA-Z0-9_";
15063
15064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15065     {
15066       if (unformat (i, "del"))
15067         is_add = 0;
15068       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15069         vec_add1 (name, 0);
15070       else
15071         {
15072           errmsg ("parse error '%U'", format_unformat_error, i);
15073           return -99;
15074         }
15075     }
15076
15077   if (!vec_len (name))
15078     {
15079       errmsg ("profile name must be specified");
15080       return -99;
15081     }
15082
15083   if (vec_len (name) > 64)
15084     {
15085       errmsg ("profile name too long");
15086       return -99;
15087     }
15088
15089   M (IKEV2_PROFILE_ADD_DEL, mp);
15090
15091   clib_memcpy (mp->name, name, vec_len (name));
15092   mp->is_add = is_add;
15093   vec_free (name);
15094
15095   S (mp);
15096   W (ret);
15097   return ret;
15098 }
15099
15100 static int
15101 api_ikev2_profile_set_auth (vat_main_t * vam)
15102 {
15103   unformat_input_t *i = vam->input;
15104   vl_api_ikev2_profile_set_auth_t *mp;
15105   u8 *name = 0;
15106   u8 *data = 0;
15107   u32 auth_method = 0;
15108   u8 is_hex = 0;
15109   int ret;
15110
15111   const char *valid_chars = "a-zA-Z0-9_";
15112
15113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15114     {
15115       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15116         vec_add1 (name, 0);
15117       else if (unformat (i, "auth_method %U",
15118                          unformat_ikev2_auth_method, &auth_method))
15119         ;
15120       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15121         is_hex = 1;
15122       else if (unformat (i, "auth_data %v", &data))
15123         ;
15124       else
15125         {
15126           errmsg ("parse error '%U'", format_unformat_error, i);
15127           return -99;
15128         }
15129     }
15130
15131   if (!vec_len (name))
15132     {
15133       errmsg ("profile name must be specified");
15134       return -99;
15135     }
15136
15137   if (vec_len (name) > 64)
15138     {
15139       errmsg ("profile name too long");
15140       return -99;
15141     }
15142
15143   if (!vec_len (data))
15144     {
15145       errmsg ("auth_data must be specified");
15146       return -99;
15147     }
15148
15149   if (!auth_method)
15150     {
15151       errmsg ("auth_method must be specified");
15152       return -99;
15153     }
15154
15155   M (IKEV2_PROFILE_SET_AUTH, mp);
15156
15157   mp->is_hex = is_hex;
15158   mp->auth_method = (u8) auth_method;
15159   mp->data_len = vec_len (data);
15160   clib_memcpy (mp->name, name, vec_len (name));
15161   clib_memcpy (mp->data, data, vec_len (data));
15162   vec_free (name);
15163   vec_free (data);
15164
15165   S (mp);
15166   W (ret);
15167   return ret;
15168 }
15169
15170 static int
15171 api_ikev2_profile_set_id (vat_main_t * vam)
15172 {
15173   unformat_input_t *i = vam->input;
15174   vl_api_ikev2_profile_set_id_t *mp;
15175   u8 *name = 0;
15176   u8 *data = 0;
15177   u8 is_local = 0;
15178   u32 id_type = 0;
15179   ip4_address_t ip4;
15180   int ret;
15181
15182   const char *valid_chars = "a-zA-Z0-9_";
15183
15184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15185     {
15186       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15187         vec_add1 (name, 0);
15188       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15189         ;
15190       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15191         {
15192           data = vec_new (u8, 4);
15193           clib_memcpy (data, ip4.as_u8, 4);
15194         }
15195       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15196         ;
15197       else if (unformat (i, "id_data %v", &data))
15198         ;
15199       else if (unformat (i, "local"))
15200         is_local = 1;
15201       else if (unformat (i, "remote"))
15202         is_local = 0;
15203       else
15204         {
15205           errmsg ("parse error '%U'", format_unformat_error, i);
15206           return -99;
15207         }
15208     }
15209
15210   if (!vec_len (name))
15211     {
15212       errmsg ("profile name must be specified");
15213       return -99;
15214     }
15215
15216   if (vec_len (name) > 64)
15217     {
15218       errmsg ("profile name too long");
15219       return -99;
15220     }
15221
15222   if (!vec_len (data))
15223     {
15224       errmsg ("id_data must be specified");
15225       return -99;
15226     }
15227
15228   if (!id_type)
15229     {
15230       errmsg ("id_type must be specified");
15231       return -99;
15232     }
15233
15234   M (IKEV2_PROFILE_SET_ID, mp);
15235
15236   mp->is_local = is_local;
15237   mp->id_type = (u8) id_type;
15238   mp->data_len = vec_len (data);
15239   clib_memcpy (mp->name, name, vec_len (name));
15240   clib_memcpy (mp->data, data, vec_len (data));
15241   vec_free (name);
15242   vec_free (data);
15243
15244   S (mp);
15245   W (ret);
15246   return ret;
15247 }
15248
15249 static int
15250 api_ikev2_profile_set_ts (vat_main_t * vam)
15251 {
15252   unformat_input_t *i = vam->input;
15253   vl_api_ikev2_profile_set_ts_t *mp;
15254   u8 *name = 0;
15255   u8 is_local = 0;
15256   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15257   ip4_address_t start_addr, end_addr;
15258
15259   const char *valid_chars = "a-zA-Z0-9_";
15260   int ret;
15261
15262   start_addr.as_u32 = 0;
15263   end_addr.as_u32 = (u32) ~ 0;
15264
15265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15266     {
15267       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15268         vec_add1 (name, 0);
15269       else if (unformat (i, "protocol %d", &proto))
15270         ;
15271       else if (unformat (i, "start_port %d", &start_port))
15272         ;
15273       else if (unformat (i, "end_port %d", &end_port))
15274         ;
15275       else
15276         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15277         ;
15278       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15279         ;
15280       else if (unformat (i, "local"))
15281         is_local = 1;
15282       else if (unformat (i, "remote"))
15283         is_local = 0;
15284       else
15285         {
15286           errmsg ("parse error '%U'", format_unformat_error, i);
15287           return -99;
15288         }
15289     }
15290
15291   if (!vec_len (name))
15292     {
15293       errmsg ("profile name must be specified");
15294       return -99;
15295     }
15296
15297   if (vec_len (name) > 64)
15298     {
15299       errmsg ("profile name too long");
15300       return -99;
15301     }
15302
15303   M (IKEV2_PROFILE_SET_TS, mp);
15304
15305   mp->is_local = is_local;
15306   mp->proto = (u8) proto;
15307   mp->start_port = (u16) start_port;
15308   mp->end_port = (u16) end_port;
15309   mp->start_addr = start_addr.as_u32;
15310   mp->end_addr = end_addr.as_u32;
15311   clib_memcpy (mp->name, name, vec_len (name));
15312   vec_free (name);
15313
15314   S (mp);
15315   W (ret);
15316   return ret;
15317 }
15318
15319 static int
15320 api_ikev2_set_local_key (vat_main_t * vam)
15321 {
15322   unformat_input_t *i = vam->input;
15323   vl_api_ikev2_set_local_key_t *mp;
15324   u8 *file = 0;
15325   int ret;
15326
15327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15328     {
15329       if (unformat (i, "file %v", &file))
15330         vec_add1 (file, 0);
15331       else
15332         {
15333           errmsg ("parse error '%U'", format_unformat_error, i);
15334           return -99;
15335         }
15336     }
15337
15338   if (!vec_len (file))
15339     {
15340       errmsg ("RSA key file must be specified");
15341       return -99;
15342     }
15343
15344   if (vec_len (file) > 256)
15345     {
15346       errmsg ("file name too long");
15347       return -99;
15348     }
15349
15350   M (IKEV2_SET_LOCAL_KEY, mp);
15351
15352   clib_memcpy (mp->key_file, file, vec_len (file));
15353   vec_free (file);
15354
15355   S (mp);
15356   W (ret);
15357   return ret;
15358 }
15359
15360 static int
15361 api_ikev2_set_responder (vat_main_t * vam)
15362 {
15363   unformat_input_t *i = vam->input;
15364   vl_api_ikev2_set_responder_t *mp;
15365   int ret;
15366   u8 *name = 0;
15367   u32 sw_if_index = ~0;
15368   ip4_address_t address;
15369
15370   const char *valid_chars = "a-zA-Z0-9_";
15371
15372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15373     {
15374       if (unformat
15375           (i, "%U interface %d address %U", unformat_token, valid_chars,
15376            &name, &sw_if_index, unformat_ip4_address, &address))
15377         vec_add1 (name, 0);
15378       else
15379         {
15380           errmsg ("parse error '%U'", format_unformat_error, i);
15381           return -99;
15382         }
15383     }
15384
15385   if (!vec_len (name))
15386     {
15387       errmsg ("profile name must be specified");
15388       return -99;
15389     }
15390
15391   if (vec_len (name) > 64)
15392     {
15393       errmsg ("profile name too long");
15394       return -99;
15395     }
15396
15397   M (IKEV2_SET_RESPONDER, mp);
15398
15399   clib_memcpy (mp->name, name, vec_len (name));
15400   vec_free (name);
15401
15402   mp->sw_if_index = sw_if_index;
15403   clib_memcpy (mp->address, &address, sizeof (address));
15404
15405   S (mp);
15406   W (ret);
15407   return ret;
15408 }
15409
15410 static int
15411 api_ikev2_set_ike_transforms (vat_main_t * vam)
15412 {
15413   unformat_input_t *i = vam->input;
15414   vl_api_ikev2_set_ike_transforms_t *mp;
15415   int ret;
15416   u8 *name = 0;
15417   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15418
15419   const char *valid_chars = "a-zA-Z0-9_";
15420
15421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15422     {
15423       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15424                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15425         vec_add1 (name, 0);
15426       else
15427         {
15428           errmsg ("parse error '%U'", format_unformat_error, i);
15429           return -99;
15430         }
15431     }
15432
15433   if (!vec_len (name))
15434     {
15435       errmsg ("profile name must be specified");
15436       return -99;
15437     }
15438
15439   if (vec_len (name) > 64)
15440     {
15441       errmsg ("profile name too long");
15442       return -99;
15443     }
15444
15445   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15446
15447   clib_memcpy (mp->name, name, vec_len (name));
15448   vec_free (name);
15449   mp->crypto_alg = crypto_alg;
15450   mp->crypto_key_size = crypto_key_size;
15451   mp->integ_alg = integ_alg;
15452   mp->dh_group = dh_group;
15453
15454   S (mp);
15455   W (ret);
15456   return ret;
15457 }
15458
15459
15460 static int
15461 api_ikev2_set_esp_transforms (vat_main_t * vam)
15462 {
15463   unformat_input_t *i = vam->input;
15464   vl_api_ikev2_set_esp_transforms_t *mp;
15465   int ret;
15466   u8 *name = 0;
15467   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15468
15469   const char *valid_chars = "a-zA-Z0-9_";
15470
15471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15472     {
15473       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15474                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15475         vec_add1 (name, 0);
15476       else
15477         {
15478           errmsg ("parse error '%U'", format_unformat_error, i);
15479           return -99;
15480         }
15481     }
15482
15483   if (!vec_len (name))
15484     {
15485       errmsg ("profile name must be specified");
15486       return -99;
15487     }
15488
15489   if (vec_len (name) > 64)
15490     {
15491       errmsg ("profile name too long");
15492       return -99;
15493     }
15494
15495   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15496
15497   clib_memcpy (mp->name, name, vec_len (name));
15498   vec_free (name);
15499   mp->crypto_alg = crypto_alg;
15500   mp->crypto_key_size = crypto_key_size;
15501   mp->integ_alg = integ_alg;
15502   mp->dh_group = dh_group;
15503
15504   S (mp);
15505   W (ret);
15506   return ret;
15507 }
15508
15509 static int
15510 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15511 {
15512   unformat_input_t *i = vam->input;
15513   vl_api_ikev2_set_sa_lifetime_t *mp;
15514   int ret;
15515   u8 *name = 0;
15516   u64 lifetime, lifetime_maxdata;
15517   u32 lifetime_jitter, handover;
15518
15519   const char *valid_chars = "a-zA-Z0-9_";
15520
15521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15522     {
15523       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15524                     &lifetime, &lifetime_jitter, &handover,
15525                     &lifetime_maxdata))
15526         vec_add1 (name, 0);
15527       else
15528         {
15529           errmsg ("parse error '%U'", format_unformat_error, i);
15530           return -99;
15531         }
15532     }
15533
15534   if (!vec_len (name))
15535     {
15536       errmsg ("profile name must be specified");
15537       return -99;
15538     }
15539
15540   if (vec_len (name) > 64)
15541     {
15542       errmsg ("profile name too long");
15543       return -99;
15544     }
15545
15546   M (IKEV2_SET_SA_LIFETIME, mp);
15547
15548   clib_memcpy (mp->name, name, vec_len (name));
15549   vec_free (name);
15550   mp->lifetime = lifetime;
15551   mp->lifetime_jitter = lifetime_jitter;
15552   mp->handover = handover;
15553   mp->lifetime_maxdata = lifetime_maxdata;
15554
15555   S (mp);
15556   W (ret);
15557   return ret;
15558 }
15559
15560 static int
15561 api_ikev2_initiate_sa_init (vat_main_t * vam)
15562 {
15563   unformat_input_t *i = vam->input;
15564   vl_api_ikev2_initiate_sa_init_t *mp;
15565   int ret;
15566   u8 *name = 0;
15567
15568   const char *valid_chars = "a-zA-Z0-9_";
15569
15570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15573         vec_add1 (name, 0);
15574       else
15575         {
15576           errmsg ("parse error '%U'", format_unformat_error, i);
15577           return -99;
15578         }
15579     }
15580
15581   if (!vec_len (name))
15582     {
15583       errmsg ("profile name must be specified");
15584       return -99;
15585     }
15586
15587   if (vec_len (name) > 64)
15588     {
15589       errmsg ("profile name too long");
15590       return -99;
15591     }
15592
15593   M (IKEV2_INITIATE_SA_INIT, mp);
15594
15595   clib_memcpy (mp->name, name, vec_len (name));
15596   vec_free (name);
15597
15598   S (mp);
15599   W (ret);
15600   return ret;
15601 }
15602
15603 static int
15604 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15605 {
15606   unformat_input_t *i = vam->input;
15607   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15608   int ret;
15609   u64 ispi;
15610
15611
15612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15613     {
15614       if (unformat (i, "%lx", &ispi))
15615         ;
15616       else
15617         {
15618           errmsg ("parse error '%U'", format_unformat_error, i);
15619           return -99;
15620         }
15621     }
15622
15623   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15624
15625   mp->ispi = ispi;
15626
15627   S (mp);
15628   W (ret);
15629   return ret;
15630 }
15631
15632 static int
15633 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15634 {
15635   unformat_input_t *i = vam->input;
15636   vl_api_ikev2_initiate_del_child_sa_t *mp;
15637   int ret;
15638   u32 ispi;
15639
15640
15641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15642     {
15643       if (unformat (i, "%x", &ispi))
15644         ;
15645       else
15646         {
15647           errmsg ("parse error '%U'", format_unformat_error, i);
15648           return -99;
15649         }
15650     }
15651
15652   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15653
15654   mp->ispi = ispi;
15655
15656   S (mp);
15657   W (ret);
15658   return ret;
15659 }
15660
15661 static int
15662 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15663 {
15664   unformat_input_t *i = vam->input;
15665   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15666   int ret;
15667   u32 ispi;
15668
15669
15670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15671     {
15672       if (unformat (i, "%x", &ispi))
15673         ;
15674       else
15675         {
15676           errmsg ("parse error '%U'", format_unformat_error, i);
15677           return -99;
15678         }
15679     }
15680
15681   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15682
15683   mp->ispi = ispi;
15684
15685   S (mp);
15686   W (ret);
15687   return ret;
15688 }
15689
15690 /*
15691  * MAP
15692  */
15693 static int
15694 api_map_add_domain (vat_main_t * vam)
15695 {
15696   unformat_input_t *i = vam->input;
15697   vl_api_map_add_domain_t *mp;
15698
15699   ip4_address_t ip4_prefix;
15700   ip6_address_t ip6_prefix;
15701   ip6_address_t ip6_src;
15702   u32 num_m_args = 0;
15703   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15704     0, psid_length = 0;
15705   u8 is_translation = 0;
15706   u32 mtu = 0;
15707   u32 ip6_src_len = 128;
15708   int ret;
15709
15710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15713                     &ip4_prefix, &ip4_prefix_len))
15714         num_m_args++;
15715       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15716                          &ip6_prefix, &ip6_prefix_len))
15717         num_m_args++;
15718       else
15719         if (unformat
15720             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15721              &ip6_src_len))
15722         num_m_args++;
15723       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15724         num_m_args++;
15725       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15726         num_m_args++;
15727       else if (unformat (i, "psid-offset %d", &psid_offset))
15728         num_m_args++;
15729       else if (unformat (i, "psid-len %d", &psid_length))
15730         num_m_args++;
15731       else if (unformat (i, "mtu %d", &mtu))
15732         num_m_args++;
15733       else if (unformat (i, "map-t"))
15734         is_translation = 1;
15735       else
15736         {
15737           clib_warning ("parse error '%U'", format_unformat_error, i);
15738           return -99;
15739         }
15740     }
15741
15742   if (num_m_args < 3)
15743     {
15744       errmsg ("mandatory argument(s) missing");
15745       return -99;
15746     }
15747
15748   /* Construct the API message */
15749   M (MAP_ADD_DOMAIN, mp);
15750
15751   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15752   mp->ip4_prefix_len = ip4_prefix_len;
15753
15754   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15755   mp->ip6_prefix_len = ip6_prefix_len;
15756
15757   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15758   mp->ip6_src_prefix_len = ip6_src_len;
15759
15760   mp->ea_bits_len = ea_bits_len;
15761   mp->psid_offset = psid_offset;
15762   mp->psid_length = psid_length;
15763   mp->is_translation = is_translation;
15764   mp->mtu = htons (mtu);
15765
15766   /* send it... */
15767   S (mp);
15768
15769   /* Wait for a reply, return good/bad news  */
15770   W (ret);
15771   return ret;
15772 }
15773
15774 static int
15775 api_map_del_domain (vat_main_t * vam)
15776 {
15777   unformat_input_t *i = vam->input;
15778   vl_api_map_del_domain_t *mp;
15779
15780   u32 num_m_args = 0;
15781   u32 index;
15782   int ret;
15783
15784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15785     {
15786       if (unformat (i, "index %d", &index))
15787         num_m_args++;
15788       else
15789         {
15790           clib_warning ("parse error '%U'", format_unformat_error, i);
15791           return -99;
15792         }
15793     }
15794
15795   if (num_m_args != 1)
15796     {
15797       errmsg ("mandatory argument(s) missing");
15798       return -99;
15799     }
15800
15801   /* Construct the API message */
15802   M (MAP_DEL_DOMAIN, mp);
15803
15804   mp->index = ntohl (index);
15805
15806   /* send it... */
15807   S (mp);
15808
15809   /* Wait for a reply, return good/bad news  */
15810   W (ret);
15811   return ret;
15812 }
15813
15814 static int
15815 api_map_add_del_rule (vat_main_t * vam)
15816 {
15817   unformat_input_t *i = vam->input;
15818   vl_api_map_add_del_rule_t *mp;
15819   u8 is_add = 1;
15820   ip6_address_t ip6_dst;
15821   u32 num_m_args = 0, index, psid = 0;
15822   int ret;
15823
15824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (i, "index %d", &index))
15827         num_m_args++;
15828       else if (unformat (i, "psid %d", &psid))
15829         num_m_args++;
15830       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15831         num_m_args++;
15832       else if (unformat (i, "del"))
15833         {
15834           is_add = 0;
15835         }
15836       else
15837         {
15838           clib_warning ("parse error '%U'", format_unformat_error, i);
15839           return -99;
15840         }
15841     }
15842
15843   /* Construct the API message */
15844   M (MAP_ADD_DEL_RULE, mp);
15845
15846   mp->index = ntohl (index);
15847   mp->is_add = is_add;
15848   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15849   mp->psid = ntohs (psid);
15850
15851   /* send it... */
15852   S (mp);
15853
15854   /* Wait for a reply, return good/bad news  */
15855   W (ret);
15856   return ret;
15857 }
15858
15859 static int
15860 api_map_domain_dump (vat_main_t * vam)
15861 {
15862   vl_api_map_domain_dump_t *mp;
15863   vl_api_control_ping_t *mp_ping;
15864   int ret;
15865
15866   /* Construct the API message */
15867   M (MAP_DOMAIN_DUMP, mp);
15868
15869   /* send it... */
15870   S (mp);
15871
15872   /* Use a control ping for synchronization */
15873   MPING (CONTROL_PING, mp_ping);
15874   S (mp_ping);
15875
15876   W (ret);
15877   return ret;
15878 }
15879
15880 static int
15881 api_map_rule_dump (vat_main_t * vam)
15882 {
15883   unformat_input_t *i = vam->input;
15884   vl_api_map_rule_dump_t *mp;
15885   vl_api_control_ping_t *mp_ping;
15886   u32 domain_index = ~0;
15887   int ret;
15888
15889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15890     {
15891       if (unformat (i, "index %u", &domain_index))
15892         ;
15893       else
15894         break;
15895     }
15896
15897   if (domain_index == ~0)
15898     {
15899       clib_warning ("parse error: domain index expected");
15900       return -99;
15901     }
15902
15903   /* Construct the API message */
15904   M (MAP_RULE_DUMP, mp);
15905
15906   mp->domain_index = htonl (domain_index);
15907
15908   /* send it... */
15909   S (mp);
15910
15911   /* Use a control ping for synchronization */
15912   MPING (CONTROL_PING, mp_ping);
15913   S (mp_ping);
15914
15915   W (ret);
15916   return ret;
15917 }
15918
15919 static void vl_api_map_add_domain_reply_t_handler
15920   (vl_api_map_add_domain_reply_t * mp)
15921 {
15922   vat_main_t *vam = &vat_main;
15923   i32 retval = ntohl (mp->retval);
15924
15925   if (vam->async_mode)
15926     {
15927       vam->async_errors += (retval < 0);
15928     }
15929   else
15930     {
15931       vam->retval = retval;
15932       vam->result_ready = 1;
15933     }
15934 }
15935
15936 static void vl_api_map_add_domain_reply_t_handler_json
15937   (vl_api_map_add_domain_reply_t * mp)
15938 {
15939   vat_main_t *vam = &vat_main;
15940   vat_json_node_t node;
15941
15942   vat_json_init_object (&node);
15943   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15944   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15945
15946   vat_json_print (vam->ofp, &node);
15947   vat_json_free (&node);
15948
15949   vam->retval = ntohl (mp->retval);
15950   vam->result_ready = 1;
15951 }
15952
15953 static int
15954 api_get_first_msg_id (vat_main_t * vam)
15955 {
15956   vl_api_get_first_msg_id_t *mp;
15957   unformat_input_t *i = vam->input;
15958   u8 *name;
15959   u8 name_set = 0;
15960   int ret;
15961
15962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15963     {
15964       if (unformat (i, "client %s", &name))
15965         name_set = 1;
15966       else
15967         break;
15968     }
15969
15970   if (name_set == 0)
15971     {
15972       errmsg ("missing client name");
15973       return -99;
15974     }
15975   vec_add1 (name, 0);
15976
15977   if (vec_len (name) > 63)
15978     {
15979       errmsg ("client name too long");
15980       return -99;
15981     }
15982
15983   M (GET_FIRST_MSG_ID, mp);
15984   clib_memcpy (mp->name, name, vec_len (name));
15985   S (mp);
15986   W (ret);
15987   return ret;
15988 }
15989
15990 static int
15991 api_cop_interface_enable_disable (vat_main_t * vam)
15992 {
15993   unformat_input_t *line_input = vam->input;
15994   vl_api_cop_interface_enable_disable_t *mp;
15995   u32 sw_if_index = ~0;
15996   u8 enable_disable = 1;
15997   int ret;
15998
15999   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16000     {
16001       if (unformat (line_input, "disable"))
16002         enable_disable = 0;
16003       if (unformat (line_input, "enable"))
16004         enable_disable = 1;
16005       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16006                          vam, &sw_if_index))
16007         ;
16008       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16009         ;
16010       else
16011         break;
16012     }
16013
16014   if (sw_if_index == ~0)
16015     {
16016       errmsg ("missing interface name or sw_if_index");
16017       return -99;
16018     }
16019
16020   /* Construct the API message */
16021   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16022   mp->sw_if_index = ntohl (sw_if_index);
16023   mp->enable_disable = enable_disable;
16024
16025   /* send it... */
16026   S (mp);
16027   /* Wait for the reply */
16028   W (ret);
16029   return ret;
16030 }
16031
16032 static int
16033 api_cop_whitelist_enable_disable (vat_main_t * vam)
16034 {
16035   unformat_input_t *line_input = vam->input;
16036   vl_api_cop_whitelist_enable_disable_t *mp;
16037   u32 sw_if_index = ~0;
16038   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16039   u32 fib_id = 0;
16040   int ret;
16041
16042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16043     {
16044       if (unformat (line_input, "ip4"))
16045         ip4 = 1;
16046       else if (unformat (line_input, "ip6"))
16047         ip6 = 1;
16048       else if (unformat (line_input, "default"))
16049         default_cop = 1;
16050       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16051                          vam, &sw_if_index))
16052         ;
16053       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16054         ;
16055       else if (unformat (line_input, "fib-id %d", &fib_id))
16056         ;
16057       else
16058         break;
16059     }
16060
16061   if (sw_if_index == ~0)
16062     {
16063       errmsg ("missing interface name or sw_if_index");
16064       return -99;
16065     }
16066
16067   /* Construct the API message */
16068   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16069   mp->sw_if_index = ntohl (sw_if_index);
16070   mp->fib_id = ntohl (fib_id);
16071   mp->ip4 = ip4;
16072   mp->ip6 = ip6;
16073   mp->default_cop = default_cop;
16074
16075   /* send it... */
16076   S (mp);
16077   /* Wait for the reply */
16078   W (ret);
16079   return ret;
16080 }
16081
16082 static int
16083 api_get_node_graph (vat_main_t * vam)
16084 {
16085   vl_api_get_node_graph_t *mp;
16086   int ret;
16087
16088   M (GET_NODE_GRAPH, mp);
16089
16090   /* send it... */
16091   S (mp);
16092   /* Wait for the reply */
16093   W (ret);
16094   return ret;
16095 }
16096
16097 /* *INDENT-OFF* */
16098 /** Used for parsing LISP eids */
16099 typedef CLIB_PACKED(struct{
16100   u8 addr[16];   /**< eid address */
16101   u32 len;       /**< prefix length if IP */
16102   u8 type;      /**< type of eid */
16103 }) lisp_eid_vat_t;
16104 /* *INDENT-ON* */
16105
16106 static uword
16107 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16108 {
16109   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16110
16111   memset (a, 0, sizeof (a[0]));
16112
16113   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16114     {
16115       a->type = 0;              /* ipv4 type */
16116     }
16117   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16118     {
16119       a->type = 1;              /* ipv6 type */
16120     }
16121   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16122     {
16123       a->type = 2;              /* mac type */
16124     }
16125   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16126     {
16127       a->type = 3;              /* NSH type */
16128       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16129       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16130     }
16131   else
16132     {
16133       return 0;
16134     }
16135
16136   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16137     {
16138       return 0;
16139     }
16140
16141   return 1;
16142 }
16143
16144 static int
16145 lisp_eid_size_vat (u8 type)
16146 {
16147   switch (type)
16148     {
16149     case 0:
16150       return 4;
16151     case 1:
16152       return 16;
16153     case 2:
16154       return 6;
16155     case 3:
16156       return 5;
16157     }
16158   return 0;
16159 }
16160
16161 static void
16162 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16163 {
16164   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16165 }
16166
16167 static int
16168 api_one_add_del_locator_set (vat_main_t * vam)
16169 {
16170   unformat_input_t *input = vam->input;
16171   vl_api_one_add_del_locator_set_t *mp;
16172   u8 is_add = 1;
16173   u8 *locator_set_name = NULL;
16174   u8 locator_set_name_set = 0;
16175   vl_api_local_locator_t locator, *locators = 0;
16176   u32 sw_if_index, priority, weight;
16177   u32 data_len = 0;
16178
16179   int ret;
16180   /* Parse args required to build the message */
16181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16182     {
16183       if (unformat (input, "del"))
16184         {
16185           is_add = 0;
16186         }
16187       else if (unformat (input, "locator-set %s", &locator_set_name))
16188         {
16189           locator_set_name_set = 1;
16190         }
16191       else if (unformat (input, "sw_if_index %u p %u w %u",
16192                          &sw_if_index, &priority, &weight))
16193         {
16194           locator.sw_if_index = htonl (sw_if_index);
16195           locator.priority = priority;
16196           locator.weight = weight;
16197           vec_add1 (locators, locator);
16198         }
16199       else
16200         if (unformat
16201             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16202              &sw_if_index, &priority, &weight))
16203         {
16204           locator.sw_if_index = htonl (sw_if_index);
16205           locator.priority = priority;
16206           locator.weight = weight;
16207           vec_add1 (locators, locator);
16208         }
16209       else
16210         break;
16211     }
16212
16213   if (locator_set_name_set == 0)
16214     {
16215       errmsg ("missing locator-set name");
16216       vec_free (locators);
16217       return -99;
16218     }
16219
16220   if (vec_len (locator_set_name) > 64)
16221     {
16222       errmsg ("locator-set name too long");
16223       vec_free (locator_set_name);
16224       vec_free (locators);
16225       return -99;
16226     }
16227   vec_add1 (locator_set_name, 0);
16228
16229   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16230
16231   /* Construct the API message */
16232   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16233
16234   mp->is_add = is_add;
16235   clib_memcpy (mp->locator_set_name, locator_set_name,
16236                vec_len (locator_set_name));
16237   vec_free (locator_set_name);
16238
16239   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16240   if (locators)
16241     clib_memcpy (mp->locators, locators, data_len);
16242   vec_free (locators);
16243
16244   /* send it... */
16245   S (mp);
16246
16247   /* Wait for a reply... */
16248   W (ret);
16249   return ret;
16250 }
16251
16252 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16253
16254 static int
16255 api_one_add_del_locator (vat_main_t * vam)
16256 {
16257   unformat_input_t *input = vam->input;
16258   vl_api_one_add_del_locator_t *mp;
16259   u32 tmp_if_index = ~0;
16260   u32 sw_if_index = ~0;
16261   u8 sw_if_index_set = 0;
16262   u8 sw_if_index_if_name_set = 0;
16263   u32 priority = ~0;
16264   u8 priority_set = 0;
16265   u32 weight = ~0;
16266   u8 weight_set = 0;
16267   u8 is_add = 1;
16268   u8 *locator_set_name = NULL;
16269   u8 locator_set_name_set = 0;
16270   int ret;
16271
16272   /* Parse args required to build the message */
16273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16274     {
16275       if (unformat (input, "del"))
16276         {
16277           is_add = 0;
16278         }
16279       else if (unformat (input, "locator-set %s", &locator_set_name))
16280         {
16281           locator_set_name_set = 1;
16282         }
16283       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16284                          &tmp_if_index))
16285         {
16286           sw_if_index_if_name_set = 1;
16287           sw_if_index = tmp_if_index;
16288         }
16289       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16290         {
16291           sw_if_index_set = 1;
16292           sw_if_index = tmp_if_index;
16293         }
16294       else if (unformat (input, "p %d", &priority))
16295         {
16296           priority_set = 1;
16297         }
16298       else if (unformat (input, "w %d", &weight))
16299         {
16300           weight_set = 1;
16301         }
16302       else
16303         break;
16304     }
16305
16306   if (locator_set_name_set == 0)
16307     {
16308       errmsg ("missing locator-set name");
16309       return -99;
16310     }
16311
16312   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16313     {
16314       errmsg ("missing sw_if_index");
16315       vec_free (locator_set_name);
16316       return -99;
16317     }
16318
16319   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16320     {
16321       errmsg ("cannot use both params interface name and sw_if_index");
16322       vec_free (locator_set_name);
16323       return -99;
16324     }
16325
16326   if (priority_set == 0)
16327     {
16328       errmsg ("missing locator-set priority");
16329       vec_free (locator_set_name);
16330       return -99;
16331     }
16332
16333   if (weight_set == 0)
16334     {
16335       errmsg ("missing locator-set weight");
16336       vec_free (locator_set_name);
16337       return -99;
16338     }
16339
16340   if (vec_len (locator_set_name) > 64)
16341     {
16342       errmsg ("locator-set name too long");
16343       vec_free (locator_set_name);
16344       return -99;
16345     }
16346   vec_add1 (locator_set_name, 0);
16347
16348   /* Construct the API message */
16349   M (ONE_ADD_DEL_LOCATOR, mp);
16350
16351   mp->is_add = is_add;
16352   mp->sw_if_index = ntohl (sw_if_index);
16353   mp->priority = priority;
16354   mp->weight = weight;
16355   clib_memcpy (mp->locator_set_name, locator_set_name,
16356                vec_len (locator_set_name));
16357   vec_free (locator_set_name);
16358
16359   /* send it... */
16360   S (mp);
16361
16362   /* Wait for a reply... */
16363   W (ret);
16364   return ret;
16365 }
16366
16367 #define api_lisp_add_del_locator api_one_add_del_locator
16368
16369 uword
16370 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16371 {
16372   u32 *key_id = va_arg (*args, u32 *);
16373   u8 *s = 0;
16374
16375   if (unformat (input, "%s", &s))
16376     {
16377       if (!strcmp ((char *) s, "sha1"))
16378         key_id[0] = HMAC_SHA_1_96;
16379       else if (!strcmp ((char *) s, "sha256"))
16380         key_id[0] = HMAC_SHA_256_128;
16381       else
16382         {
16383           clib_warning ("invalid key_id: '%s'", s);
16384           key_id[0] = HMAC_NO_KEY;
16385         }
16386     }
16387   else
16388     return 0;
16389
16390   vec_free (s);
16391   return 1;
16392 }
16393
16394 static int
16395 api_one_add_del_local_eid (vat_main_t * vam)
16396 {
16397   unformat_input_t *input = vam->input;
16398   vl_api_one_add_del_local_eid_t *mp;
16399   u8 is_add = 1;
16400   u8 eid_set = 0;
16401   lisp_eid_vat_t _eid, *eid = &_eid;
16402   u8 *locator_set_name = 0;
16403   u8 locator_set_name_set = 0;
16404   u32 vni = 0;
16405   u16 key_id = 0;
16406   u8 *key = 0;
16407   int ret;
16408
16409   /* Parse args required to build the message */
16410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16411     {
16412       if (unformat (input, "del"))
16413         {
16414           is_add = 0;
16415         }
16416       else if (unformat (input, "vni %d", &vni))
16417         {
16418           ;
16419         }
16420       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16421         {
16422           eid_set = 1;
16423         }
16424       else if (unformat (input, "locator-set %s", &locator_set_name))
16425         {
16426           locator_set_name_set = 1;
16427         }
16428       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16429         ;
16430       else if (unformat (input, "secret-key %_%v%_", &key))
16431         ;
16432       else
16433         break;
16434     }
16435
16436   if (locator_set_name_set == 0)
16437     {
16438       errmsg ("missing locator-set name");
16439       return -99;
16440     }
16441
16442   if (0 == eid_set)
16443     {
16444       errmsg ("EID address not set!");
16445       vec_free (locator_set_name);
16446       return -99;
16447     }
16448
16449   if (key && (0 == key_id))
16450     {
16451       errmsg ("invalid key_id!");
16452       return -99;
16453     }
16454
16455   if (vec_len (key) > 64)
16456     {
16457       errmsg ("key too long");
16458       vec_free (key);
16459       return -99;
16460     }
16461
16462   if (vec_len (locator_set_name) > 64)
16463     {
16464       errmsg ("locator-set name too long");
16465       vec_free (locator_set_name);
16466       return -99;
16467     }
16468   vec_add1 (locator_set_name, 0);
16469
16470   /* Construct the API message */
16471   M (ONE_ADD_DEL_LOCAL_EID, mp);
16472
16473   mp->is_add = is_add;
16474   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16475   mp->eid_type = eid->type;
16476   mp->prefix_len = eid->len;
16477   mp->vni = clib_host_to_net_u32 (vni);
16478   mp->key_id = clib_host_to_net_u16 (key_id);
16479   clib_memcpy (mp->locator_set_name, locator_set_name,
16480                vec_len (locator_set_name));
16481   clib_memcpy (mp->key, key, vec_len (key));
16482
16483   vec_free (locator_set_name);
16484   vec_free (key);
16485
16486   /* send it... */
16487   S (mp);
16488
16489   /* Wait for a reply... */
16490   W (ret);
16491   return ret;
16492 }
16493
16494 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16495
16496 static int
16497 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16498 {
16499   u32 dp_table = 0, vni = 0;;
16500   unformat_input_t *input = vam->input;
16501   vl_api_gpe_add_del_fwd_entry_t *mp;
16502   u8 is_add = 1;
16503   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16504   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16505   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16506   u32 action = ~0, w;
16507   ip4_address_t rmt_rloc4, lcl_rloc4;
16508   ip6_address_t rmt_rloc6, lcl_rloc6;
16509   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16510   int ret;
16511
16512   memset (&rloc, 0, sizeof (rloc));
16513
16514   /* Parse args required to build the message */
16515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (input, "del"))
16518         is_add = 0;
16519       else if (unformat (input, "add"))
16520         is_add = 1;
16521       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16522         {
16523           rmt_eid_set = 1;
16524         }
16525       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16526         {
16527           lcl_eid_set = 1;
16528         }
16529       else if (unformat (input, "vrf %d", &dp_table))
16530         ;
16531       else if (unformat (input, "bd %d", &dp_table))
16532         ;
16533       else if (unformat (input, "vni %d", &vni))
16534         ;
16535       else if (unformat (input, "w %d", &w))
16536         {
16537           if (!curr_rloc)
16538             {
16539               errmsg ("No RLOC configured for setting priority/weight!");
16540               return -99;
16541             }
16542           curr_rloc->weight = w;
16543         }
16544       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16545                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16546         {
16547           rloc.is_ip4 = 1;
16548
16549           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16550           rloc.weight = 0;
16551           vec_add1 (lcl_locs, rloc);
16552
16553           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16554           vec_add1 (rmt_locs, rloc);
16555           /* weight saved in rmt loc */
16556           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16557         }
16558       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16559                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16560         {
16561           rloc.is_ip4 = 0;
16562           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16563           rloc.weight = 0;
16564           vec_add1 (lcl_locs, rloc);
16565
16566           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16567           vec_add1 (rmt_locs, rloc);
16568           /* weight saved in rmt loc */
16569           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16570         }
16571       else if (unformat (input, "action %d", &action))
16572         {
16573           ;
16574         }
16575       else
16576         {
16577           clib_warning ("parse error '%U'", format_unformat_error, input);
16578           return -99;
16579         }
16580     }
16581
16582   if (!rmt_eid_set)
16583     {
16584       errmsg ("remote eid addresses not set");
16585       return -99;
16586     }
16587
16588   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16589     {
16590       errmsg ("eid types don't match");
16591       return -99;
16592     }
16593
16594   if (0 == rmt_locs && (u32) ~ 0 == action)
16595     {
16596       errmsg ("action not set for negative mapping");
16597       return -99;
16598     }
16599
16600   /* Construct the API message */
16601   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16602       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16603
16604   mp->is_add = is_add;
16605   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16606   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16607   mp->eid_type = rmt_eid->type;
16608   mp->dp_table = clib_host_to_net_u32 (dp_table);
16609   mp->vni = clib_host_to_net_u32 (vni);
16610   mp->rmt_len = rmt_eid->len;
16611   mp->lcl_len = lcl_eid->len;
16612   mp->action = action;
16613
16614   if (0 != rmt_locs && 0 != lcl_locs)
16615     {
16616       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16617       clib_memcpy (mp->locs, lcl_locs,
16618                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16619
16620       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16621       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16622                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16623     }
16624   vec_free (lcl_locs);
16625   vec_free (rmt_locs);
16626
16627   /* send it... */
16628   S (mp);
16629
16630   /* Wait for a reply... */
16631   W (ret);
16632   return ret;
16633 }
16634
16635 static int
16636 api_one_add_del_map_server (vat_main_t * vam)
16637 {
16638   unformat_input_t *input = vam->input;
16639   vl_api_one_add_del_map_server_t *mp;
16640   u8 is_add = 1;
16641   u8 ipv4_set = 0;
16642   u8 ipv6_set = 0;
16643   ip4_address_t ipv4;
16644   ip6_address_t ipv6;
16645   int ret;
16646
16647   /* Parse args required to build the message */
16648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16649     {
16650       if (unformat (input, "del"))
16651         {
16652           is_add = 0;
16653         }
16654       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16655         {
16656           ipv4_set = 1;
16657         }
16658       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16659         {
16660           ipv6_set = 1;
16661         }
16662       else
16663         break;
16664     }
16665
16666   if (ipv4_set && ipv6_set)
16667     {
16668       errmsg ("both eid v4 and v6 addresses set");
16669       return -99;
16670     }
16671
16672   if (!ipv4_set && !ipv6_set)
16673     {
16674       errmsg ("eid addresses not set");
16675       return -99;
16676     }
16677
16678   /* Construct the API message */
16679   M (ONE_ADD_DEL_MAP_SERVER, mp);
16680
16681   mp->is_add = is_add;
16682   if (ipv6_set)
16683     {
16684       mp->is_ipv6 = 1;
16685       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16686     }
16687   else
16688     {
16689       mp->is_ipv6 = 0;
16690       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16691     }
16692
16693   /* send it... */
16694   S (mp);
16695
16696   /* Wait for a reply... */
16697   W (ret);
16698   return ret;
16699 }
16700
16701 #define api_lisp_add_del_map_server api_one_add_del_map_server
16702
16703 static int
16704 api_one_add_del_map_resolver (vat_main_t * vam)
16705 {
16706   unformat_input_t *input = vam->input;
16707   vl_api_one_add_del_map_resolver_t *mp;
16708   u8 is_add = 1;
16709   u8 ipv4_set = 0;
16710   u8 ipv6_set = 0;
16711   ip4_address_t ipv4;
16712   ip6_address_t ipv6;
16713   int ret;
16714
16715   /* Parse args required to build the message */
16716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (input, "del"))
16719         {
16720           is_add = 0;
16721         }
16722       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16723         {
16724           ipv4_set = 1;
16725         }
16726       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16727         {
16728           ipv6_set = 1;
16729         }
16730       else
16731         break;
16732     }
16733
16734   if (ipv4_set && ipv6_set)
16735     {
16736       errmsg ("both eid v4 and v6 addresses set");
16737       return -99;
16738     }
16739
16740   if (!ipv4_set && !ipv6_set)
16741     {
16742       errmsg ("eid addresses not set");
16743       return -99;
16744     }
16745
16746   /* Construct the API message */
16747   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16748
16749   mp->is_add = is_add;
16750   if (ipv6_set)
16751     {
16752       mp->is_ipv6 = 1;
16753       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16754     }
16755   else
16756     {
16757       mp->is_ipv6 = 0;
16758       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16759     }
16760
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16770
16771 static int
16772 api_lisp_gpe_enable_disable (vat_main_t * vam)
16773 {
16774   unformat_input_t *input = vam->input;
16775   vl_api_gpe_enable_disable_t *mp;
16776   u8 is_set = 0;
16777   u8 is_en = 1;
16778   int ret;
16779
16780   /* Parse args required to build the message */
16781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16782     {
16783       if (unformat (input, "enable"))
16784         {
16785           is_set = 1;
16786           is_en = 1;
16787         }
16788       else if (unformat (input, "disable"))
16789         {
16790           is_set = 1;
16791           is_en = 0;
16792         }
16793       else
16794         break;
16795     }
16796
16797   if (is_set == 0)
16798     {
16799       errmsg ("Value not set");
16800       return -99;
16801     }
16802
16803   /* Construct the API message */
16804   M (GPE_ENABLE_DISABLE, mp);
16805
16806   mp->is_en = is_en;
16807
16808   /* send it... */
16809   S (mp);
16810
16811   /* Wait for a reply... */
16812   W (ret);
16813   return ret;
16814 }
16815
16816 static int
16817 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16818 {
16819   unformat_input_t *input = vam->input;
16820   vl_api_one_rloc_probe_enable_disable_t *mp;
16821   u8 is_set = 0;
16822   u8 is_en = 0;
16823   int ret;
16824
16825   /* Parse args required to build the message */
16826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16827     {
16828       if (unformat (input, "enable"))
16829         {
16830           is_set = 1;
16831           is_en = 1;
16832         }
16833       else if (unformat (input, "disable"))
16834         is_set = 1;
16835       else
16836         break;
16837     }
16838
16839   if (!is_set)
16840     {
16841       errmsg ("Value not set");
16842       return -99;
16843     }
16844
16845   /* Construct the API message */
16846   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16847
16848   mp->is_enabled = is_en;
16849
16850   /* send it... */
16851   S (mp);
16852
16853   /* Wait for a reply... */
16854   W (ret);
16855   return ret;
16856 }
16857
16858 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16859
16860 static int
16861 api_one_map_register_enable_disable (vat_main_t * vam)
16862 {
16863   unformat_input_t *input = vam->input;
16864   vl_api_one_map_register_enable_disable_t *mp;
16865   u8 is_set = 0;
16866   u8 is_en = 0;
16867   int ret;
16868
16869   /* Parse args required to build the message */
16870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16871     {
16872       if (unformat (input, "enable"))
16873         {
16874           is_set = 1;
16875           is_en = 1;
16876         }
16877       else if (unformat (input, "disable"))
16878         is_set = 1;
16879       else
16880         break;
16881     }
16882
16883   if (!is_set)
16884     {
16885       errmsg ("Value not set");
16886       return -99;
16887     }
16888
16889   /* Construct the API message */
16890   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16891
16892   mp->is_enabled = is_en;
16893
16894   /* send it... */
16895   S (mp);
16896
16897   /* Wait for a reply... */
16898   W (ret);
16899   return ret;
16900 }
16901
16902 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16903
16904 static int
16905 api_one_enable_disable (vat_main_t * vam)
16906 {
16907   unformat_input_t *input = vam->input;
16908   vl_api_one_enable_disable_t *mp;
16909   u8 is_set = 0;
16910   u8 is_en = 0;
16911   int ret;
16912
16913   /* Parse args required to build the message */
16914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16915     {
16916       if (unformat (input, "enable"))
16917         {
16918           is_set = 1;
16919           is_en = 1;
16920         }
16921       else if (unformat (input, "disable"))
16922         {
16923           is_set = 1;
16924         }
16925       else
16926         break;
16927     }
16928
16929   if (!is_set)
16930     {
16931       errmsg ("Value not set");
16932       return -99;
16933     }
16934
16935   /* Construct the API message */
16936   M (ONE_ENABLE_DISABLE, mp);
16937
16938   mp->is_en = is_en;
16939
16940   /* send it... */
16941   S (mp);
16942
16943   /* Wait for a reply... */
16944   W (ret);
16945   return ret;
16946 }
16947
16948 #define api_lisp_enable_disable api_one_enable_disable
16949
16950 static int
16951 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16952 {
16953   unformat_input_t *input = vam->input;
16954   vl_api_one_enable_disable_xtr_mode_t *mp;
16955   u8 is_set = 0;
16956   u8 is_en = 0;
16957   int ret;
16958
16959   /* Parse args required to build the message */
16960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (input, "enable"))
16963         {
16964           is_set = 1;
16965           is_en = 1;
16966         }
16967       else if (unformat (input, "disable"))
16968         {
16969           is_set = 1;
16970         }
16971       else
16972         break;
16973     }
16974
16975   if (!is_set)
16976     {
16977       errmsg ("Value not set");
16978       return -99;
16979     }
16980
16981   /* Construct the API message */
16982   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16983
16984   mp->is_en = is_en;
16985
16986   /* send it... */
16987   S (mp);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 static int
16995 api_one_show_xtr_mode (vat_main_t * vam)
16996 {
16997   vl_api_one_show_xtr_mode_t *mp;
16998   int ret;
16999
17000   /* Construct the API message */
17001   M (ONE_SHOW_XTR_MODE, mp);
17002
17003   /* send it... */
17004   S (mp);
17005
17006   /* Wait for a reply... */
17007   W (ret);
17008   return ret;
17009 }
17010
17011 static int
17012 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17013 {
17014   unformat_input_t *input = vam->input;
17015   vl_api_one_enable_disable_pitr_mode_t *mp;
17016   u8 is_set = 0;
17017   u8 is_en = 0;
17018   int ret;
17019
17020   /* Parse args required to build the message */
17021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17022     {
17023       if (unformat (input, "enable"))
17024         {
17025           is_set = 1;
17026           is_en = 1;
17027         }
17028       else if (unformat (input, "disable"))
17029         {
17030           is_set = 1;
17031         }
17032       else
17033         break;
17034     }
17035
17036   if (!is_set)
17037     {
17038       errmsg ("Value not set");
17039       return -99;
17040     }
17041
17042   /* Construct the API message */
17043   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17044
17045   mp->is_en = is_en;
17046
17047   /* send it... */
17048   S (mp);
17049
17050   /* Wait for a reply... */
17051   W (ret);
17052   return ret;
17053 }
17054
17055 static int
17056 api_one_show_pitr_mode (vat_main_t * vam)
17057 {
17058   vl_api_one_show_pitr_mode_t *mp;
17059   int ret;
17060
17061   /* Construct the API message */
17062   M (ONE_SHOW_PITR_MODE, mp);
17063
17064   /* send it... */
17065   S (mp);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 static int
17073 api_one_enable_disable_petr_mode (vat_main_t * vam)
17074 {
17075   unformat_input_t *input = vam->input;
17076   vl_api_one_enable_disable_petr_mode_t *mp;
17077   u8 is_set = 0;
17078   u8 is_en = 0;
17079   int ret;
17080
17081   /* Parse args required to build the message */
17082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17083     {
17084       if (unformat (input, "enable"))
17085         {
17086           is_set = 1;
17087           is_en = 1;
17088         }
17089       else if (unformat (input, "disable"))
17090         {
17091           is_set = 1;
17092         }
17093       else
17094         break;
17095     }
17096
17097   if (!is_set)
17098     {
17099       errmsg ("Value not set");
17100       return -99;
17101     }
17102
17103   /* Construct the API message */
17104   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17105
17106   mp->is_en = is_en;
17107
17108   /* send it... */
17109   S (mp);
17110
17111   /* Wait for a reply... */
17112   W (ret);
17113   return ret;
17114 }
17115
17116 static int
17117 api_one_show_petr_mode (vat_main_t * vam)
17118 {
17119   vl_api_one_show_petr_mode_t *mp;
17120   int ret;
17121
17122   /* Construct the API message */
17123   M (ONE_SHOW_PETR_MODE, mp);
17124
17125   /* send it... */
17126   S (mp);
17127
17128   /* Wait for a reply... */
17129   W (ret);
17130   return ret;
17131 }
17132
17133 static int
17134 api_show_one_map_register_state (vat_main_t * vam)
17135 {
17136   vl_api_show_one_map_register_state_t *mp;
17137   int ret;
17138
17139   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17140
17141   /* send */
17142   S (mp);
17143
17144   /* wait for reply */
17145   W (ret);
17146   return ret;
17147 }
17148
17149 #define api_show_lisp_map_register_state api_show_one_map_register_state
17150
17151 static int
17152 api_show_one_rloc_probe_state (vat_main_t * vam)
17153 {
17154   vl_api_show_one_rloc_probe_state_t *mp;
17155   int ret;
17156
17157   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17158
17159   /* send */
17160   S (mp);
17161
17162   /* wait for reply */
17163   W (ret);
17164   return ret;
17165 }
17166
17167 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17168
17169 static int
17170 api_one_add_del_ndp_entry (vat_main_t * vam)
17171 {
17172   vl_api_one_add_del_ndp_entry_t *mp;
17173   unformat_input_t *input = vam->input;
17174   u8 is_add = 1;
17175   u8 mac_set = 0;
17176   u8 bd_set = 0;
17177   u8 ip_set = 0;
17178   u8 mac[6] = { 0, };
17179   u8 ip6[16] = { 0, };
17180   u32 bd = ~0;
17181   int ret;
17182
17183   /* Parse args required to build the message */
17184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17185     {
17186       if (unformat (input, "del"))
17187         is_add = 0;
17188       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17189         mac_set = 1;
17190       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17191         ip_set = 1;
17192       else if (unformat (input, "bd %d", &bd))
17193         bd_set = 1;
17194       else
17195         {
17196           errmsg ("parse error '%U'", format_unformat_error, input);
17197           return -99;
17198         }
17199     }
17200
17201   if (!bd_set || !ip_set || (!mac_set && is_add))
17202     {
17203       errmsg ("Missing BD, IP or MAC!");
17204       return -99;
17205     }
17206
17207   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17208   mp->is_add = is_add;
17209   clib_memcpy (mp->mac, mac, 6);
17210   mp->bd = clib_host_to_net_u32 (bd);
17211   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17212
17213   /* send */
17214   S (mp);
17215
17216   /* wait for reply */
17217   W (ret);
17218   return ret;
17219 }
17220
17221 static int
17222 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17223 {
17224   vl_api_one_add_del_l2_arp_entry_t *mp;
17225   unformat_input_t *input = vam->input;
17226   u8 is_add = 1;
17227   u8 mac_set = 0;
17228   u8 bd_set = 0;
17229   u8 ip_set = 0;
17230   u8 mac[6] = { 0, };
17231   u32 ip4 = 0, bd = ~0;
17232   int ret;
17233
17234   /* Parse args required to build the message */
17235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17236     {
17237       if (unformat (input, "del"))
17238         is_add = 0;
17239       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17240         mac_set = 1;
17241       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17242         ip_set = 1;
17243       else if (unformat (input, "bd %d", &bd))
17244         bd_set = 1;
17245       else
17246         {
17247           errmsg ("parse error '%U'", format_unformat_error, input);
17248           return -99;
17249         }
17250     }
17251
17252   if (!bd_set || !ip_set || (!mac_set && is_add))
17253     {
17254       errmsg ("Missing BD, IP or MAC!");
17255       return -99;
17256     }
17257
17258   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17259   mp->is_add = is_add;
17260   clib_memcpy (mp->mac, mac, 6);
17261   mp->bd = clib_host_to_net_u32 (bd);
17262   mp->ip4 = ip4;
17263
17264   /* send */
17265   S (mp);
17266
17267   /* wait for reply */
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_one_ndp_bd_get (vat_main_t * vam)
17274 {
17275   vl_api_one_ndp_bd_get_t *mp;
17276   int ret;
17277
17278   M (ONE_NDP_BD_GET, mp);
17279
17280   /* send */
17281   S (mp);
17282
17283   /* wait for reply */
17284   W (ret);
17285   return ret;
17286 }
17287
17288 static int
17289 api_one_ndp_entries_get (vat_main_t * vam)
17290 {
17291   vl_api_one_ndp_entries_get_t *mp;
17292   unformat_input_t *input = vam->input;
17293   u8 bd_set = 0;
17294   u32 bd = ~0;
17295   int ret;
17296
17297   /* Parse args required to build the message */
17298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17299     {
17300       if (unformat (input, "bd %d", &bd))
17301         bd_set = 1;
17302       else
17303         {
17304           errmsg ("parse error '%U'", format_unformat_error, input);
17305           return -99;
17306         }
17307     }
17308
17309   if (!bd_set)
17310     {
17311       errmsg ("Expected bridge domain!");
17312       return -99;
17313     }
17314
17315   M (ONE_NDP_ENTRIES_GET, mp);
17316   mp->bd = clib_host_to_net_u32 (bd);
17317
17318   /* send */
17319   S (mp);
17320
17321   /* wait for reply */
17322   W (ret);
17323   return ret;
17324 }
17325
17326 static int
17327 api_one_l2_arp_bd_get (vat_main_t * vam)
17328 {
17329   vl_api_one_l2_arp_bd_get_t *mp;
17330   int ret;
17331
17332   M (ONE_L2_ARP_BD_GET, mp);
17333
17334   /* send */
17335   S (mp);
17336
17337   /* wait for reply */
17338   W (ret);
17339   return ret;
17340 }
17341
17342 static int
17343 api_one_l2_arp_entries_get (vat_main_t * vam)
17344 {
17345   vl_api_one_l2_arp_entries_get_t *mp;
17346   unformat_input_t *input = vam->input;
17347   u8 bd_set = 0;
17348   u32 bd = ~0;
17349   int ret;
17350
17351   /* Parse args required to build the message */
17352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17353     {
17354       if (unformat (input, "bd %d", &bd))
17355         bd_set = 1;
17356       else
17357         {
17358           errmsg ("parse error '%U'", format_unformat_error, input);
17359           return -99;
17360         }
17361     }
17362
17363   if (!bd_set)
17364     {
17365       errmsg ("Expected bridge domain!");
17366       return -99;
17367     }
17368
17369   M (ONE_L2_ARP_ENTRIES_GET, mp);
17370   mp->bd = clib_host_to_net_u32 (bd);
17371
17372   /* send */
17373   S (mp);
17374
17375   /* wait for reply */
17376   W (ret);
17377   return ret;
17378 }
17379
17380 static int
17381 api_one_stats_enable_disable (vat_main_t * vam)
17382 {
17383   vl_api_one_stats_enable_disable_t *mp;
17384   unformat_input_t *input = vam->input;
17385   u8 is_set = 0;
17386   u8 is_en = 0;
17387   int ret;
17388
17389   /* Parse args required to build the message */
17390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17391     {
17392       if (unformat (input, "enable"))
17393         {
17394           is_set = 1;
17395           is_en = 1;
17396         }
17397       else if (unformat (input, "disable"))
17398         {
17399           is_set = 1;
17400         }
17401       else
17402         break;
17403     }
17404
17405   if (!is_set)
17406     {
17407       errmsg ("Value not set");
17408       return -99;
17409     }
17410
17411   M (ONE_STATS_ENABLE_DISABLE, mp);
17412   mp->is_en = is_en;
17413
17414   /* send */
17415   S (mp);
17416
17417   /* wait for reply */
17418   W (ret);
17419   return ret;
17420 }
17421
17422 static int
17423 api_show_one_stats_enable_disable (vat_main_t * vam)
17424 {
17425   vl_api_show_one_stats_enable_disable_t *mp;
17426   int ret;
17427
17428   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17429
17430   /* send */
17431   S (mp);
17432
17433   /* wait for reply */
17434   W (ret);
17435   return ret;
17436 }
17437
17438 static int
17439 api_show_one_map_request_mode (vat_main_t * vam)
17440 {
17441   vl_api_show_one_map_request_mode_t *mp;
17442   int ret;
17443
17444   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17445
17446   /* send */
17447   S (mp);
17448
17449   /* wait for reply */
17450   W (ret);
17451   return ret;
17452 }
17453
17454 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17455
17456 static int
17457 api_one_map_request_mode (vat_main_t * vam)
17458 {
17459   unformat_input_t *input = vam->input;
17460   vl_api_one_map_request_mode_t *mp;
17461   u8 mode = 0;
17462   int ret;
17463
17464   /* Parse args required to build the message */
17465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17466     {
17467       if (unformat (input, "dst-only"))
17468         mode = 0;
17469       else if (unformat (input, "src-dst"))
17470         mode = 1;
17471       else
17472         {
17473           errmsg ("parse error '%U'", format_unformat_error, input);
17474           return -99;
17475         }
17476     }
17477
17478   M (ONE_MAP_REQUEST_MODE, mp);
17479
17480   mp->mode = mode;
17481
17482   /* send */
17483   S (mp);
17484
17485   /* wait for reply */
17486   W (ret);
17487   return ret;
17488 }
17489
17490 #define api_lisp_map_request_mode api_one_map_request_mode
17491
17492 /**
17493  * Enable/disable ONE proxy ITR.
17494  *
17495  * @param vam vpp API test context
17496  * @return return code
17497  */
17498 static int
17499 api_one_pitr_set_locator_set (vat_main_t * vam)
17500 {
17501   u8 ls_name_set = 0;
17502   unformat_input_t *input = vam->input;
17503   vl_api_one_pitr_set_locator_set_t *mp;
17504   u8 is_add = 1;
17505   u8 *ls_name = 0;
17506   int ret;
17507
17508   /* Parse args required to build the message */
17509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17510     {
17511       if (unformat (input, "del"))
17512         is_add = 0;
17513       else if (unformat (input, "locator-set %s", &ls_name))
17514         ls_name_set = 1;
17515       else
17516         {
17517           errmsg ("parse error '%U'", format_unformat_error, input);
17518           return -99;
17519         }
17520     }
17521
17522   if (!ls_name_set)
17523     {
17524       errmsg ("locator-set name not set!");
17525       return -99;
17526     }
17527
17528   M (ONE_PITR_SET_LOCATOR_SET, mp);
17529
17530   mp->is_add = is_add;
17531   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17532   vec_free (ls_name);
17533
17534   /* send */
17535   S (mp);
17536
17537   /* wait for reply */
17538   W (ret);
17539   return ret;
17540 }
17541
17542 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17543
17544 static int
17545 api_one_nsh_set_locator_set (vat_main_t * vam)
17546 {
17547   u8 ls_name_set = 0;
17548   unformat_input_t *input = vam->input;
17549   vl_api_one_nsh_set_locator_set_t *mp;
17550   u8 is_add = 1;
17551   u8 *ls_name = 0;
17552   int ret;
17553
17554   /* Parse args required to build the message */
17555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17556     {
17557       if (unformat (input, "del"))
17558         is_add = 0;
17559       else if (unformat (input, "ls %s", &ls_name))
17560         ls_name_set = 1;
17561       else
17562         {
17563           errmsg ("parse error '%U'", format_unformat_error, input);
17564           return -99;
17565         }
17566     }
17567
17568   if (!ls_name_set && is_add)
17569     {
17570       errmsg ("locator-set name not set!");
17571       return -99;
17572     }
17573
17574   M (ONE_NSH_SET_LOCATOR_SET, mp);
17575
17576   mp->is_add = is_add;
17577   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17578   vec_free (ls_name);
17579
17580   /* send */
17581   S (mp);
17582
17583   /* wait for reply */
17584   W (ret);
17585   return ret;
17586 }
17587
17588 static int
17589 api_show_one_pitr (vat_main_t * vam)
17590 {
17591   vl_api_show_one_pitr_t *mp;
17592   int ret;
17593
17594   if (!vam->json_output)
17595     {
17596       print (vam->ofp, "%=20s", "lisp status:");
17597     }
17598
17599   M (SHOW_ONE_PITR, mp);
17600   /* send it... */
17601   S (mp);
17602
17603   /* Wait for a reply... */
17604   W (ret);
17605   return ret;
17606 }
17607
17608 #define api_show_lisp_pitr api_show_one_pitr
17609
17610 static int
17611 api_one_use_petr (vat_main_t * vam)
17612 {
17613   unformat_input_t *input = vam->input;
17614   vl_api_one_use_petr_t *mp;
17615   u8 is_add = 0;
17616   ip_address_t ip;
17617   int ret;
17618
17619   memset (&ip, 0, sizeof (ip));
17620
17621   /* Parse args required to build the message */
17622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17623     {
17624       if (unformat (input, "disable"))
17625         is_add = 0;
17626       else
17627         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17628         {
17629           is_add = 1;
17630           ip_addr_version (&ip) = IP4;
17631         }
17632       else
17633         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17634         {
17635           is_add = 1;
17636           ip_addr_version (&ip) = IP6;
17637         }
17638       else
17639         {
17640           errmsg ("parse error '%U'", format_unformat_error, input);
17641           return -99;
17642         }
17643     }
17644
17645   M (ONE_USE_PETR, mp);
17646
17647   mp->is_add = is_add;
17648   if (is_add)
17649     {
17650       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17651       if (mp->is_ip4)
17652         clib_memcpy (mp->address, &ip, 4);
17653       else
17654         clib_memcpy (mp->address, &ip, 16);
17655     }
17656
17657   /* send */
17658   S (mp);
17659
17660   /* wait for reply */
17661   W (ret);
17662   return ret;
17663 }
17664
17665 #define api_lisp_use_petr api_one_use_petr
17666
17667 static int
17668 api_show_one_nsh_mapping (vat_main_t * vam)
17669 {
17670   vl_api_show_one_use_petr_t *mp;
17671   int ret;
17672
17673   if (!vam->json_output)
17674     {
17675       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17676     }
17677
17678   M (SHOW_ONE_NSH_MAPPING, mp);
17679   /* send it... */
17680   S (mp);
17681
17682   /* Wait for a reply... */
17683   W (ret);
17684   return ret;
17685 }
17686
17687 static int
17688 api_show_one_use_petr (vat_main_t * vam)
17689 {
17690   vl_api_show_one_use_petr_t *mp;
17691   int ret;
17692
17693   if (!vam->json_output)
17694     {
17695       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17696     }
17697
17698   M (SHOW_ONE_USE_PETR, mp);
17699   /* send it... */
17700   S (mp);
17701
17702   /* Wait for a reply... */
17703   W (ret);
17704   return ret;
17705 }
17706
17707 #define api_show_lisp_use_petr api_show_one_use_petr
17708
17709 /**
17710  * Add/delete mapping between vni and vrf
17711  */
17712 static int
17713 api_one_eid_table_add_del_map (vat_main_t * vam)
17714 {
17715   unformat_input_t *input = vam->input;
17716   vl_api_one_eid_table_add_del_map_t *mp;
17717   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17718   u32 vni, vrf, bd_index;
17719   int ret;
17720
17721   /* Parse args required to build the message */
17722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17723     {
17724       if (unformat (input, "del"))
17725         is_add = 0;
17726       else if (unformat (input, "vrf %d", &vrf))
17727         vrf_set = 1;
17728       else if (unformat (input, "bd_index %d", &bd_index))
17729         bd_index_set = 1;
17730       else if (unformat (input, "vni %d", &vni))
17731         vni_set = 1;
17732       else
17733         break;
17734     }
17735
17736   if (!vni_set || (!vrf_set && !bd_index_set))
17737     {
17738       errmsg ("missing arguments!");
17739       return -99;
17740     }
17741
17742   if (vrf_set && bd_index_set)
17743     {
17744       errmsg ("error: both vrf and bd entered!");
17745       return -99;
17746     }
17747
17748   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17749
17750   mp->is_add = is_add;
17751   mp->vni = htonl (vni);
17752   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17753   mp->is_l2 = bd_index_set;
17754
17755   /* send */
17756   S (mp);
17757
17758   /* wait for reply */
17759   W (ret);
17760   return ret;
17761 }
17762
17763 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17764
17765 uword
17766 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17767 {
17768   u32 *action = va_arg (*args, u32 *);
17769   u8 *s = 0;
17770
17771   if (unformat (input, "%s", &s))
17772     {
17773       if (!strcmp ((char *) s, "no-action"))
17774         action[0] = 0;
17775       else if (!strcmp ((char *) s, "natively-forward"))
17776         action[0] = 1;
17777       else if (!strcmp ((char *) s, "send-map-request"))
17778         action[0] = 2;
17779       else if (!strcmp ((char *) s, "drop"))
17780         action[0] = 3;
17781       else
17782         {
17783           clib_warning ("invalid action: '%s'", s);
17784           action[0] = 3;
17785         }
17786     }
17787   else
17788     return 0;
17789
17790   vec_free (s);
17791   return 1;
17792 }
17793
17794 /**
17795  * Add/del remote mapping to/from ONE control plane
17796  *
17797  * @param vam vpp API test context
17798  * @return return code
17799  */
17800 static int
17801 api_one_add_del_remote_mapping (vat_main_t * vam)
17802 {
17803   unformat_input_t *input = vam->input;
17804   vl_api_one_add_del_remote_mapping_t *mp;
17805   u32 vni = 0;
17806   lisp_eid_vat_t _eid, *eid = &_eid;
17807   lisp_eid_vat_t _seid, *seid = &_seid;
17808   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17809   u32 action = ~0, p, w, data_len;
17810   ip4_address_t rloc4;
17811   ip6_address_t rloc6;
17812   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17813   int ret;
17814
17815   memset (&rloc, 0, sizeof (rloc));
17816
17817   /* Parse args required to build the message */
17818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17819     {
17820       if (unformat (input, "del-all"))
17821         {
17822           del_all = 1;
17823         }
17824       else if (unformat (input, "del"))
17825         {
17826           is_add = 0;
17827         }
17828       else if (unformat (input, "add"))
17829         {
17830           is_add = 1;
17831         }
17832       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17833         {
17834           eid_set = 1;
17835         }
17836       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17837         {
17838           seid_set = 1;
17839         }
17840       else if (unformat (input, "vni %d", &vni))
17841         {
17842           ;
17843         }
17844       else if (unformat (input, "p %d w %d", &p, &w))
17845         {
17846           if (!curr_rloc)
17847             {
17848               errmsg ("No RLOC configured for setting priority/weight!");
17849               return -99;
17850             }
17851           curr_rloc->priority = p;
17852           curr_rloc->weight = w;
17853         }
17854       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17855         {
17856           rloc.is_ip4 = 1;
17857           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17858           vec_add1 (rlocs, rloc);
17859           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17860         }
17861       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17862         {
17863           rloc.is_ip4 = 0;
17864           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17865           vec_add1 (rlocs, rloc);
17866           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17867         }
17868       else if (unformat (input, "action %U",
17869                          unformat_negative_mapping_action, &action))
17870         {
17871           ;
17872         }
17873       else
17874         {
17875           clib_warning ("parse error '%U'", format_unformat_error, input);
17876           return -99;
17877         }
17878     }
17879
17880   if (0 == eid_set)
17881     {
17882       errmsg ("missing params!");
17883       return -99;
17884     }
17885
17886   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17887     {
17888       errmsg ("no action set for negative map-reply!");
17889       return -99;
17890     }
17891
17892   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17893
17894   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17895   mp->is_add = is_add;
17896   mp->vni = htonl (vni);
17897   mp->action = (u8) action;
17898   mp->is_src_dst = seid_set;
17899   mp->eid_len = eid->len;
17900   mp->seid_len = seid->len;
17901   mp->del_all = del_all;
17902   mp->eid_type = eid->type;
17903   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17904   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17905
17906   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17907   clib_memcpy (mp->rlocs, rlocs, data_len);
17908   vec_free (rlocs);
17909
17910   /* send it... */
17911   S (mp);
17912
17913   /* Wait for a reply... */
17914   W (ret);
17915   return ret;
17916 }
17917
17918 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17919
17920 /**
17921  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17922  * forwarding entries in data-plane accordingly.
17923  *
17924  * @param vam vpp API test context
17925  * @return return code
17926  */
17927 static int
17928 api_one_add_del_adjacency (vat_main_t * vam)
17929 {
17930   unformat_input_t *input = vam->input;
17931   vl_api_one_add_del_adjacency_t *mp;
17932   u32 vni = 0;
17933   ip4_address_t leid4, reid4;
17934   ip6_address_t leid6, reid6;
17935   u8 reid_mac[6] = { 0 };
17936   u8 leid_mac[6] = { 0 };
17937   u8 reid_type, leid_type;
17938   u32 leid_len = 0, reid_len = 0, len;
17939   u8 is_add = 1;
17940   int ret;
17941
17942   leid_type = reid_type = (u8) ~ 0;
17943
17944   /* Parse args required to build the message */
17945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17946     {
17947       if (unformat (input, "del"))
17948         {
17949           is_add = 0;
17950         }
17951       else if (unformat (input, "add"))
17952         {
17953           is_add = 1;
17954         }
17955       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17956                          &reid4, &len))
17957         {
17958           reid_type = 0;        /* ipv4 */
17959           reid_len = len;
17960         }
17961       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17962                          &reid6, &len))
17963         {
17964           reid_type = 1;        /* ipv6 */
17965           reid_len = len;
17966         }
17967       else if (unformat (input, "reid %U", unformat_ethernet_address,
17968                          reid_mac))
17969         {
17970           reid_type = 2;        /* mac */
17971         }
17972       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17973                          &leid4, &len))
17974         {
17975           leid_type = 0;        /* ipv4 */
17976           leid_len = len;
17977         }
17978       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17979                          &leid6, &len))
17980         {
17981           leid_type = 1;        /* ipv6 */
17982           leid_len = len;
17983         }
17984       else if (unformat (input, "leid %U", unformat_ethernet_address,
17985                          leid_mac))
17986         {
17987           leid_type = 2;        /* mac */
17988         }
17989       else if (unformat (input, "vni %d", &vni))
17990         {
17991           ;
17992         }
17993       else
17994         {
17995           errmsg ("parse error '%U'", format_unformat_error, input);
17996           return -99;
17997         }
17998     }
17999
18000   if ((u8) ~ 0 == reid_type)
18001     {
18002       errmsg ("missing params!");
18003       return -99;
18004     }
18005
18006   if (leid_type != reid_type)
18007     {
18008       errmsg ("remote and local EIDs are of different types!");
18009       return -99;
18010     }
18011
18012   M (ONE_ADD_DEL_ADJACENCY, mp);
18013   mp->is_add = is_add;
18014   mp->vni = htonl (vni);
18015   mp->leid_len = leid_len;
18016   mp->reid_len = reid_len;
18017   mp->eid_type = reid_type;
18018
18019   switch (mp->eid_type)
18020     {
18021     case 0:
18022       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18023       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18024       break;
18025     case 1:
18026       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18027       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18028       break;
18029     case 2:
18030       clib_memcpy (mp->leid, leid_mac, 6);
18031       clib_memcpy (mp->reid, reid_mac, 6);
18032       break;
18033     default:
18034       errmsg ("unknown EID type %d!", mp->eid_type);
18035       return 0;
18036     }
18037
18038   /* send it... */
18039   S (mp);
18040
18041   /* Wait for a reply... */
18042   W (ret);
18043   return ret;
18044 }
18045
18046 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18047
18048 uword
18049 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18050 {
18051   u32 *mode = va_arg (*args, u32 *);
18052
18053   if (unformat (input, "lisp"))
18054     *mode = 0;
18055   else if (unformat (input, "vxlan"))
18056     *mode = 1;
18057   else
18058     return 0;
18059
18060   return 1;
18061 }
18062
18063 static int
18064 api_gpe_get_encap_mode (vat_main_t * vam)
18065 {
18066   vl_api_gpe_get_encap_mode_t *mp;
18067   int ret;
18068
18069   /* Construct the API message */
18070   M (GPE_GET_ENCAP_MODE, mp);
18071
18072   /* send it... */
18073   S (mp);
18074
18075   /* Wait for a reply... */
18076   W (ret);
18077   return ret;
18078 }
18079
18080 static int
18081 api_gpe_set_encap_mode (vat_main_t * vam)
18082 {
18083   unformat_input_t *input = vam->input;
18084   vl_api_gpe_set_encap_mode_t *mp;
18085   int ret;
18086   u32 mode = 0;
18087
18088   /* Parse args required to build the message */
18089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18090     {
18091       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18092         ;
18093       else
18094         break;
18095     }
18096
18097   /* Construct the API message */
18098   M (GPE_SET_ENCAP_MODE, mp);
18099
18100   mp->mode = mode;
18101
18102   /* send it... */
18103   S (mp);
18104
18105   /* Wait for a reply... */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 static int
18111 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18112 {
18113   unformat_input_t *input = vam->input;
18114   vl_api_gpe_add_del_iface_t *mp;
18115   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18116   u32 dp_table = 0, vni = 0;
18117   int ret;
18118
18119   /* Parse args required to build the message */
18120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18121     {
18122       if (unformat (input, "up"))
18123         {
18124           action_set = 1;
18125           is_add = 1;
18126         }
18127       else if (unformat (input, "down"))
18128         {
18129           action_set = 1;
18130           is_add = 0;
18131         }
18132       else if (unformat (input, "table_id %d", &dp_table))
18133         {
18134           dp_table_set = 1;
18135         }
18136       else if (unformat (input, "bd_id %d", &dp_table))
18137         {
18138           dp_table_set = 1;
18139           is_l2 = 1;
18140         }
18141       else if (unformat (input, "vni %d", &vni))
18142         {
18143           vni_set = 1;
18144         }
18145       else
18146         break;
18147     }
18148
18149   if (action_set == 0)
18150     {
18151       errmsg ("Action not set");
18152       return -99;
18153     }
18154   if (dp_table_set == 0 || vni_set == 0)
18155     {
18156       errmsg ("vni and dp_table must be set");
18157       return -99;
18158     }
18159
18160   /* Construct the API message */
18161   M (GPE_ADD_DEL_IFACE, mp);
18162
18163   mp->is_add = is_add;
18164   mp->dp_table = clib_host_to_net_u32 (dp_table);
18165   mp->is_l2 = is_l2;
18166   mp->vni = clib_host_to_net_u32 (vni);
18167
18168   /* send it... */
18169   S (mp);
18170
18171   /* Wait for a reply... */
18172   W (ret);
18173   return ret;
18174 }
18175
18176 static int
18177 api_one_map_register_fallback_threshold (vat_main_t * vam)
18178 {
18179   unformat_input_t *input = vam->input;
18180   vl_api_one_map_register_fallback_threshold_t *mp;
18181   u32 value = 0;
18182   u8 is_set = 0;
18183   int ret;
18184
18185   /* Parse args required to build the message */
18186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18187     {
18188       if (unformat (input, "%u", &value))
18189         is_set = 1;
18190       else
18191         {
18192           clib_warning ("parse error '%U'", format_unformat_error, input);
18193           return -99;
18194         }
18195     }
18196
18197   if (!is_set)
18198     {
18199       errmsg ("fallback threshold value is missing!");
18200       return -99;
18201     }
18202
18203   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18204   mp->value = clib_host_to_net_u32 (value);
18205
18206   /* send it... */
18207   S (mp);
18208
18209   /* Wait for a reply... */
18210   W (ret);
18211   return ret;
18212 }
18213
18214 static int
18215 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18216 {
18217   vl_api_show_one_map_register_fallback_threshold_t *mp;
18218   int ret;
18219
18220   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18221
18222   /* send it... */
18223   S (mp);
18224
18225   /* Wait for a reply... */
18226   W (ret);
18227   return ret;
18228 }
18229
18230 uword
18231 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18232 {
18233   u32 *proto = va_arg (*args, u32 *);
18234
18235   if (unformat (input, "udp"))
18236     *proto = 1;
18237   else if (unformat (input, "api"))
18238     *proto = 2;
18239   else
18240     return 0;
18241
18242   return 1;
18243 }
18244
18245 static int
18246 api_one_set_transport_protocol (vat_main_t * vam)
18247 {
18248   unformat_input_t *input = vam->input;
18249   vl_api_one_set_transport_protocol_t *mp;
18250   u8 is_set = 0;
18251   u32 protocol = 0;
18252   int ret;
18253
18254   /* Parse args required to build the message */
18255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18256     {
18257       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18258         is_set = 1;
18259       else
18260         {
18261           clib_warning ("parse error '%U'", format_unformat_error, input);
18262           return -99;
18263         }
18264     }
18265
18266   if (!is_set)
18267     {
18268       errmsg ("Transport protocol missing!");
18269       return -99;
18270     }
18271
18272   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18273   mp->protocol = (u8) protocol;
18274
18275   /* send it... */
18276   S (mp);
18277
18278   /* Wait for a reply... */
18279   W (ret);
18280   return ret;
18281 }
18282
18283 static int
18284 api_one_get_transport_protocol (vat_main_t * vam)
18285 {
18286   vl_api_one_get_transport_protocol_t *mp;
18287   int ret;
18288
18289   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18290
18291   /* send it... */
18292   S (mp);
18293
18294   /* Wait for a reply... */
18295   W (ret);
18296   return ret;
18297 }
18298
18299 static int
18300 api_one_map_register_set_ttl (vat_main_t * vam)
18301 {
18302   unformat_input_t *input = vam->input;
18303   vl_api_one_map_register_set_ttl_t *mp;
18304   u32 ttl = 0;
18305   u8 is_set = 0;
18306   int ret;
18307
18308   /* Parse args required to build the message */
18309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18310     {
18311       if (unformat (input, "%u", &ttl))
18312         is_set = 1;
18313       else
18314         {
18315           clib_warning ("parse error '%U'", format_unformat_error, input);
18316           return -99;
18317         }
18318     }
18319
18320   if (!is_set)
18321     {
18322       errmsg ("TTL value missing!");
18323       return -99;
18324     }
18325
18326   M (ONE_MAP_REGISTER_SET_TTL, mp);
18327   mp->ttl = clib_host_to_net_u32 (ttl);
18328
18329   /* send it... */
18330   S (mp);
18331
18332   /* Wait for a reply... */
18333   W (ret);
18334   return ret;
18335 }
18336
18337 static int
18338 api_show_one_map_register_ttl (vat_main_t * vam)
18339 {
18340   vl_api_show_one_map_register_ttl_t *mp;
18341   int ret;
18342
18343   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18344
18345   /* send it... */
18346   S (mp);
18347
18348   /* Wait for a reply... */
18349   W (ret);
18350   return ret;
18351 }
18352
18353 /**
18354  * Add/del map request itr rlocs from ONE control plane and updates
18355  *
18356  * @param vam vpp API test context
18357  * @return return code
18358  */
18359 static int
18360 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18361 {
18362   unformat_input_t *input = vam->input;
18363   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18364   u8 *locator_set_name = 0;
18365   u8 locator_set_name_set = 0;
18366   u8 is_add = 1;
18367   int ret;
18368
18369   /* Parse args required to build the message */
18370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18371     {
18372       if (unformat (input, "del"))
18373         {
18374           is_add = 0;
18375         }
18376       else if (unformat (input, "%_%v%_", &locator_set_name))
18377         {
18378           locator_set_name_set = 1;
18379         }
18380       else
18381         {
18382           clib_warning ("parse error '%U'", format_unformat_error, input);
18383           return -99;
18384         }
18385     }
18386
18387   if (is_add && !locator_set_name_set)
18388     {
18389       errmsg ("itr-rloc is not set!");
18390       return -99;
18391     }
18392
18393   if (is_add && vec_len (locator_set_name) > 64)
18394     {
18395       errmsg ("itr-rloc locator-set name too long");
18396       vec_free (locator_set_name);
18397       return -99;
18398     }
18399
18400   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18401   mp->is_add = is_add;
18402   if (is_add)
18403     {
18404       clib_memcpy (mp->locator_set_name, locator_set_name,
18405                    vec_len (locator_set_name));
18406     }
18407   else
18408     {
18409       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18410     }
18411   vec_free (locator_set_name);
18412
18413   /* send it... */
18414   S (mp);
18415
18416   /* Wait for a reply... */
18417   W (ret);
18418   return ret;
18419 }
18420
18421 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18422
18423 static int
18424 api_one_locator_dump (vat_main_t * vam)
18425 {
18426   unformat_input_t *input = vam->input;
18427   vl_api_one_locator_dump_t *mp;
18428   vl_api_control_ping_t *mp_ping;
18429   u8 is_index_set = 0, is_name_set = 0;
18430   u8 *ls_name = 0;
18431   u32 ls_index = ~0;
18432   int ret;
18433
18434   /* Parse args required to build the message */
18435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18436     {
18437       if (unformat (input, "ls_name %_%v%_", &ls_name))
18438         {
18439           is_name_set = 1;
18440         }
18441       else if (unformat (input, "ls_index %d", &ls_index))
18442         {
18443           is_index_set = 1;
18444         }
18445       else
18446         {
18447           errmsg ("parse error '%U'", format_unformat_error, input);
18448           return -99;
18449         }
18450     }
18451
18452   if (!is_index_set && !is_name_set)
18453     {
18454       errmsg ("error: expected one of index or name!");
18455       return -99;
18456     }
18457
18458   if (is_index_set && is_name_set)
18459     {
18460       errmsg ("error: only one param expected!");
18461       return -99;
18462     }
18463
18464   if (vec_len (ls_name) > 62)
18465     {
18466       errmsg ("error: locator set name too long!");
18467       return -99;
18468     }
18469
18470   if (!vam->json_output)
18471     {
18472       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18473     }
18474
18475   M (ONE_LOCATOR_DUMP, mp);
18476   mp->is_index_set = is_index_set;
18477
18478   if (is_index_set)
18479     mp->ls_index = clib_host_to_net_u32 (ls_index);
18480   else
18481     {
18482       vec_add1 (ls_name, 0);
18483       strncpy ((char *) mp->ls_name, (char *) ls_name,
18484                sizeof (mp->ls_name) - 1);
18485     }
18486
18487   /* send it... */
18488   S (mp);
18489
18490   /* Use a control ping for synchronization */
18491   MPING (CONTROL_PING, mp_ping);
18492   S (mp_ping);
18493
18494   /* Wait for a reply... */
18495   W (ret);
18496   return ret;
18497 }
18498
18499 #define api_lisp_locator_dump api_one_locator_dump
18500
18501 static int
18502 api_one_locator_set_dump (vat_main_t * vam)
18503 {
18504   vl_api_one_locator_set_dump_t *mp;
18505   vl_api_control_ping_t *mp_ping;
18506   unformat_input_t *input = vam->input;
18507   u8 filter = 0;
18508   int ret;
18509
18510   /* Parse args required to build the message */
18511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18512     {
18513       if (unformat (input, "local"))
18514         {
18515           filter = 1;
18516         }
18517       else if (unformat (input, "remote"))
18518         {
18519           filter = 2;
18520         }
18521       else
18522         {
18523           errmsg ("parse error '%U'", format_unformat_error, input);
18524           return -99;
18525         }
18526     }
18527
18528   if (!vam->json_output)
18529     {
18530       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18531     }
18532
18533   M (ONE_LOCATOR_SET_DUMP, mp);
18534
18535   mp->filter = filter;
18536
18537   /* send it... */
18538   S (mp);
18539
18540   /* Use a control ping for synchronization */
18541   MPING (CONTROL_PING, mp_ping);
18542   S (mp_ping);
18543
18544   /* Wait for a reply... */
18545   W (ret);
18546   return ret;
18547 }
18548
18549 #define api_lisp_locator_set_dump api_one_locator_set_dump
18550
18551 static int
18552 api_one_eid_table_map_dump (vat_main_t * vam)
18553 {
18554   u8 is_l2 = 0;
18555   u8 mode_set = 0;
18556   unformat_input_t *input = vam->input;
18557   vl_api_one_eid_table_map_dump_t *mp;
18558   vl_api_control_ping_t *mp_ping;
18559   int ret;
18560
18561   /* Parse args required to build the message */
18562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18563     {
18564       if (unformat (input, "l2"))
18565         {
18566           is_l2 = 1;
18567           mode_set = 1;
18568         }
18569       else if (unformat (input, "l3"))
18570         {
18571           is_l2 = 0;
18572           mode_set = 1;
18573         }
18574       else
18575         {
18576           errmsg ("parse error '%U'", format_unformat_error, input);
18577           return -99;
18578         }
18579     }
18580
18581   if (!mode_set)
18582     {
18583       errmsg ("expected one of 'l2' or 'l3' parameter!");
18584       return -99;
18585     }
18586
18587   if (!vam->json_output)
18588     {
18589       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18590     }
18591
18592   M (ONE_EID_TABLE_MAP_DUMP, mp);
18593   mp->is_l2 = is_l2;
18594
18595   /* send it... */
18596   S (mp);
18597
18598   /* Use a control ping for synchronization */
18599   MPING (CONTROL_PING, mp_ping);
18600   S (mp_ping);
18601
18602   /* Wait for a reply... */
18603   W (ret);
18604   return ret;
18605 }
18606
18607 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18608
18609 static int
18610 api_one_eid_table_vni_dump (vat_main_t * vam)
18611 {
18612   vl_api_one_eid_table_vni_dump_t *mp;
18613   vl_api_control_ping_t *mp_ping;
18614   int ret;
18615
18616   if (!vam->json_output)
18617     {
18618       print (vam->ofp, "VNI");
18619     }
18620
18621   M (ONE_EID_TABLE_VNI_DUMP, mp);
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_vni_dump api_one_eid_table_vni_dump
18636
18637 static int
18638 api_one_eid_table_dump (vat_main_t * vam)
18639 {
18640   unformat_input_t *i = vam->input;
18641   vl_api_one_eid_table_dump_t *mp;
18642   vl_api_control_ping_t *mp_ping;
18643   struct in_addr ip4;
18644   struct in6_addr ip6;
18645   u8 mac[6];
18646   u8 eid_type = ~0, eid_set = 0;
18647   u32 prefix_length = ~0, t, vni = 0;
18648   u8 filter = 0;
18649   int ret;
18650   lisp_nsh_api_t nsh;
18651
18652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18653     {
18654       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18655         {
18656           eid_set = 1;
18657           eid_type = 0;
18658           prefix_length = t;
18659         }
18660       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18661         {
18662           eid_set = 1;
18663           eid_type = 1;
18664           prefix_length = t;
18665         }
18666       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18667         {
18668           eid_set = 1;
18669           eid_type = 2;
18670         }
18671       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18672         {
18673           eid_set = 1;
18674           eid_type = 3;
18675         }
18676       else if (unformat (i, "vni %d", &t))
18677         {
18678           vni = t;
18679         }
18680       else if (unformat (i, "local"))
18681         {
18682           filter = 1;
18683         }
18684       else if (unformat (i, "remote"))
18685         {
18686           filter = 2;
18687         }
18688       else
18689         {
18690           errmsg ("parse error '%U'", format_unformat_error, i);
18691           return -99;
18692         }
18693     }
18694
18695   if (!vam->json_output)
18696     {
18697       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18698              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18699     }
18700
18701   M (ONE_EID_TABLE_DUMP, mp);
18702
18703   mp->filter = filter;
18704   if (eid_set)
18705     {
18706       mp->eid_set = 1;
18707       mp->vni = htonl (vni);
18708       mp->eid_type = eid_type;
18709       switch (eid_type)
18710         {
18711         case 0:
18712           mp->prefix_length = prefix_length;
18713           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18714           break;
18715         case 1:
18716           mp->prefix_length = prefix_length;
18717           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18718           break;
18719         case 2:
18720           clib_memcpy (mp->eid, mac, sizeof (mac));
18721           break;
18722         case 3:
18723           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18724           break;
18725         default:
18726           errmsg ("unknown EID type %d!", eid_type);
18727           return -99;
18728         }
18729     }
18730
18731   /* send it... */
18732   S (mp);
18733
18734   /* Use a control ping for synchronization */
18735   MPING (CONTROL_PING, mp_ping);
18736   S (mp_ping);
18737
18738   /* Wait for a reply... */
18739   W (ret);
18740   return ret;
18741 }
18742
18743 #define api_lisp_eid_table_dump api_one_eid_table_dump
18744
18745 static int
18746 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18747 {
18748   unformat_input_t *i = vam->input;
18749   vl_api_gpe_fwd_entries_get_t *mp;
18750   u8 vni_set = 0;
18751   u32 vni = ~0;
18752   int ret;
18753
18754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18755     {
18756       if (unformat (i, "vni %d", &vni))
18757         {
18758           vni_set = 1;
18759         }
18760       else
18761         {
18762           errmsg ("parse error '%U'", format_unformat_error, i);
18763           return -99;
18764         }
18765     }
18766
18767   if (!vni_set)
18768     {
18769       errmsg ("vni not set!");
18770       return -99;
18771     }
18772
18773   if (!vam->json_output)
18774     {
18775       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18776              "leid", "reid");
18777     }
18778
18779   M (GPE_FWD_ENTRIES_GET, mp);
18780   mp->vni = clib_host_to_net_u32 (vni);
18781
18782   /* send it... */
18783   S (mp);
18784
18785   /* Wait for a reply... */
18786   W (ret);
18787   return ret;
18788 }
18789
18790 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18791 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18792 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18793 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18794 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18795 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18796 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18797 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18798
18799 static int
18800 api_one_adjacencies_get (vat_main_t * vam)
18801 {
18802   unformat_input_t *i = vam->input;
18803   vl_api_one_adjacencies_get_t *mp;
18804   u8 vni_set = 0;
18805   u32 vni = ~0;
18806   int ret;
18807
18808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18809     {
18810       if (unformat (i, "vni %d", &vni))
18811         {
18812           vni_set = 1;
18813         }
18814       else
18815         {
18816           errmsg ("parse error '%U'", format_unformat_error, i);
18817           return -99;
18818         }
18819     }
18820
18821   if (!vni_set)
18822     {
18823       errmsg ("vni not set!");
18824       return -99;
18825     }
18826
18827   if (!vam->json_output)
18828     {
18829       print (vam->ofp, "%s %40s", "leid", "reid");
18830     }
18831
18832   M (ONE_ADJACENCIES_GET, mp);
18833   mp->vni = clib_host_to_net_u32 (vni);
18834
18835   /* send it... */
18836   S (mp);
18837
18838   /* Wait for a reply... */
18839   W (ret);
18840   return ret;
18841 }
18842
18843 #define api_lisp_adjacencies_get api_one_adjacencies_get
18844
18845 static int
18846 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18847 {
18848   unformat_input_t *i = vam->input;
18849   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18850   int ret;
18851   u8 ip_family_set = 0, is_ip4 = 1;
18852
18853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18854     {
18855       if (unformat (i, "ip4"))
18856         {
18857           ip_family_set = 1;
18858           is_ip4 = 1;
18859         }
18860       else if (unformat (i, "ip6"))
18861         {
18862           ip_family_set = 1;
18863           is_ip4 = 0;
18864         }
18865       else
18866         {
18867           errmsg ("parse error '%U'", format_unformat_error, i);
18868           return -99;
18869         }
18870     }
18871
18872   if (!ip_family_set)
18873     {
18874       errmsg ("ip family not set!");
18875       return -99;
18876     }
18877
18878   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18879   mp->is_ip4 = is_ip4;
18880
18881   /* send it... */
18882   S (mp);
18883
18884   /* Wait for a reply... */
18885   W (ret);
18886   return ret;
18887 }
18888
18889 static int
18890 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18891 {
18892   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18893   int ret;
18894
18895   if (!vam->json_output)
18896     {
18897       print (vam->ofp, "VNIs");
18898     }
18899
18900   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18901
18902   /* send it... */
18903   S (mp);
18904
18905   /* Wait for a reply... */
18906   W (ret);
18907   return ret;
18908 }
18909
18910 static int
18911 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18912 {
18913   unformat_input_t *i = vam->input;
18914   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18915   int ret = 0;
18916   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18917   struct in_addr ip4;
18918   struct in6_addr ip6;
18919   u32 table_id = 0, nh_sw_if_index = ~0;
18920
18921   memset (&ip4, 0, sizeof (ip4));
18922   memset (&ip6, 0, sizeof (ip6));
18923
18924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18925     {
18926       if (unformat (i, "del"))
18927         is_add = 0;
18928       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18929                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18930         {
18931           ip_set = 1;
18932           is_ip4 = 1;
18933         }
18934       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18935                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18936         {
18937           ip_set = 1;
18938           is_ip4 = 0;
18939         }
18940       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18941         {
18942           ip_set = 1;
18943           is_ip4 = 1;
18944           nh_sw_if_index = ~0;
18945         }
18946       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18947         {
18948           ip_set = 1;
18949           is_ip4 = 0;
18950           nh_sw_if_index = ~0;
18951         }
18952       else if (unformat (i, "table %d", &table_id))
18953         ;
18954       else
18955         {
18956           errmsg ("parse error '%U'", format_unformat_error, i);
18957           return -99;
18958         }
18959     }
18960
18961   if (!ip_set)
18962     {
18963       errmsg ("nh addr not set!");
18964       return -99;
18965     }
18966
18967   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18968   mp->is_add = is_add;
18969   mp->table_id = clib_host_to_net_u32 (table_id);
18970   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18971   mp->is_ip4 = is_ip4;
18972   if (is_ip4)
18973     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18974   else
18975     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18976
18977   /* send it... */
18978   S (mp);
18979
18980   /* Wait for a reply... */
18981   W (ret);
18982   return ret;
18983 }
18984
18985 static int
18986 api_one_map_server_dump (vat_main_t * vam)
18987 {
18988   vl_api_one_map_server_dump_t *mp;
18989   vl_api_control_ping_t *mp_ping;
18990   int ret;
18991
18992   if (!vam->json_output)
18993     {
18994       print (vam->ofp, "%=20s", "Map server");
18995     }
18996
18997   M (ONE_MAP_SERVER_DUMP, mp);
18998   /* send it... */
18999   S (mp);
19000
19001   /* Use a control ping for synchronization */
19002   MPING (CONTROL_PING, mp_ping);
19003   S (mp_ping);
19004
19005   /* Wait for a reply... */
19006   W (ret);
19007   return ret;
19008 }
19009
19010 #define api_lisp_map_server_dump api_one_map_server_dump
19011
19012 static int
19013 api_one_map_resolver_dump (vat_main_t * vam)
19014 {
19015   vl_api_one_map_resolver_dump_t *mp;
19016   vl_api_control_ping_t *mp_ping;
19017   int ret;
19018
19019   if (!vam->json_output)
19020     {
19021       print (vam->ofp, "%=20s", "Map resolver");
19022     }
19023
19024   M (ONE_MAP_RESOLVER_DUMP, mp);
19025   /* send it... */
19026   S (mp);
19027
19028   /* Use a control ping for synchronization */
19029   MPING (CONTROL_PING, mp_ping);
19030   S (mp_ping);
19031
19032   /* Wait for a reply... */
19033   W (ret);
19034   return ret;
19035 }
19036
19037 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19038
19039 static int
19040 api_one_stats_flush (vat_main_t * vam)
19041 {
19042   vl_api_one_stats_flush_t *mp;
19043   int ret = 0;
19044
19045   M (ONE_STATS_FLUSH, mp);
19046   S (mp);
19047   W (ret);
19048   return ret;
19049 }
19050
19051 static int
19052 api_one_stats_dump (vat_main_t * vam)
19053 {
19054   vl_api_one_stats_dump_t *mp;
19055   vl_api_control_ping_t *mp_ping;
19056   int ret;
19057
19058   M (ONE_STATS_DUMP, mp);
19059   /* send it... */
19060   S (mp);
19061
19062   /* Use a control ping for synchronization */
19063   MPING (CONTROL_PING, mp_ping);
19064   S (mp_ping);
19065
19066   /* Wait for a reply... */
19067   W (ret);
19068   return ret;
19069 }
19070
19071 static int
19072 api_show_one_status (vat_main_t * vam)
19073 {
19074   vl_api_show_one_status_t *mp;
19075   int ret;
19076
19077   if (!vam->json_output)
19078     {
19079       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19080     }
19081
19082   M (SHOW_ONE_STATUS, mp);
19083   /* send it... */
19084   S (mp);
19085   /* Wait for a reply... */
19086   W (ret);
19087   return ret;
19088 }
19089
19090 #define api_show_lisp_status api_show_one_status
19091
19092 static int
19093 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19094 {
19095   vl_api_gpe_fwd_entry_path_dump_t *mp;
19096   vl_api_control_ping_t *mp_ping;
19097   unformat_input_t *i = vam->input;
19098   u32 fwd_entry_index = ~0;
19099   int ret;
19100
19101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19102     {
19103       if (unformat (i, "index %d", &fwd_entry_index))
19104         ;
19105       else
19106         break;
19107     }
19108
19109   if (~0 == fwd_entry_index)
19110     {
19111       errmsg ("no index specified!");
19112       return -99;
19113     }
19114
19115   if (!vam->json_output)
19116     {
19117       print (vam->ofp, "first line");
19118     }
19119
19120   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19121
19122   /* send it... */
19123   S (mp);
19124   /* Use a control ping for synchronization */
19125   MPING (CONTROL_PING, mp_ping);
19126   S (mp_ping);
19127
19128   /* Wait for a reply... */
19129   W (ret);
19130   return ret;
19131 }
19132
19133 static int
19134 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19135 {
19136   vl_api_one_get_map_request_itr_rlocs_t *mp;
19137   int ret;
19138
19139   if (!vam->json_output)
19140     {
19141       print (vam->ofp, "%=20s", "itr-rlocs:");
19142     }
19143
19144   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19145   /* send it... */
19146   S (mp);
19147   /* Wait for a reply... */
19148   W (ret);
19149   return ret;
19150 }
19151
19152 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19153
19154 static int
19155 api_af_packet_create (vat_main_t * vam)
19156 {
19157   unformat_input_t *i = vam->input;
19158   vl_api_af_packet_create_t *mp;
19159   u8 *host_if_name = 0;
19160   u8 hw_addr[6];
19161   u8 random_hw_addr = 1;
19162   int ret;
19163
19164   memset (hw_addr, 0, sizeof (hw_addr));
19165
19166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19167     {
19168       if (unformat (i, "name %s", &host_if_name))
19169         vec_add1 (host_if_name, 0);
19170       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19171         random_hw_addr = 0;
19172       else
19173         break;
19174     }
19175
19176   if (!vec_len (host_if_name))
19177     {
19178       errmsg ("host-interface name must be specified");
19179       return -99;
19180     }
19181
19182   if (vec_len (host_if_name) > 64)
19183     {
19184       errmsg ("host-interface name too long");
19185       return -99;
19186     }
19187
19188   M (AF_PACKET_CREATE, mp);
19189
19190   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19191   clib_memcpy (mp->hw_addr, hw_addr, 6);
19192   mp->use_random_hw_addr = random_hw_addr;
19193   vec_free (host_if_name);
19194
19195   S (mp);
19196
19197   /* *INDENT-OFF* */
19198   W2 (ret,
19199       ({
19200         if (ret == 0)
19201           fprintf (vam->ofp ? vam->ofp : stderr,
19202                    " new sw_if_index = %d\n", vam->sw_if_index);
19203       }));
19204   /* *INDENT-ON* */
19205   return ret;
19206 }
19207
19208 static int
19209 api_af_packet_delete (vat_main_t * vam)
19210 {
19211   unformat_input_t *i = vam->input;
19212   vl_api_af_packet_delete_t *mp;
19213   u8 *host_if_name = 0;
19214   int ret;
19215
19216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19217     {
19218       if (unformat (i, "name %s", &host_if_name))
19219         vec_add1 (host_if_name, 0);
19220       else
19221         break;
19222     }
19223
19224   if (!vec_len (host_if_name))
19225     {
19226       errmsg ("host-interface name must be specified");
19227       return -99;
19228     }
19229
19230   if (vec_len (host_if_name) > 64)
19231     {
19232       errmsg ("host-interface name too long");
19233       return -99;
19234     }
19235
19236   M (AF_PACKET_DELETE, mp);
19237
19238   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19239   vec_free (host_if_name);
19240
19241   S (mp);
19242   W (ret);
19243   return ret;
19244 }
19245
19246 static int
19247 api_policer_add_del (vat_main_t * vam)
19248 {
19249   unformat_input_t *i = vam->input;
19250   vl_api_policer_add_del_t *mp;
19251   u8 is_add = 1;
19252   u8 *name = 0;
19253   u32 cir = 0;
19254   u32 eir = 0;
19255   u64 cb = 0;
19256   u64 eb = 0;
19257   u8 rate_type = 0;
19258   u8 round_type = 0;
19259   u8 type = 0;
19260   u8 color_aware = 0;
19261   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19262   int ret;
19263
19264   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19265   conform_action.dscp = 0;
19266   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19267   exceed_action.dscp = 0;
19268   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19269   violate_action.dscp = 0;
19270
19271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19272     {
19273       if (unformat (i, "del"))
19274         is_add = 0;
19275       else if (unformat (i, "name %s", &name))
19276         vec_add1 (name, 0);
19277       else if (unformat (i, "cir %u", &cir))
19278         ;
19279       else if (unformat (i, "eir %u", &eir))
19280         ;
19281       else if (unformat (i, "cb %u", &cb))
19282         ;
19283       else if (unformat (i, "eb %u", &eb))
19284         ;
19285       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19286                          &rate_type))
19287         ;
19288       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19289                          &round_type))
19290         ;
19291       else if (unformat (i, "type %U", unformat_policer_type, &type))
19292         ;
19293       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19294                          &conform_action))
19295         ;
19296       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19297                          &exceed_action))
19298         ;
19299       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19300                          &violate_action))
19301         ;
19302       else if (unformat (i, "color-aware"))
19303         color_aware = 1;
19304       else
19305         break;
19306     }
19307
19308   if (!vec_len (name))
19309     {
19310       errmsg ("policer name must be specified");
19311       return -99;
19312     }
19313
19314   if (vec_len (name) > 64)
19315     {
19316       errmsg ("policer name too long");
19317       return -99;
19318     }
19319
19320   M (POLICER_ADD_DEL, mp);
19321
19322   clib_memcpy (mp->name, name, vec_len (name));
19323   vec_free (name);
19324   mp->is_add = is_add;
19325   mp->cir = ntohl (cir);
19326   mp->eir = ntohl (eir);
19327   mp->cb = clib_net_to_host_u64 (cb);
19328   mp->eb = clib_net_to_host_u64 (eb);
19329   mp->rate_type = rate_type;
19330   mp->round_type = round_type;
19331   mp->type = type;
19332   mp->conform_action_type = conform_action.action_type;
19333   mp->conform_dscp = conform_action.dscp;
19334   mp->exceed_action_type = exceed_action.action_type;
19335   mp->exceed_dscp = exceed_action.dscp;
19336   mp->violate_action_type = violate_action.action_type;
19337   mp->violate_dscp = violate_action.dscp;
19338   mp->color_aware = color_aware;
19339
19340   S (mp);
19341   W (ret);
19342   return ret;
19343 }
19344
19345 static int
19346 api_policer_dump (vat_main_t * vam)
19347 {
19348   unformat_input_t *i = vam->input;
19349   vl_api_policer_dump_t *mp;
19350   vl_api_control_ping_t *mp_ping;
19351   u8 *match_name = 0;
19352   u8 match_name_valid = 0;
19353   int ret;
19354
19355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19356     {
19357       if (unformat (i, "name %s", &match_name))
19358         {
19359           vec_add1 (match_name, 0);
19360           match_name_valid = 1;
19361         }
19362       else
19363         break;
19364     }
19365
19366   M (POLICER_DUMP, mp);
19367   mp->match_name_valid = match_name_valid;
19368   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19369   vec_free (match_name);
19370   /* send it... */
19371   S (mp);
19372
19373   /* Use a control ping for synchronization */
19374   MPING (CONTROL_PING, mp_ping);
19375   S (mp_ping);
19376
19377   /* Wait for a reply... */
19378   W (ret);
19379   return ret;
19380 }
19381
19382 static int
19383 api_policer_classify_set_interface (vat_main_t * vam)
19384 {
19385   unformat_input_t *i = vam->input;
19386   vl_api_policer_classify_set_interface_t *mp;
19387   u32 sw_if_index;
19388   int sw_if_index_set;
19389   u32 ip4_table_index = ~0;
19390   u32 ip6_table_index = ~0;
19391   u32 l2_table_index = ~0;
19392   u8 is_add = 1;
19393   int ret;
19394
19395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19396     {
19397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19398         sw_if_index_set = 1;
19399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19400         sw_if_index_set = 1;
19401       else if (unformat (i, "del"))
19402         is_add = 0;
19403       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19404         ;
19405       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19406         ;
19407       else if (unformat (i, "l2-table %d", &l2_table_index))
19408         ;
19409       else
19410         {
19411           clib_warning ("parse error '%U'", format_unformat_error, i);
19412           return -99;
19413         }
19414     }
19415
19416   if (sw_if_index_set == 0)
19417     {
19418       errmsg ("missing interface name or sw_if_index");
19419       return -99;
19420     }
19421
19422   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19423
19424   mp->sw_if_index = ntohl (sw_if_index);
19425   mp->ip4_table_index = ntohl (ip4_table_index);
19426   mp->ip6_table_index = ntohl (ip6_table_index);
19427   mp->l2_table_index = ntohl (l2_table_index);
19428   mp->is_add = is_add;
19429
19430   S (mp);
19431   W (ret);
19432   return ret;
19433 }
19434
19435 static int
19436 api_policer_classify_dump (vat_main_t * vam)
19437 {
19438   unformat_input_t *i = vam->input;
19439   vl_api_policer_classify_dump_t *mp;
19440   vl_api_control_ping_t *mp_ping;
19441   u8 type = POLICER_CLASSIFY_N_TABLES;
19442   int ret;
19443
19444   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19445     ;
19446   else
19447     {
19448       errmsg ("classify table type must be specified");
19449       return -99;
19450     }
19451
19452   if (!vam->json_output)
19453     {
19454       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19455     }
19456
19457   M (POLICER_CLASSIFY_DUMP, mp);
19458   mp->type = type;
19459   /* send it... */
19460   S (mp);
19461
19462   /* Use a control ping for synchronization */
19463   MPING (CONTROL_PING, mp_ping);
19464   S (mp_ping);
19465
19466   /* Wait for a reply... */
19467   W (ret);
19468   return ret;
19469 }
19470
19471 static int
19472 api_netmap_create (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_netmap_create_t *mp;
19476   u8 *if_name = 0;
19477   u8 hw_addr[6];
19478   u8 random_hw_addr = 1;
19479   u8 is_pipe = 0;
19480   u8 is_master = 0;
19481   int ret;
19482
19483   memset (hw_addr, 0, sizeof (hw_addr));
19484
19485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19486     {
19487       if (unformat (i, "name %s", &if_name))
19488         vec_add1 (if_name, 0);
19489       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19490         random_hw_addr = 0;
19491       else if (unformat (i, "pipe"))
19492         is_pipe = 1;
19493       else if (unformat (i, "master"))
19494         is_master = 1;
19495       else if (unformat (i, "slave"))
19496         is_master = 0;
19497       else
19498         break;
19499     }
19500
19501   if (!vec_len (if_name))
19502     {
19503       errmsg ("interface name must be specified");
19504       return -99;
19505     }
19506
19507   if (vec_len (if_name) > 64)
19508     {
19509       errmsg ("interface name too long");
19510       return -99;
19511     }
19512
19513   M (NETMAP_CREATE, mp);
19514
19515   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19516   clib_memcpy (mp->hw_addr, hw_addr, 6);
19517   mp->use_random_hw_addr = random_hw_addr;
19518   mp->is_pipe = is_pipe;
19519   mp->is_master = is_master;
19520   vec_free (if_name);
19521
19522   S (mp);
19523   W (ret);
19524   return ret;
19525 }
19526
19527 static int
19528 api_netmap_delete (vat_main_t * vam)
19529 {
19530   unformat_input_t *i = vam->input;
19531   vl_api_netmap_delete_t *mp;
19532   u8 *if_name = 0;
19533   int ret;
19534
19535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19536     {
19537       if (unformat (i, "name %s", &if_name))
19538         vec_add1 (if_name, 0);
19539       else
19540         break;
19541     }
19542
19543   if (!vec_len (if_name))
19544     {
19545       errmsg ("interface name must be specified");
19546       return -99;
19547     }
19548
19549   if (vec_len (if_name) > 64)
19550     {
19551       errmsg ("interface name too long");
19552       return -99;
19553     }
19554
19555   M (NETMAP_DELETE, mp);
19556
19557   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19558   vec_free (if_name);
19559
19560   S (mp);
19561   W (ret);
19562   return ret;
19563 }
19564
19565 static void
19566 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19567 {
19568   if (fp->afi == IP46_TYPE_IP6)
19569     print (vam->ofp,
19570            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19571            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19572            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19573            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19574            format_ip6_address, fp->next_hop);
19575   else if (fp->afi == IP46_TYPE_IP4)
19576     print (vam->ofp,
19577            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19578            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19579            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19580            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19581            format_ip4_address, fp->next_hop);
19582 }
19583
19584 static void
19585 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19586                                  vl_api_fib_path2_t * fp)
19587 {
19588   struct in_addr ip4;
19589   struct in6_addr ip6;
19590
19591   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19592   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19593   vat_json_object_add_uint (node, "is_local", fp->is_local);
19594   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19595   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19596   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19597   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19598   if (fp->afi == IP46_TYPE_IP4)
19599     {
19600       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19601       vat_json_object_add_ip4 (node, "next_hop", ip4);
19602     }
19603   else if (fp->afi == IP46_TYPE_IP6)
19604     {
19605       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19606       vat_json_object_add_ip6 (node, "next_hop", ip6);
19607     }
19608 }
19609
19610 static void
19611 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19612 {
19613   vat_main_t *vam = &vat_main;
19614   int count = ntohl (mp->mt_count);
19615   vl_api_fib_path2_t *fp;
19616   i32 i;
19617
19618   print (vam->ofp, "[%d]: sw_if_index %d via:",
19619          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19620   fp = mp->mt_paths;
19621   for (i = 0; i < count; i++)
19622     {
19623       vl_api_mpls_fib_path_print (vam, fp);
19624       fp++;
19625     }
19626
19627   print (vam->ofp, "");
19628 }
19629
19630 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19631 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19632
19633 static void
19634 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19635 {
19636   vat_main_t *vam = &vat_main;
19637   vat_json_node_t *node = NULL;
19638   int count = ntohl (mp->mt_count);
19639   vl_api_fib_path2_t *fp;
19640   i32 i;
19641
19642   if (VAT_JSON_ARRAY != vam->json_tree.type)
19643     {
19644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19645       vat_json_init_array (&vam->json_tree);
19646     }
19647   node = vat_json_array_add (&vam->json_tree);
19648
19649   vat_json_init_object (node);
19650   vat_json_object_add_uint (node, "tunnel_index",
19651                             ntohl (mp->mt_tunnel_index));
19652   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19653
19654   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19655
19656   fp = mp->mt_paths;
19657   for (i = 0; i < count; i++)
19658     {
19659       vl_api_mpls_fib_path_json_print (node, fp);
19660       fp++;
19661     }
19662 }
19663
19664 static int
19665 api_mpls_tunnel_dump (vat_main_t * vam)
19666 {
19667   vl_api_mpls_tunnel_dump_t *mp;
19668   vl_api_control_ping_t *mp_ping;
19669   i32 index = -1;
19670   int ret;
19671
19672   /* Parse args required to build the message */
19673   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19674     {
19675       if (!unformat (vam->input, "tunnel_index %d", &index))
19676         {
19677           index = -1;
19678           break;
19679         }
19680     }
19681
19682   print (vam->ofp, "  tunnel_index %d", index);
19683
19684   M (MPLS_TUNNEL_DUMP, mp);
19685   mp->tunnel_index = htonl (index);
19686   S (mp);
19687
19688   /* Use a control ping for synchronization */
19689   MPING (CONTROL_PING, mp_ping);
19690   S (mp_ping);
19691
19692   W (ret);
19693   return ret;
19694 }
19695
19696 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19697 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19698
19699
19700 static void
19701 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19702 {
19703   vat_main_t *vam = &vat_main;
19704   int count = ntohl (mp->count);
19705   vl_api_fib_path2_t *fp;
19706   int i;
19707
19708   print (vam->ofp,
19709          "table-id %d, label %u, ess_bit %u",
19710          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19711   fp = mp->path;
19712   for (i = 0; i < count; i++)
19713     {
19714       vl_api_mpls_fib_path_print (vam, fp);
19715       fp++;
19716     }
19717 }
19718
19719 static void vl_api_mpls_fib_details_t_handler_json
19720   (vl_api_mpls_fib_details_t * mp)
19721 {
19722   vat_main_t *vam = &vat_main;
19723   int count = ntohl (mp->count);
19724   vat_json_node_t *node = NULL;
19725   vl_api_fib_path2_t *fp;
19726   int i;
19727
19728   if (VAT_JSON_ARRAY != vam->json_tree.type)
19729     {
19730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19731       vat_json_init_array (&vam->json_tree);
19732     }
19733   node = vat_json_array_add (&vam->json_tree);
19734
19735   vat_json_init_object (node);
19736   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19737   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19738   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19739   vat_json_object_add_uint (node, "path_count", count);
19740   fp = mp->path;
19741   for (i = 0; i < count; i++)
19742     {
19743       vl_api_mpls_fib_path_json_print (node, fp);
19744       fp++;
19745     }
19746 }
19747
19748 static int
19749 api_mpls_fib_dump (vat_main_t * vam)
19750 {
19751   vl_api_mpls_fib_dump_t *mp;
19752   vl_api_control_ping_t *mp_ping;
19753   int ret;
19754
19755   M (MPLS_FIB_DUMP, mp);
19756   S (mp);
19757
19758   /* Use a control ping for synchronization */
19759   MPING (CONTROL_PING, mp_ping);
19760   S (mp_ping);
19761
19762   W (ret);
19763   return ret;
19764 }
19765
19766 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19767 #define vl_api_ip_fib_details_t_print vl_noop_handler
19768
19769 static void
19770 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19771 {
19772   vat_main_t *vam = &vat_main;
19773   int count = ntohl (mp->count);
19774   vl_api_fib_path_t *fp;
19775   int i;
19776
19777   print (vam->ofp,
19778          "table-id %d, prefix %U/%d",
19779          ntohl (mp->table_id), format_ip4_address, mp->address,
19780          mp->address_length);
19781   fp = mp->path;
19782   for (i = 0; i < count; i++)
19783     {
19784       if (fp->afi == IP46_TYPE_IP6)
19785         print (vam->ofp,
19786                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19787                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19788                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19789                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19790                format_ip6_address, fp->next_hop);
19791       else if (fp->afi == IP46_TYPE_IP4)
19792         print (vam->ofp,
19793                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19794                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19795                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19796                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19797                format_ip4_address, fp->next_hop);
19798       fp++;
19799     }
19800 }
19801
19802 static void vl_api_ip_fib_details_t_handler_json
19803   (vl_api_ip_fib_details_t * mp)
19804 {
19805   vat_main_t *vam = &vat_main;
19806   int count = ntohl (mp->count);
19807   vat_json_node_t *node = NULL;
19808   struct in_addr ip4;
19809   struct in6_addr ip6;
19810   vl_api_fib_path_t *fp;
19811   int i;
19812
19813   if (VAT_JSON_ARRAY != vam->json_tree.type)
19814     {
19815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19816       vat_json_init_array (&vam->json_tree);
19817     }
19818   node = vat_json_array_add (&vam->json_tree);
19819
19820   vat_json_init_object (node);
19821   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19822   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19823   vat_json_object_add_ip4 (node, "prefix", ip4);
19824   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19825   vat_json_object_add_uint (node, "path_count", count);
19826   fp = mp->path;
19827   for (i = 0; i < count; i++)
19828     {
19829       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19830       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19831       vat_json_object_add_uint (node, "is_local", fp->is_local);
19832       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19833       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19834       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19835       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19836       if (fp->afi == IP46_TYPE_IP4)
19837         {
19838           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19839           vat_json_object_add_ip4 (node, "next_hop", ip4);
19840         }
19841       else if (fp->afi == IP46_TYPE_IP6)
19842         {
19843           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19844           vat_json_object_add_ip6 (node, "next_hop", ip6);
19845         }
19846     }
19847 }
19848
19849 static int
19850 api_ip_fib_dump (vat_main_t * vam)
19851 {
19852   vl_api_ip_fib_dump_t *mp;
19853   vl_api_control_ping_t *mp_ping;
19854   int ret;
19855
19856   M (IP_FIB_DUMP, mp);
19857   S (mp);
19858
19859   /* Use a control ping for synchronization */
19860   MPING (CONTROL_PING, mp_ping);
19861   S (mp_ping);
19862
19863   W (ret);
19864   return ret;
19865 }
19866
19867 static int
19868 api_ip_mfib_dump (vat_main_t * vam)
19869 {
19870   vl_api_ip_mfib_dump_t *mp;
19871   vl_api_control_ping_t *mp_ping;
19872   int ret;
19873
19874   M (IP_MFIB_DUMP, mp);
19875   S (mp);
19876
19877   /* Use a control ping for synchronization */
19878   MPING (CONTROL_PING, mp_ping);
19879   S (mp_ping);
19880
19881   W (ret);
19882   return ret;
19883 }
19884
19885 static void vl_api_ip_neighbor_details_t_handler
19886   (vl_api_ip_neighbor_details_t * mp)
19887 {
19888   vat_main_t *vam = &vat_main;
19889
19890   print (vam->ofp, "%c %U %U",
19891          (mp->is_static) ? 'S' : 'D',
19892          format_ethernet_address, &mp->mac_address,
19893          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19894          &mp->ip_address);
19895 }
19896
19897 static void vl_api_ip_neighbor_details_t_handler_json
19898   (vl_api_ip_neighbor_details_t * mp)
19899 {
19900
19901   vat_main_t *vam = &vat_main;
19902   vat_json_node_t *node;
19903   struct in_addr ip4;
19904   struct in6_addr ip6;
19905
19906   if (VAT_JSON_ARRAY != vam->json_tree.type)
19907     {
19908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19909       vat_json_init_array (&vam->json_tree);
19910     }
19911   node = vat_json_array_add (&vam->json_tree);
19912
19913   vat_json_init_object (node);
19914   vat_json_object_add_string_copy (node, "flag",
19915                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19916                                    "dynamic");
19917
19918   vat_json_object_add_string_copy (node, "link_layer",
19919                                    format (0, "%U", format_ethernet_address,
19920                                            &mp->mac_address));
19921
19922   if (mp->is_ipv6)
19923     {
19924       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19925       vat_json_object_add_ip6 (node, "ip_address", ip6);
19926     }
19927   else
19928     {
19929       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19930       vat_json_object_add_ip4 (node, "ip_address", ip4);
19931     }
19932 }
19933
19934 static int
19935 api_ip_neighbor_dump (vat_main_t * vam)
19936 {
19937   unformat_input_t *i = vam->input;
19938   vl_api_ip_neighbor_dump_t *mp;
19939   vl_api_control_ping_t *mp_ping;
19940   u8 is_ipv6 = 0;
19941   u32 sw_if_index = ~0;
19942   int ret;
19943
19944   /* Parse args required to build the message */
19945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19946     {
19947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19948         ;
19949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19950         ;
19951       else if (unformat (i, "ip6"))
19952         is_ipv6 = 1;
19953       else
19954         break;
19955     }
19956
19957   if (sw_if_index == ~0)
19958     {
19959       errmsg ("missing interface name or sw_if_index");
19960       return -99;
19961     }
19962
19963   M (IP_NEIGHBOR_DUMP, mp);
19964   mp->is_ipv6 = (u8) is_ipv6;
19965   mp->sw_if_index = ntohl (sw_if_index);
19966   S (mp);
19967
19968   /* Use a control ping for synchronization */
19969   MPING (CONTROL_PING, mp_ping);
19970   S (mp_ping);
19971
19972   W (ret);
19973   return ret;
19974 }
19975
19976 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19977 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19978
19979 static void
19980 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19981 {
19982   vat_main_t *vam = &vat_main;
19983   int count = ntohl (mp->count);
19984   vl_api_fib_path_t *fp;
19985   int i;
19986
19987   print (vam->ofp,
19988          "table-id %d, prefix %U/%d",
19989          ntohl (mp->table_id), format_ip6_address, mp->address,
19990          mp->address_length);
19991   fp = mp->path;
19992   for (i = 0; i < count; i++)
19993     {
19994       if (fp->afi == IP46_TYPE_IP6)
19995         print (vam->ofp,
19996                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19997                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19998                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19999                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20000                format_ip6_address, fp->next_hop);
20001       else if (fp->afi == IP46_TYPE_IP4)
20002         print (vam->ofp,
20003                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20004                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20005                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20006                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20007                format_ip4_address, fp->next_hop);
20008       fp++;
20009     }
20010 }
20011
20012 static void vl_api_ip6_fib_details_t_handler_json
20013   (vl_api_ip6_fib_details_t * mp)
20014 {
20015   vat_main_t *vam = &vat_main;
20016   int count = ntohl (mp->count);
20017   vat_json_node_t *node = NULL;
20018   struct in_addr ip4;
20019   struct in6_addr ip6;
20020   vl_api_fib_path_t *fp;
20021   int i;
20022
20023   if (VAT_JSON_ARRAY != vam->json_tree.type)
20024     {
20025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20026       vat_json_init_array (&vam->json_tree);
20027     }
20028   node = vat_json_array_add (&vam->json_tree);
20029
20030   vat_json_init_object (node);
20031   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20032   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20033   vat_json_object_add_ip6 (node, "prefix", ip6);
20034   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20035   vat_json_object_add_uint (node, "path_count", count);
20036   fp = mp->path;
20037   for (i = 0; i < count; i++)
20038     {
20039       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20040       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20041       vat_json_object_add_uint (node, "is_local", fp->is_local);
20042       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20043       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20044       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20045       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20046       if (fp->afi == IP46_TYPE_IP4)
20047         {
20048           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20049           vat_json_object_add_ip4 (node, "next_hop", ip4);
20050         }
20051       else if (fp->afi == IP46_TYPE_IP6)
20052         {
20053           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20054           vat_json_object_add_ip6 (node, "next_hop", ip6);
20055         }
20056     }
20057 }
20058
20059 static int
20060 api_ip6_fib_dump (vat_main_t * vam)
20061 {
20062   vl_api_ip6_fib_dump_t *mp;
20063   vl_api_control_ping_t *mp_ping;
20064   int ret;
20065
20066   M (IP6_FIB_DUMP, mp);
20067   S (mp);
20068
20069   /* Use a control ping for synchronization */
20070   MPING (CONTROL_PING, mp_ping);
20071   S (mp_ping);
20072
20073   W (ret);
20074   return ret;
20075 }
20076
20077 static int
20078 api_ip6_mfib_dump (vat_main_t * vam)
20079 {
20080   vl_api_ip6_mfib_dump_t *mp;
20081   vl_api_control_ping_t *mp_ping;
20082   int ret;
20083
20084   M (IP6_MFIB_DUMP, mp);
20085   S (mp);
20086
20087   /* Use a control ping for synchronization */
20088   MPING (CONTROL_PING, mp_ping);
20089   S (mp_ping);
20090
20091   W (ret);
20092   return ret;
20093 }
20094
20095 int
20096 api_classify_table_ids (vat_main_t * vam)
20097 {
20098   vl_api_classify_table_ids_t *mp;
20099   int ret;
20100
20101   /* Construct the API message */
20102   M (CLASSIFY_TABLE_IDS, mp);
20103   mp->context = 0;
20104
20105   S (mp);
20106   W (ret);
20107   return ret;
20108 }
20109
20110 int
20111 api_classify_table_by_interface (vat_main_t * vam)
20112 {
20113   unformat_input_t *input = vam->input;
20114   vl_api_classify_table_by_interface_t *mp;
20115
20116   u32 sw_if_index = ~0;
20117   int ret;
20118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20119     {
20120       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20121         ;
20122       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20123         ;
20124       else
20125         break;
20126     }
20127   if (sw_if_index == ~0)
20128     {
20129       errmsg ("missing interface name or sw_if_index");
20130       return -99;
20131     }
20132
20133   /* Construct the API message */
20134   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20135   mp->context = 0;
20136   mp->sw_if_index = ntohl (sw_if_index);
20137
20138   S (mp);
20139   W (ret);
20140   return ret;
20141 }
20142
20143 int
20144 api_classify_table_info (vat_main_t * vam)
20145 {
20146   unformat_input_t *input = vam->input;
20147   vl_api_classify_table_info_t *mp;
20148
20149   u32 table_id = ~0;
20150   int ret;
20151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20152     {
20153       if (unformat (input, "table_id %d", &table_id))
20154         ;
20155       else
20156         break;
20157     }
20158   if (table_id == ~0)
20159     {
20160       errmsg ("missing table id");
20161       return -99;
20162     }
20163
20164   /* Construct the API message */
20165   M (CLASSIFY_TABLE_INFO, mp);
20166   mp->context = 0;
20167   mp->table_id = ntohl (table_id);
20168
20169   S (mp);
20170   W (ret);
20171   return ret;
20172 }
20173
20174 int
20175 api_classify_session_dump (vat_main_t * vam)
20176 {
20177   unformat_input_t *input = vam->input;
20178   vl_api_classify_session_dump_t *mp;
20179   vl_api_control_ping_t *mp_ping;
20180
20181   u32 table_id = ~0;
20182   int ret;
20183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20184     {
20185       if (unformat (input, "table_id %d", &table_id))
20186         ;
20187       else
20188         break;
20189     }
20190   if (table_id == ~0)
20191     {
20192       errmsg ("missing table id");
20193       return -99;
20194     }
20195
20196   /* Construct the API message */
20197   M (CLASSIFY_SESSION_DUMP, mp);
20198   mp->context = 0;
20199   mp->table_id = ntohl (table_id);
20200   S (mp);
20201
20202   /* Use a control ping for synchronization */
20203   MPING (CONTROL_PING, mp_ping);
20204   S (mp_ping);
20205
20206   W (ret);
20207   return ret;
20208 }
20209
20210 static void
20211 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20212 {
20213   vat_main_t *vam = &vat_main;
20214
20215   print (vam->ofp, "collector_address %U, collector_port %d, "
20216          "src_address %U, vrf_id %d, path_mtu %u, "
20217          "template_interval %u, udp_checksum %d",
20218          format_ip4_address, mp->collector_address,
20219          ntohs (mp->collector_port),
20220          format_ip4_address, mp->src_address,
20221          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20222          ntohl (mp->template_interval), mp->udp_checksum);
20223
20224   vam->retval = 0;
20225   vam->result_ready = 1;
20226 }
20227
20228 static void
20229   vl_api_ipfix_exporter_details_t_handler_json
20230   (vl_api_ipfix_exporter_details_t * mp)
20231 {
20232   vat_main_t *vam = &vat_main;
20233   vat_json_node_t node;
20234   struct in_addr collector_address;
20235   struct in_addr src_address;
20236
20237   vat_json_init_object (&node);
20238   clib_memcpy (&collector_address, &mp->collector_address,
20239                sizeof (collector_address));
20240   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20241   vat_json_object_add_uint (&node, "collector_port",
20242                             ntohs (mp->collector_port));
20243   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20244   vat_json_object_add_ip4 (&node, "src_address", src_address);
20245   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20246   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20247   vat_json_object_add_uint (&node, "template_interval",
20248                             ntohl (mp->template_interval));
20249   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20250
20251   vat_json_print (vam->ofp, &node);
20252   vat_json_free (&node);
20253   vam->retval = 0;
20254   vam->result_ready = 1;
20255 }
20256
20257 int
20258 api_ipfix_exporter_dump (vat_main_t * vam)
20259 {
20260   vl_api_ipfix_exporter_dump_t *mp;
20261   int ret;
20262
20263   /* Construct the API message */
20264   M (IPFIX_EXPORTER_DUMP, mp);
20265   mp->context = 0;
20266
20267   S (mp);
20268   W (ret);
20269   return ret;
20270 }
20271
20272 static int
20273 api_ipfix_classify_stream_dump (vat_main_t * vam)
20274 {
20275   vl_api_ipfix_classify_stream_dump_t *mp;
20276   int ret;
20277
20278   /* Construct the API message */
20279   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20280   mp->context = 0;
20281
20282   S (mp);
20283   W (ret);
20284   return ret;
20285   /* NOTREACHED */
20286   return 0;
20287 }
20288
20289 static void
20290   vl_api_ipfix_classify_stream_details_t_handler
20291   (vl_api_ipfix_classify_stream_details_t * mp)
20292 {
20293   vat_main_t *vam = &vat_main;
20294   print (vam->ofp, "domain_id %d, src_port %d",
20295          ntohl (mp->domain_id), ntohs (mp->src_port));
20296   vam->retval = 0;
20297   vam->result_ready = 1;
20298 }
20299
20300 static void
20301   vl_api_ipfix_classify_stream_details_t_handler_json
20302   (vl_api_ipfix_classify_stream_details_t * mp)
20303 {
20304   vat_main_t *vam = &vat_main;
20305   vat_json_node_t node;
20306
20307   vat_json_init_object (&node);
20308   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20309   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20310
20311   vat_json_print (vam->ofp, &node);
20312   vat_json_free (&node);
20313   vam->retval = 0;
20314   vam->result_ready = 1;
20315 }
20316
20317 static int
20318 api_ipfix_classify_table_dump (vat_main_t * vam)
20319 {
20320   vl_api_ipfix_classify_table_dump_t *mp;
20321   vl_api_control_ping_t *mp_ping;
20322   int ret;
20323
20324   if (!vam->json_output)
20325     {
20326       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20327              "transport_protocol");
20328     }
20329
20330   /* Construct the API message */
20331   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20332
20333   /* send it... */
20334   S (mp);
20335
20336   /* Use a control ping for synchronization */
20337   MPING (CONTROL_PING, mp_ping);
20338   S (mp_ping);
20339
20340   W (ret);
20341   return ret;
20342 }
20343
20344 static void
20345   vl_api_ipfix_classify_table_details_t_handler
20346   (vl_api_ipfix_classify_table_details_t * mp)
20347 {
20348   vat_main_t *vam = &vat_main;
20349   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20350          mp->transport_protocol);
20351 }
20352
20353 static void
20354   vl_api_ipfix_classify_table_details_t_handler_json
20355   (vl_api_ipfix_classify_table_details_t * mp)
20356 {
20357   vat_json_node_t *node = NULL;
20358   vat_main_t *vam = &vat_main;
20359
20360   if (VAT_JSON_ARRAY != vam->json_tree.type)
20361     {
20362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20363       vat_json_init_array (&vam->json_tree);
20364     }
20365
20366   node = vat_json_array_add (&vam->json_tree);
20367   vat_json_init_object (node);
20368
20369   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20370   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20371   vat_json_object_add_uint (node, "transport_protocol",
20372                             mp->transport_protocol);
20373 }
20374
20375 static int
20376 api_sw_interface_span_enable_disable (vat_main_t * vam)
20377 {
20378   unformat_input_t *i = vam->input;
20379   vl_api_sw_interface_span_enable_disable_t *mp;
20380   u32 src_sw_if_index = ~0;
20381   u32 dst_sw_if_index = ~0;
20382   u8 state = 3;
20383   int ret;
20384   u8 is_l2 = 0;
20385
20386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20387     {
20388       if (unformat
20389           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20390         ;
20391       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20392         ;
20393       else
20394         if (unformat
20395             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20396         ;
20397       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20398         ;
20399       else if (unformat (i, "disable"))
20400         state = 0;
20401       else if (unformat (i, "rx"))
20402         state = 1;
20403       else if (unformat (i, "tx"))
20404         state = 2;
20405       else if (unformat (i, "both"))
20406         state = 3;
20407       else if (unformat (i, "l2"))
20408         is_l2 = 1;
20409       else
20410         break;
20411     }
20412
20413   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20414
20415   mp->sw_if_index_from = htonl (src_sw_if_index);
20416   mp->sw_if_index_to = htonl (dst_sw_if_index);
20417   mp->state = state;
20418   mp->is_l2 = is_l2;
20419
20420   S (mp);
20421   W (ret);
20422   return ret;
20423 }
20424
20425 static void
20426 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20427                                             * mp)
20428 {
20429   vat_main_t *vam = &vat_main;
20430   u8 *sw_if_from_name = 0;
20431   u8 *sw_if_to_name = 0;
20432   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20433   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20434   char *states[] = { "none", "rx", "tx", "both" };
20435   hash_pair_t *p;
20436
20437   /* *INDENT-OFF* */
20438   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20439   ({
20440     if ((u32) p->value[0] == sw_if_index_from)
20441       {
20442         sw_if_from_name = (u8 *)(p->key);
20443         if (sw_if_to_name)
20444           break;
20445       }
20446     if ((u32) p->value[0] == sw_if_index_to)
20447       {
20448         sw_if_to_name = (u8 *)(p->key);
20449         if (sw_if_from_name)
20450           break;
20451       }
20452   }));
20453   /* *INDENT-ON* */
20454   print (vam->ofp, "%20s => %20s (%s)",
20455          sw_if_from_name, sw_if_to_name, states[mp->state]);
20456 }
20457
20458 static void
20459   vl_api_sw_interface_span_details_t_handler_json
20460   (vl_api_sw_interface_span_details_t * mp)
20461 {
20462   vat_main_t *vam = &vat_main;
20463   vat_json_node_t *node = NULL;
20464   u8 *sw_if_from_name = 0;
20465   u8 *sw_if_to_name = 0;
20466   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20467   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20468   hash_pair_t *p;
20469
20470   /* *INDENT-OFF* */
20471   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20472   ({
20473     if ((u32) p->value[0] == sw_if_index_from)
20474       {
20475         sw_if_from_name = (u8 *)(p->key);
20476         if (sw_if_to_name)
20477           break;
20478       }
20479     if ((u32) p->value[0] == sw_if_index_to)
20480       {
20481         sw_if_to_name = (u8 *)(p->key);
20482         if (sw_if_from_name)
20483           break;
20484       }
20485   }));
20486   /* *INDENT-ON* */
20487
20488   if (VAT_JSON_ARRAY != vam->json_tree.type)
20489     {
20490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20491       vat_json_init_array (&vam->json_tree);
20492     }
20493   node = vat_json_array_add (&vam->json_tree);
20494
20495   vat_json_init_object (node);
20496   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20497   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20498   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20499   if (0 != sw_if_to_name)
20500     {
20501       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20502     }
20503   vat_json_object_add_uint (node, "state", mp->state);
20504 }
20505
20506 static int
20507 api_sw_interface_span_dump (vat_main_t * vam)
20508 {
20509   unformat_input_t *input = vam->input;
20510   vl_api_sw_interface_span_dump_t *mp;
20511   vl_api_control_ping_t *mp_ping;
20512   u8 is_l2 = 0;
20513   int ret;
20514
20515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20516     {
20517       if (unformat (input, "l2"))
20518         is_l2 = 1;
20519       else
20520         break;
20521     }
20522
20523   M (SW_INTERFACE_SPAN_DUMP, mp);
20524   mp->is_l2 = is_l2;
20525   S (mp);
20526
20527   /* Use a control ping for synchronization */
20528   MPING (CONTROL_PING, mp_ping);
20529   S (mp_ping);
20530
20531   W (ret);
20532   return ret;
20533 }
20534
20535 int
20536 api_pg_create_interface (vat_main_t * vam)
20537 {
20538   unformat_input_t *input = vam->input;
20539   vl_api_pg_create_interface_t *mp;
20540
20541   u32 if_id = ~0;
20542   int ret;
20543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (input, "if_id %d", &if_id))
20546         ;
20547       else
20548         break;
20549     }
20550   if (if_id == ~0)
20551     {
20552       errmsg ("missing pg interface index");
20553       return -99;
20554     }
20555
20556   /* Construct the API message */
20557   M (PG_CREATE_INTERFACE, mp);
20558   mp->context = 0;
20559   mp->interface_id = ntohl (if_id);
20560
20561   S (mp);
20562   W (ret);
20563   return ret;
20564 }
20565
20566 int
20567 api_pg_capture (vat_main_t * vam)
20568 {
20569   unformat_input_t *input = vam->input;
20570   vl_api_pg_capture_t *mp;
20571
20572   u32 if_id = ~0;
20573   u8 enable = 1;
20574   u32 count = 1;
20575   u8 pcap_file_set = 0;
20576   u8 *pcap_file = 0;
20577   int ret;
20578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20579     {
20580       if (unformat (input, "if_id %d", &if_id))
20581         ;
20582       else if (unformat (input, "pcap %s", &pcap_file))
20583         pcap_file_set = 1;
20584       else if (unformat (input, "count %d", &count))
20585         ;
20586       else if (unformat (input, "disable"))
20587         enable = 0;
20588       else
20589         break;
20590     }
20591   if (if_id == ~0)
20592     {
20593       errmsg ("missing pg interface index");
20594       return -99;
20595     }
20596   if (pcap_file_set > 0)
20597     {
20598       if (vec_len (pcap_file) > 255)
20599         {
20600           errmsg ("pcap file name is too long");
20601           return -99;
20602         }
20603     }
20604
20605   u32 name_len = vec_len (pcap_file);
20606   /* Construct the API message */
20607   M (PG_CAPTURE, mp);
20608   mp->context = 0;
20609   mp->interface_id = ntohl (if_id);
20610   mp->is_enabled = enable;
20611   mp->count = ntohl (count);
20612   mp->pcap_name_length = ntohl (name_len);
20613   if (pcap_file_set != 0)
20614     {
20615       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20616     }
20617   vec_free (pcap_file);
20618
20619   S (mp);
20620   W (ret);
20621   return ret;
20622 }
20623
20624 int
20625 api_pg_enable_disable (vat_main_t * vam)
20626 {
20627   unformat_input_t *input = vam->input;
20628   vl_api_pg_enable_disable_t *mp;
20629
20630   u8 enable = 1;
20631   u8 stream_name_set = 0;
20632   u8 *stream_name = 0;
20633   int ret;
20634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20635     {
20636       if (unformat (input, "stream %s", &stream_name))
20637         stream_name_set = 1;
20638       else if (unformat (input, "disable"))
20639         enable = 0;
20640       else
20641         break;
20642     }
20643
20644   if (stream_name_set > 0)
20645     {
20646       if (vec_len (stream_name) > 255)
20647         {
20648           errmsg ("stream name too long");
20649           return -99;
20650         }
20651     }
20652
20653   u32 name_len = vec_len (stream_name);
20654   /* Construct the API message */
20655   M (PG_ENABLE_DISABLE, mp);
20656   mp->context = 0;
20657   mp->is_enabled = enable;
20658   if (stream_name_set != 0)
20659     {
20660       mp->stream_name_length = ntohl (name_len);
20661       clib_memcpy (mp->stream_name, stream_name, name_len);
20662     }
20663   vec_free (stream_name);
20664
20665   S (mp);
20666   W (ret);
20667   return ret;
20668 }
20669
20670 int
20671 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20672 {
20673   unformat_input_t *input = vam->input;
20674   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20675
20676   u16 *low_ports = 0;
20677   u16 *high_ports = 0;
20678   u16 this_low;
20679   u16 this_hi;
20680   ip4_address_t ip4_addr;
20681   ip6_address_t ip6_addr;
20682   u32 length;
20683   u32 tmp, tmp2;
20684   u8 prefix_set = 0;
20685   u32 vrf_id = ~0;
20686   u8 is_add = 1;
20687   u8 is_ipv6 = 0;
20688   int ret;
20689
20690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20691     {
20692       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20693         {
20694           prefix_set = 1;
20695         }
20696       else
20697         if (unformat
20698             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20699         {
20700           prefix_set = 1;
20701           is_ipv6 = 1;
20702         }
20703       else if (unformat (input, "vrf %d", &vrf_id))
20704         ;
20705       else if (unformat (input, "del"))
20706         is_add = 0;
20707       else if (unformat (input, "port %d", &tmp))
20708         {
20709           if (tmp == 0 || tmp > 65535)
20710             {
20711               errmsg ("port %d out of range", tmp);
20712               return -99;
20713             }
20714           this_low = tmp;
20715           this_hi = this_low + 1;
20716           vec_add1 (low_ports, this_low);
20717           vec_add1 (high_ports, this_hi);
20718         }
20719       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20720         {
20721           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20722             {
20723               errmsg ("incorrect range parameters");
20724               return -99;
20725             }
20726           this_low = tmp;
20727           /* Note: in debug CLI +1 is added to high before
20728              passing to real fn that does "the work"
20729              (ip_source_and_port_range_check_add_del).
20730              This fn is a wrapper around the binary API fn a
20731              control plane will call, which expects this increment
20732              to have occurred. Hence letting the binary API control
20733              plane fn do the increment for consistency between VAT
20734              and other control planes.
20735            */
20736           this_hi = tmp2;
20737           vec_add1 (low_ports, this_low);
20738           vec_add1 (high_ports, this_hi);
20739         }
20740       else
20741         break;
20742     }
20743
20744   if (prefix_set == 0)
20745     {
20746       errmsg ("<address>/<mask> not specified");
20747       return -99;
20748     }
20749
20750   if (vrf_id == ~0)
20751     {
20752       errmsg ("VRF ID required, not specified");
20753       return -99;
20754     }
20755
20756   if (vrf_id == 0)
20757     {
20758       errmsg
20759         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20760       return -99;
20761     }
20762
20763   if (vec_len (low_ports) == 0)
20764     {
20765       errmsg ("At least one port or port range required");
20766       return -99;
20767     }
20768
20769   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20770
20771   mp->is_add = is_add;
20772
20773   if (is_ipv6)
20774     {
20775       mp->is_ipv6 = 1;
20776       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20777     }
20778   else
20779     {
20780       mp->is_ipv6 = 0;
20781       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20782     }
20783
20784   mp->mask_length = length;
20785   mp->number_of_ranges = vec_len (low_ports);
20786
20787   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20788   vec_free (low_ports);
20789
20790   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20791   vec_free (high_ports);
20792
20793   mp->vrf_id = ntohl (vrf_id);
20794
20795   S (mp);
20796   W (ret);
20797   return ret;
20798 }
20799
20800 int
20801 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20802 {
20803   unformat_input_t *input = vam->input;
20804   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20805   u32 sw_if_index = ~0;
20806   int vrf_set = 0;
20807   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20808   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20809   u8 is_add = 1;
20810   int ret;
20811
20812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20813     {
20814       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20815         ;
20816       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20817         ;
20818       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20819         vrf_set = 1;
20820       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20821         vrf_set = 1;
20822       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20823         vrf_set = 1;
20824       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20825         vrf_set = 1;
20826       else if (unformat (input, "del"))
20827         is_add = 0;
20828       else
20829         break;
20830     }
20831
20832   if (sw_if_index == ~0)
20833     {
20834       errmsg ("Interface required but not specified");
20835       return -99;
20836     }
20837
20838   if (vrf_set == 0)
20839     {
20840       errmsg ("VRF ID required but not specified");
20841       return -99;
20842     }
20843
20844   if (tcp_out_vrf_id == 0
20845       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20846     {
20847       errmsg
20848         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20849       return -99;
20850     }
20851
20852   /* Construct the API message */
20853   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20854
20855   mp->sw_if_index = ntohl (sw_if_index);
20856   mp->is_add = is_add;
20857   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20858   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20859   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20860   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20861
20862   /* send it... */
20863   S (mp);
20864
20865   /* Wait for a reply... */
20866   W (ret);
20867   return ret;
20868 }
20869
20870 static int
20871 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20872 {
20873   unformat_input_t *i = vam->input;
20874   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20875   u32 local_sa_id = 0;
20876   u32 remote_sa_id = 0;
20877   ip4_address_t src_address;
20878   ip4_address_t dst_address;
20879   u8 is_add = 1;
20880   int ret;
20881
20882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20883     {
20884       if (unformat (i, "local_sa %d", &local_sa_id))
20885         ;
20886       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20887         ;
20888       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20889         ;
20890       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20891         ;
20892       else if (unformat (i, "del"))
20893         is_add = 0;
20894       else
20895         {
20896           clib_warning ("parse error '%U'", format_unformat_error, i);
20897           return -99;
20898         }
20899     }
20900
20901   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20902
20903   mp->local_sa_id = ntohl (local_sa_id);
20904   mp->remote_sa_id = ntohl (remote_sa_id);
20905   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20906   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20907   mp->is_add = is_add;
20908
20909   S (mp);
20910   W (ret);
20911   return ret;
20912 }
20913
20914 static int
20915 api_punt (vat_main_t * vam)
20916 {
20917   unformat_input_t *i = vam->input;
20918   vl_api_punt_t *mp;
20919   u32 ipv = ~0;
20920   u32 protocol = ~0;
20921   u32 port = ~0;
20922   int is_add = 1;
20923   int ret;
20924
20925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20926     {
20927       if (unformat (i, "ip %d", &ipv))
20928         ;
20929       else if (unformat (i, "protocol %d", &protocol))
20930         ;
20931       else if (unformat (i, "port %d", &port))
20932         ;
20933       else if (unformat (i, "del"))
20934         is_add = 0;
20935       else
20936         {
20937           clib_warning ("parse error '%U'", format_unformat_error, i);
20938           return -99;
20939         }
20940     }
20941
20942   M (PUNT, mp);
20943
20944   mp->is_add = (u8) is_add;
20945   mp->ipv = (u8) ipv;
20946   mp->l4_protocol = (u8) protocol;
20947   mp->l4_port = htons ((u16) port);
20948
20949   S (mp);
20950   W (ret);
20951   return ret;
20952 }
20953
20954 static void vl_api_ipsec_gre_tunnel_details_t_handler
20955   (vl_api_ipsec_gre_tunnel_details_t * mp)
20956 {
20957   vat_main_t *vam = &vat_main;
20958
20959   print (vam->ofp, "%11d%15U%15U%14d%14d",
20960          ntohl (mp->sw_if_index),
20961          format_ip4_address, &mp->src_address,
20962          format_ip4_address, &mp->dst_address,
20963          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20964 }
20965
20966 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20967   (vl_api_ipsec_gre_tunnel_details_t * mp)
20968 {
20969   vat_main_t *vam = &vat_main;
20970   vat_json_node_t *node = NULL;
20971   struct in_addr ip4;
20972
20973   if (VAT_JSON_ARRAY != vam->json_tree.type)
20974     {
20975       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20976       vat_json_init_array (&vam->json_tree);
20977     }
20978   node = vat_json_array_add (&vam->json_tree);
20979
20980   vat_json_init_object (node);
20981   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20982   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20983   vat_json_object_add_ip4 (node, "src_address", ip4);
20984   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20985   vat_json_object_add_ip4 (node, "dst_address", ip4);
20986   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20987   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20988 }
20989
20990 static int
20991 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20992 {
20993   unformat_input_t *i = vam->input;
20994   vl_api_ipsec_gre_tunnel_dump_t *mp;
20995   vl_api_control_ping_t *mp_ping;
20996   u32 sw_if_index;
20997   u8 sw_if_index_set = 0;
20998   int ret;
20999
21000   /* Parse args required to build the message */
21001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21002     {
21003       if (unformat (i, "sw_if_index %d", &sw_if_index))
21004         sw_if_index_set = 1;
21005       else
21006         break;
21007     }
21008
21009   if (sw_if_index_set == 0)
21010     {
21011       sw_if_index = ~0;
21012     }
21013
21014   if (!vam->json_output)
21015     {
21016       print (vam->ofp, "%11s%15s%15s%14s%14s",
21017              "sw_if_index", "src_address", "dst_address",
21018              "local_sa_id", "remote_sa_id");
21019     }
21020
21021   /* Get list of gre-tunnel interfaces */
21022   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21023
21024   mp->sw_if_index = htonl (sw_if_index);
21025
21026   S (mp);
21027
21028   /* Use a control ping for synchronization */
21029   MPING (CONTROL_PING, mp_ping);
21030   S (mp_ping);
21031
21032   W (ret);
21033   return ret;
21034 }
21035
21036 static int
21037 api_delete_subif (vat_main_t * vam)
21038 {
21039   unformat_input_t *i = vam->input;
21040   vl_api_delete_subif_t *mp;
21041   u32 sw_if_index = ~0;
21042   int ret;
21043
21044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21045     {
21046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21047         ;
21048       if (unformat (i, "sw_if_index %d", &sw_if_index))
21049         ;
21050       else
21051         break;
21052     }
21053
21054   if (sw_if_index == ~0)
21055     {
21056       errmsg ("missing sw_if_index");
21057       return -99;
21058     }
21059
21060   /* Construct the API message */
21061   M (DELETE_SUBIF, mp);
21062   mp->sw_if_index = ntohl (sw_if_index);
21063
21064   S (mp);
21065   W (ret);
21066   return ret;
21067 }
21068
21069 #define foreach_pbb_vtr_op      \
21070 _("disable",  L2_VTR_DISABLED)  \
21071 _("pop",  L2_VTR_POP_2)         \
21072 _("push",  L2_VTR_PUSH_2)
21073
21074 static int
21075 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21076 {
21077   unformat_input_t *i = vam->input;
21078   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21079   u32 sw_if_index = ~0, vtr_op = ~0;
21080   u16 outer_tag = ~0;
21081   u8 dmac[6], smac[6];
21082   u8 dmac_set = 0, smac_set = 0;
21083   u16 vlanid = 0;
21084   u32 sid = ~0;
21085   u32 tmp;
21086   int ret;
21087
21088   /* Shut up coverity */
21089   memset (dmac, 0, sizeof (dmac));
21090   memset (smac, 0, sizeof (smac));
21091
21092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21093     {
21094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21095         ;
21096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21097         ;
21098       else if (unformat (i, "vtr_op %d", &vtr_op))
21099         ;
21100 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21101       foreach_pbb_vtr_op
21102 #undef _
21103         else if (unformat (i, "translate_pbb_stag"))
21104         {
21105           if (unformat (i, "%d", &tmp))
21106             {
21107               vtr_op = L2_VTR_TRANSLATE_2_1;
21108               outer_tag = tmp;
21109             }
21110           else
21111             {
21112               errmsg
21113                 ("translate_pbb_stag operation requires outer tag definition");
21114               return -99;
21115             }
21116         }
21117       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21118         dmac_set++;
21119       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21120         smac_set++;
21121       else if (unformat (i, "sid %d", &sid))
21122         ;
21123       else if (unformat (i, "vlanid %d", &tmp))
21124         vlanid = tmp;
21125       else
21126         {
21127           clib_warning ("parse error '%U'", format_unformat_error, i);
21128           return -99;
21129         }
21130     }
21131
21132   if ((sw_if_index == ~0) || (vtr_op == ~0))
21133     {
21134       errmsg ("missing sw_if_index or vtr operation");
21135       return -99;
21136     }
21137   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21138       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21139     {
21140       errmsg
21141         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21142       return -99;
21143     }
21144
21145   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21146   mp->sw_if_index = ntohl (sw_if_index);
21147   mp->vtr_op = ntohl (vtr_op);
21148   mp->outer_tag = ntohs (outer_tag);
21149   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21150   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21151   mp->b_vlanid = ntohs (vlanid);
21152   mp->i_sid = ntohl (sid);
21153
21154   S (mp);
21155   W (ret);
21156   return ret;
21157 }
21158
21159 static int
21160 api_flow_classify_set_interface (vat_main_t * vam)
21161 {
21162   unformat_input_t *i = vam->input;
21163   vl_api_flow_classify_set_interface_t *mp;
21164   u32 sw_if_index;
21165   int sw_if_index_set;
21166   u32 ip4_table_index = ~0;
21167   u32 ip6_table_index = ~0;
21168   u8 is_add = 1;
21169   int ret;
21170
21171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21172     {
21173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21174         sw_if_index_set = 1;
21175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21176         sw_if_index_set = 1;
21177       else if (unformat (i, "del"))
21178         is_add = 0;
21179       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21180         ;
21181       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21182         ;
21183       else
21184         {
21185           clib_warning ("parse error '%U'", format_unformat_error, i);
21186           return -99;
21187         }
21188     }
21189
21190   if (sw_if_index_set == 0)
21191     {
21192       errmsg ("missing interface name or sw_if_index");
21193       return -99;
21194     }
21195
21196   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21197
21198   mp->sw_if_index = ntohl (sw_if_index);
21199   mp->ip4_table_index = ntohl (ip4_table_index);
21200   mp->ip6_table_index = ntohl (ip6_table_index);
21201   mp->is_add = is_add;
21202
21203   S (mp);
21204   W (ret);
21205   return ret;
21206 }
21207
21208 static int
21209 api_flow_classify_dump (vat_main_t * vam)
21210 {
21211   unformat_input_t *i = vam->input;
21212   vl_api_flow_classify_dump_t *mp;
21213   vl_api_control_ping_t *mp_ping;
21214   u8 type = FLOW_CLASSIFY_N_TABLES;
21215   int ret;
21216
21217   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21218     ;
21219   else
21220     {
21221       errmsg ("classify table type must be specified");
21222       return -99;
21223     }
21224
21225   if (!vam->json_output)
21226     {
21227       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21228     }
21229
21230   M (FLOW_CLASSIFY_DUMP, mp);
21231   mp->type = type;
21232   /* send it... */
21233   S (mp);
21234
21235   /* Use a control ping for synchronization */
21236   MPING (CONTROL_PING, mp_ping);
21237   S (mp_ping);
21238
21239   /* Wait for a reply... */
21240   W (ret);
21241   return ret;
21242 }
21243
21244 static int
21245 api_feature_enable_disable (vat_main_t * vam)
21246 {
21247   unformat_input_t *i = vam->input;
21248   vl_api_feature_enable_disable_t *mp;
21249   u8 *arc_name = 0;
21250   u8 *feature_name = 0;
21251   u32 sw_if_index = ~0;
21252   u8 enable = 1;
21253   int ret;
21254
21255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21256     {
21257       if (unformat (i, "arc_name %s", &arc_name))
21258         ;
21259       else if (unformat (i, "feature_name %s", &feature_name))
21260         ;
21261       else
21262         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21263         ;
21264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21265         ;
21266       else if (unformat (i, "disable"))
21267         enable = 0;
21268       else
21269         break;
21270     }
21271
21272   if (arc_name == 0)
21273     {
21274       errmsg ("missing arc name");
21275       return -99;
21276     }
21277   if (vec_len (arc_name) > 63)
21278     {
21279       errmsg ("arc name too long");
21280     }
21281
21282   if (feature_name == 0)
21283     {
21284       errmsg ("missing feature name");
21285       return -99;
21286     }
21287   if (vec_len (feature_name) > 63)
21288     {
21289       errmsg ("feature name too long");
21290     }
21291
21292   if (sw_if_index == ~0)
21293     {
21294       errmsg ("missing interface name or sw_if_index");
21295       return -99;
21296     }
21297
21298   /* Construct the API message */
21299   M (FEATURE_ENABLE_DISABLE, mp);
21300   mp->sw_if_index = ntohl (sw_if_index);
21301   mp->enable = enable;
21302   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21303   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21304   vec_free (arc_name);
21305   vec_free (feature_name);
21306
21307   S (mp);
21308   W (ret);
21309   return ret;
21310 }
21311
21312 static int
21313 api_sw_interface_tag_add_del (vat_main_t * vam)
21314 {
21315   unformat_input_t *i = vam->input;
21316   vl_api_sw_interface_tag_add_del_t *mp;
21317   u32 sw_if_index = ~0;
21318   u8 *tag = 0;
21319   u8 enable = 1;
21320   int ret;
21321
21322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21323     {
21324       if (unformat (i, "tag %s", &tag))
21325         ;
21326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21327         ;
21328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21329         ;
21330       else if (unformat (i, "del"))
21331         enable = 0;
21332       else
21333         break;
21334     }
21335
21336   if (sw_if_index == ~0)
21337     {
21338       errmsg ("missing interface name or sw_if_index");
21339       return -99;
21340     }
21341
21342   if (enable && (tag == 0))
21343     {
21344       errmsg ("no tag specified");
21345       return -99;
21346     }
21347
21348   /* Construct the API message */
21349   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21350   mp->sw_if_index = ntohl (sw_if_index);
21351   mp->is_add = enable;
21352   if (enable)
21353     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21354   vec_free (tag);
21355
21356   S (mp);
21357   W (ret);
21358   return ret;
21359 }
21360
21361 static void vl_api_l2_xconnect_details_t_handler
21362   (vl_api_l2_xconnect_details_t * mp)
21363 {
21364   vat_main_t *vam = &vat_main;
21365
21366   print (vam->ofp, "%15d%15d",
21367          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21368 }
21369
21370 static void vl_api_l2_xconnect_details_t_handler_json
21371   (vl_api_l2_xconnect_details_t * mp)
21372 {
21373   vat_main_t *vam = &vat_main;
21374   vat_json_node_t *node = NULL;
21375
21376   if (VAT_JSON_ARRAY != vam->json_tree.type)
21377     {
21378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21379       vat_json_init_array (&vam->json_tree);
21380     }
21381   node = vat_json_array_add (&vam->json_tree);
21382
21383   vat_json_init_object (node);
21384   vat_json_object_add_uint (node, "rx_sw_if_index",
21385                             ntohl (mp->rx_sw_if_index));
21386   vat_json_object_add_uint (node, "tx_sw_if_index",
21387                             ntohl (mp->tx_sw_if_index));
21388 }
21389
21390 static int
21391 api_l2_xconnect_dump (vat_main_t * vam)
21392 {
21393   vl_api_l2_xconnect_dump_t *mp;
21394   vl_api_control_ping_t *mp_ping;
21395   int ret;
21396
21397   if (!vam->json_output)
21398     {
21399       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21400     }
21401
21402   M (L2_XCONNECT_DUMP, mp);
21403
21404   S (mp);
21405
21406   /* Use a control ping for synchronization */
21407   MPING (CONTROL_PING, mp_ping);
21408   S (mp_ping);
21409
21410   W (ret);
21411   return ret;
21412 }
21413
21414 static int
21415 api_sw_interface_set_mtu (vat_main_t * vam)
21416 {
21417   unformat_input_t *i = vam->input;
21418   vl_api_sw_interface_set_mtu_t *mp;
21419   u32 sw_if_index = ~0;
21420   u32 mtu = 0;
21421   int ret;
21422
21423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21424     {
21425       if (unformat (i, "mtu %d", &mtu))
21426         ;
21427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21428         ;
21429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21430         ;
21431       else
21432         break;
21433     }
21434
21435   if (sw_if_index == ~0)
21436     {
21437       errmsg ("missing interface name or sw_if_index");
21438       return -99;
21439     }
21440
21441   if (mtu == 0)
21442     {
21443       errmsg ("no mtu specified");
21444       return -99;
21445     }
21446
21447   /* Construct the API message */
21448   M (SW_INTERFACE_SET_MTU, mp);
21449   mp->sw_if_index = ntohl (sw_if_index);
21450   mp->mtu = ntohs ((u16) mtu);
21451
21452   S (mp);
21453   W (ret);
21454   return ret;
21455 }
21456
21457 static int
21458 api_p2p_ethernet_add (vat_main_t * vam)
21459 {
21460   unformat_input_t *i = vam->input;
21461   vl_api_p2p_ethernet_add_t *mp;
21462   u32 parent_if_index = ~0;
21463   u32 sub_id = ~0;
21464   u8 remote_mac[6];
21465   u8 mac_set = 0;
21466   int ret;
21467
21468   memset (remote_mac, 0, sizeof (remote_mac));
21469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21470     {
21471       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21472         ;
21473       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21474         ;
21475       else
21476         if (unformat
21477             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21478         mac_set++;
21479       else if (unformat (i, "sub_id %d", &sub_id))
21480         ;
21481       else
21482         {
21483           clib_warning ("parse error '%U'", format_unformat_error, i);
21484           return -99;
21485         }
21486     }
21487
21488   if (parent_if_index == ~0)
21489     {
21490       errmsg ("missing interface name or sw_if_index");
21491       return -99;
21492     }
21493   if (mac_set == 0)
21494     {
21495       errmsg ("missing remote mac address");
21496       return -99;
21497     }
21498   if (sub_id == ~0)
21499     {
21500       errmsg ("missing sub-interface id");
21501       return -99;
21502     }
21503
21504   M (P2P_ETHERNET_ADD, mp);
21505   mp->parent_if_index = ntohl (parent_if_index);
21506   mp->subif_id = ntohl (sub_id);
21507   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21508
21509   S (mp);
21510   W (ret);
21511   return ret;
21512 }
21513
21514 static int
21515 api_p2p_ethernet_del (vat_main_t * vam)
21516 {
21517   unformat_input_t *i = vam->input;
21518   vl_api_p2p_ethernet_del_t *mp;
21519   u32 parent_if_index = ~0;
21520   u8 remote_mac[6];
21521   u8 mac_set = 0;
21522   int ret;
21523
21524   memset (remote_mac, 0, sizeof (remote_mac));
21525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21526     {
21527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21528         ;
21529       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21530         ;
21531       else
21532         if (unformat
21533             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21534         mac_set++;
21535       else
21536         {
21537           clib_warning ("parse error '%U'", format_unformat_error, i);
21538           return -99;
21539         }
21540     }
21541
21542   if (parent_if_index == ~0)
21543     {
21544       errmsg ("missing interface name or sw_if_index");
21545       return -99;
21546     }
21547   if (mac_set == 0)
21548     {
21549       errmsg ("missing remote mac address");
21550       return -99;
21551     }
21552
21553   M (P2P_ETHERNET_DEL, mp);
21554   mp->parent_if_index = ntohl (parent_if_index);
21555   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21556
21557   S (mp);
21558   W (ret);
21559   return ret;
21560 }
21561
21562 static int
21563 api_lldp_config (vat_main_t * vam)
21564 {
21565   unformat_input_t *i = vam->input;
21566   vl_api_lldp_config_t *mp;
21567   int tx_hold = 0;
21568   int tx_interval = 0;
21569   u8 *sys_name = NULL;
21570   int ret;
21571
21572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21573     {
21574       if (unformat (i, "system-name %s", &sys_name))
21575         ;
21576       else if (unformat (i, "tx-hold %d", &tx_hold))
21577         ;
21578       else if (unformat (i, "tx-interval %d", &tx_interval))
21579         ;
21580       else
21581         {
21582           clib_warning ("parse error '%U'", format_unformat_error, i);
21583           return -99;
21584         }
21585     }
21586
21587   vec_add1 (sys_name, 0);
21588
21589   M (LLDP_CONFIG, mp);
21590   mp->tx_hold = htonl (tx_hold);
21591   mp->tx_interval = htonl (tx_interval);
21592   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21593   vec_free (sys_name);
21594
21595   S (mp);
21596   W (ret);
21597   return ret;
21598 }
21599
21600 static int
21601 api_sw_interface_set_lldp (vat_main_t * vam)
21602 {
21603   unformat_input_t *i = vam->input;
21604   vl_api_sw_interface_set_lldp_t *mp;
21605   u32 sw_if_index = ~0;
21606   u32 enable = 1;
21607   u8 *port_desc = NULL, *mgmt_oid = NULL;
21608   ip4_address_t ip4_addr;
21609   ip6_address_t ip6_addr;
21610   int ret;
21611
21612   memset (&ip4_addr, 0, sizeof (ip4_addr));
21613   memset (&ip6_addr, 0, sizeof (ip6_addr));
21614
21615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21616     {
21617       if (unformat (i, "disable"))
21618         enable = 0;
21619       else
21620         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21621         ;
21622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21623         ;
21624       else if (unformat (i, "port-desc %s", &port_desc))
21625         ;
21626       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21627         ;
21628       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21629         ;
21630       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21631         ;
21632       else
21633         break;
21634     }
21635
21636   if (sw_if_index == ~0)
21637     {
21638       errmsg ("missing interface name or sw_if_index");
21639       return -99;
21640     }
21641
21642   /* Construct the API message */
21643   vec_add1 (port_desc, 0);
21644   vec_add1 (mgmt_oid, 0);
21645   M (SW_INTERFACE_SET_LLDP, mp);
21646   mp->sw_if_index = ntohl (sw_if_index);
21647   mp->enable = enable;
21648   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21649   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21650   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21651   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21652   vec_free (port_desc);
21653   vec_free (mgmt_oid);
21654
21655   S (mp);
21656   W (ret);
21657   return ret;
21658 }
21659
21660 static int
21661 api_tcp_configure_src_addresses (vat_main_t * vam)
21662 {
21663   vl_api_tcp_configure_src_addresses_t *mp;
21664   unformat_input_t *i = vam->input;
21665   ip4_address_t v4first, v4last;
21666   ip6_address_t v6first, v6last;
21667   u8 range_set = 0;
21668   u32 vrf_id = 0;
21669   int ret;
21670
21671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21672     {
21673       if (unformat (i, "%U - %U",
21674                     unformat_ip4_address, &v4first,
21675                     unformat_ip4_address, &v4last))
21676         {
21677           if (range_set)
21678             {
21679               errmsg ("one range per message (range already set)");
21680               return -99;
21681             }
21682           range_set = 1;
21683         }
21684       else if (unformat (i, "%U - %U",
21685                          unformat_ip6_address, &v6first,
21686                          unformat_ip6_address, &v6last))
21687         {
21688           if (range_set)
21689             {
21690               errmsg ("one range per message (range already set)");
21691               return -99;
21692             }
21693           range_set = 2;
21694         }
21695       else if (unformat (i, "vrf %d", &vrf_id))
21696         ;
21697       else
21698         break;
21699     }
21700
21701   if (range_set == 0)
21702     {
21703       errmsg ("address range not set");
21704       return -99;
21705     }
21706
21707   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21708   mp->vrf_id = ntohl (vrf_id);
21709   /* ipv6? */
21710   if (range_set == 2)
21711     {
21712       mp->is_ipv6 = 1;
21713       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21714       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21715     }
21716   else
21717     {
21718       mp->is_ipv6 = 0;
21719       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21720       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21721     }
21722   S (mp);
21723   W (ret);
21724   return ret;
21725 }
21726
21727 static void vl_api_app_namespace_add_del_reply_t_handler
21728   (vl_api_app_namespace_add_del_reply_t * mp)
21729 {
21730   vat_main_t *vam = &vat_main;
21731   i32 retval = ntohl (mp->retval);
21732   if (vam->async_mode)
21733     {
21734       vam->async_errors += (retval < 0);
21735     }
21736   else
21737     {
21738       vam->retval = retval;
21739       if (retval == 0)
21740         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21741       vam->result_ready = 1;
21742     }
21743 }
21744
21745 static void vl_api_app_namespace_add_del_reply_t_handler_json
21746   (vl_api_app_namespace_add_del_reply_t * mp)
21747 {
21748   vat_main_t *vam = &vat_main;
21749   vat_json_node_t node;
21750
21751   vat_json_init_object (&node);
21752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21753   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21754
21755   vat_json_print (vam->ofp, &node);
21756   vat_json_free (&node);
21757
21758   vam->retval = ntohl (mp->retval);
21759   vam->result_ready = 1;
21760 }
21761
21762 static int
21763 api_app_namespace_add_del (vat_main_t * vam)
21764 {
21765   vl_api_app_namespace_add_del_t *mp;
21766   unformat_input_t *i = vam->input;
21767   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21768   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21769   u64 secret;
21770   int ret;
21771
21772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21773     {
21774       if (unformat (i, "id %_%v%_", &ns_id))
21775         ;
21776       else if (unformat (i, "secret %lu", &secret))
21777         secret_set = 1;
21778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21779         sw_if_index_set = 1;
21780       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21781         ;
21782       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21783         ;
21784       else
21785         break;
21786     }
21787   if (!ns_id || !secret_set || !sw_if_index_set)
21788     {
21789       errmsg ("namespace id, secret and sw_if_index must be set");
21790       return -99;
21791     }
21792   if (vec_len (ns_id) > 64)
21793     {
21794       errmsg ("namespace id too long");
21795       return -99;
21796     }
21797   M (APP_NAMESPACE_ADD_DEL, mp);
21798
21799   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21800   mp->namespace_id_len = vec_len (ns_id);
21801   mp->secret = clib_host_to_net_u64 (secret);
21802   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21803   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21804   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21805   vec_free (ns_id);
21806   S (mp);
21807   W (ret);
21808   return ret;
21809 }
21810
21811 static int
21812 api_memfd_segment_create (vat_main_t * vam)
21813 {
21814 #if VPP_API_TEST_BUILTIN == 0
21815   unformat_input_t *i = vam->input;
21816   vl_api_memfd_segment_create_t *mp;
21817   u64 size = 64 << 20;
21818   int ret;
21819
21820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21821     {
21822       if (unformat (i, "size %U", unformat_memory_size, &size))
21823         ;
21824       else
21825         break;
21826     }
21827
21828   M (MEMFD_SEGMENT_CREATE, mp);
21829   mp->requested_size = size;
21830   S (mp);
21831   W (ret);
21832   return ret;
21833
21834 #else
21835   errmsg ("memfd_segment_create (builtin) not supported");
21836   return -99;
21837 #endif
21838 }
21839
21840 static int
21841 api_dns_enable_disable (vat_main_t * vam)
21842 {
21843   unformat_input_t *line_input = vam->input;
21844   vl_api_dns_enable_disable_t *mp;
21845   u8 enable_disable = 1;
21846   int ret;
21847
21848   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21849     {
21850       if (unformat (line_input, "disable"))
21851         enable_disable = 0;
21852       if (unformat (line_input, "enable"))
21853         enable_disable = 1;
21854       else
21855         break;
21856     }
21857
21858   /* Construct the API message */
21859   M (DNS_ENABLE_DISABLE, mp);
21860   mp->enable = enable_disable;
21861
21862   /* send it... */
21863   S (mp);
21864   /* Wait for the reply */
21865   W (ret);
21866   return ret;
21867 }
21868
21869 static int
21870 api_dns_resolve_name (vat_main_t * vam)
21871 {
21872   unformat_input_t *line_input = vam->input;
21873   vl_api_dns_resolve_name_t *mp;
21874   u8 *name = 0;
21875   int ret;
21876
21877   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21878     {
21879       if (unformat (line_input, "%s", &name))
21880         ;
21881       else
21882         break;
21883     }
21884
21885   if (vec_len (name) > 127)
21886     {
21887       errmsg ("name too long");
21888       return -99;
21889     }
21890
21891   /* Construct the API message */
21892   M (DNS_RESOLVE_NAME, mp);
21893   memcpy (mp->name, name, vec_len (name));
21894   vec_free (name);
21895
21896   /* send it... */
21897   S (mp);
21898   /* Wait for the reply */
21899   W (ret);
21900   return ret;
21901 }
21902
21903 static int
21904 api_dns_resolve_ip (vat_main_t * vam)
21905 {
21906   unformat_input_t *line_input = vam->input;
21907   vl_api_dns_resolve_ip_t *mp;
21908   int is_ip6 = -1;
21909   ip4_address_t addr4;
21910   ip6_address_t addr6;
21911   int ret;
21912
21913   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21914     {
21915       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21916         is_ip6 = 1;
21917       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21918         is_ip6 = 0;
21919       else
21920         break;
21921     }
21922
21923   if (is_ip6 == -1)
21924     {
21925       errmsg ("missing address");
21926       return -99;
21927     }
21928
21929   /* Construct the API message */
21930   M (DNS_RESOLVE_IP, mp);
21931   mp->is_ip6 = is_ip6;
21932   if (is_ip6)
21933     memcpy (mp->address, &addr6, sizeof (addr6));
21934   else
21935     memcpy (mp->address, &addr4, sizeof (addr4));
21936
21937   /* send it... */
21938   S (mp);
21939   /* Wait for the reply */
21940   W (ret);
21941   return ret;
21942 }
21943
21944 static int
21945 api_dns_name_server_add_del (vat_main_t * vam)
21946 {
21947   unformat_input_t *i = vam->input;
21948   vl_api_dns_name_server_add_del_t *mp;
21949   u8 is_add = 1;
21950   ip6_address_t ip6_server;
21951   ip4_address_t ip4_server;
21952   int ip6_set = 0;
21953   int ip4_set = 0;
21954   int ret = 0;
21955
21956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21957     {
21958       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21959         ip6_set = 1;
21960       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21961         ip4_set = 1;
21962       else if (unformat (i, "del"))
21963         is_add = 0;
21964       else
21965         {
21966           clib_warning ("parse error '%U'", format_unformat_error, i);
21967           return -99;
21968         }
21969     }
21970
21971   if (ip4_set && ip6_set)
21972     {
21973       errmsg ("Only one server address allowed per message");
21974       return -99;
21975     }
21976   if ((ip4_set + ip6_set) == 0)
21977     {
21978       errmsg ("Server address required");
21979       return -99;
21980     }
21981
21982   /* Construct the API message */
21983   M (DNS_NAME_SERVER_ADD_DEL, mp);
21984
21985   if (ip6_set)
21986     {
21987       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21988       mp->is_ip6 = 1;
21989     }
21990   else
21991     {
21992       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21993       mp->is_ip6 = 0;
21994     }
21995
21996   mp->is_add = is_add;
21997
21998   /* send it... */
21999   S (mp);
22000
22001   /* Wait for a reply, return good/bad news  */
22002   W (ret);
22003   return ret;
22004 }
22005
22006 static void
22007 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22008 {
22009   vat_main_t *vam = &vat_main;
22010
22011   if (mp->is_ip4)
22012     {
22013       print (vam->ofp,
22014              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22015              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22016              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22017              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22018              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22019              clib_net_to_host_u32 (mp->action_index), mp->tag);
22020     }
22021   else
22022     {
22023       print (vam->ofp,
22024              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22025              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22026              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22027              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22028              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22029              clib_net_to_host_u32 (mp->action_index), mp->tag);
22030     }
22031 }
22032
22033 static void
22034 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22035                                              mp)
22036 {
22037   vat_main_t *vam = &vat_main;
22038   vat_json_node_t *node = NULL;
22039   struct in6_addr ip6;
22040   struct in_addr ip4;
22041
22042   if (VAT_JSON_ARRAY != vam->json_tree.type)
22043     {
22044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22045       vat_json_init_array (&vam->json_tree);
22046     }
22047   node = vat_json_array_add (&vam->json_tree);
22048   vat_json_init_object (node);
22049
22050   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22051   vat_json_object_add_uint (node, "appns_index",
22052                             clib_net_to_host_u32 (mp->appns_index));
22053   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22054   vat_json_object_add_uint (node, "scope", mp->scope);
22055   vat_json_object_add_uint (node, "action_index",
22056                             clib_net_to_host_u32 (mp->action_index));
22057   vat_json_object_add_uint (node, "lcl_port",
22058                             clib_net_to_host_u16 (mp->lcl_port));
22059   vat_json_object_add_uint (node, "rmt_port",
22060                             clib_net_to_host_u16 (mp->rmt_port));
22061   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22062   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22063   vat_json_object_add_string_copy (node, "tag", mp->tag);
22064   if (mp->is_ip4)
22065     {
22066       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22067       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22068       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22069       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22070     }
22071   else
22072     {
22073       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22074       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22075       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22076       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22077     }
22078 }
22079
22080 static int
22081 api_session_rule_add_del (vat_main_t * vam)
22082 {
22083   vl_api_session_rule_add_del_t *mp;
22084   unformat_input_t *i = vam->input;
22085   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22086   u32 appns_index = 0, scope = 0;
22087   ip4_address_t lcl_ip4, rmt_ip4;
22088   ip6_address_t lcl_ip6, rmt_ip6;
22089   u8 is_ip4 = 1, conn_set = 0;
22090   u8 is_add = 1, *tag = 0;
22091   int ret;
22092
22093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22094     {
22095       if (unformat (i, "del"))
22096         is_add = 0;
22097       else if (unformat (i, "add"))
22098         ;
22099       else if (unformat (i, "proto tcp"))
22100         proto = 0;
22101       else if (unformat (i, "proto udp"))
22102         proto = 1;
22103       else if (unformat (i, "appns %d", &appns_index))
22104         ;
22105       else if (unformat (i, "scope %d", &scope))
22106         ;
22107       else if (unformat (i, "tag %_%v%_", &tag))
22108         ;
22109       else
22110         if (unformat
22111             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22112              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22113              &rmt_port))
22114         {
22115           is_ip4 = 1;
22116           conn_set = 1;
22117         }
22118       else
22119         if (unformat
22120             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22121              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22122              &rmt_port))
22123         {
22124           is_ip4 = 0;
22125           conn_set = 1;
22126         }
22127       else if (unformat (i, "action %d", &action))
22128         ;
22129       else
22130         break;
22131     }
22132   if (proto == ~0 || !conn_set || action == ~0)
22133     {
22134       errmsg ("transport proto, connection and action must be set");
22135       return -99;
22136     }
22137
22138   if (scope > 3)
22139     {
22140       errmsg ("scope should be 0-3");
22141       return -99;
22142     }
22143
22144   M (SESSION_RULE_ADD_DEL, mp);
22145
22146   mp->is_ip4 = is_ip4;
22147   mp->transport_proto = proto;
22148   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22149   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22150   mp->lcl_plen = lcl_plen;
22151   mp->rmt_plen = rmt_plen;
22152   mp->action_index = clib_host_to_net_u32 (action);
22153   mp->appns_index = clib_host_to_net_u32 (appns_index);
22154   mp->scope = scope;
22155   mp->is_add = is_add;
22156   if (is_ip4)
22157     {
22158       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22159       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22160     }
22161   else
22162     {
22163       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22164       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22165     }
22166   if (tag)
22167     {
22168       clib_memcpy (mp->tag, tag, vec_len (tag));
22169       vec_free (tag);
22170     }
22171
22172   S (mp);
22173   W (ret);
22174   return ret;
22175 }
22176
22177 static int
22178 api_session_rules_dump (vat_main_t * vam)
22179 {
22180   vl_api_session_rules_dump_t *mp;
22181   vl_api_control_ping_t *mp_ping;
22182   int ret;
22183
22184   if (!vam->json_output)
22185     {
22186       print (vam->ofp, "%=20s", "Session Rules");
22187     }
22188
22189   M (SESSION_RULES_DUMP, mp);
22190   /* send it... */
22191   S (mp);
22192
22193   /* Use a control ping for synchronization */
22194   MPING (CONTROL_PING, mp_ping);
22195   S (mp_ping);
22196
22197   /* Wait for a reply... */
22198   W (ret);
22199   return ret;
22200 }
22201
22202 static int
22203 api_ip_container_proxy_add_del (vat_main_t * vam)
22204 {
22205   vl_api_ip_container_proxy_add_del_t *mp;
22206   unformat_input_t *i = vam->input;
22207   u32 plen = ~0, sw_if_index = ~0;
22208   ip4_address_t ip4;
22209   ip6_address_t ip6;
22210   u8 is_ip4 = 1;
22211   u8 is_add = 1;
22212   int ret;
22213
22214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22215     {
22216       if (unformat (i, "del"))
22217         is_add = 0;
22218       else if (unformat (i, "add"))
22219         ;
22220       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22221         {
22222           is_ip4 = 1;
22223           plen = 32;
22224         }
22225       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22226         {
22227           is_ip4 = 0;
22228           plen = 128;
22229         }
22230       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22231         ;
22232       else
22233         break;
22234     }
22235   if (sw_if_index == ~0 || plen == ~0)
22236     {
22237       errmsg ("address and sw_if_index must be set");
22238       return -99;
22239     }
22240
22241   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22242
22243   mp->is_ip4 = is_ip4;
22244   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22245   mp->plen = plen;
22246   mp->is_add = is_add;
22247   if (is_ip4)
22248     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22249   else
22250     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22251
22252   S (mp);
22253   W (ret);
22254   return ret;
22255 }
22256
22257 static int
22258 q_or_quit (vat_main_t * vam)
22259 {
22260 #if VPP_API_TEST_BUILTIN == 0
22261   longjmp (vam->jump_buf, 1);
22262 #endif
22263   return 0;                     /* not so much */
22264 }
22265
22266 static int
22267 q (vat_main_t * vam)
22268 {
22269   return q_or_quit (vam);
22270 }
22271
22272 static int
22273 quit (vat_main_t * vam)
22274 {
22275   return q_or_quit (vam);
22276 }
22277
22278 static int
22279 comment (vat_main_t * vam)
22280 {
22281   return 0;
22282 }
22283
22284 static int
22285 cmd_cmp (void *a1, void *a2)
22286 {
22287   u8 **c1 = a1;
22288   u8 **c2 = a2;
22289
22290   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22291 }
22292
22293 static int
22294 help (vat_main_t * vam)
22295 {
22296   u8 **cmds = 0;
22297   u8 *name = 0;
22298   hash_pair_t *p;
22299   unformat_input_t *i = vam->input;
22300   int j;
22301
22302   if (unformat (i, "%s", &name))
22303     {
22304       uword *hs;
22305
22306       vec_add1 (name, 0);
22307
22308       hs = hash_get_mem (vam->help_by_name, name);
22309       if (hs)
22310         print (vam->ofp, "usage: %s %s", name, hs[0]);
22311       else
22312         print (vam->ofp, "No such msg / command '%s'", name);
22313       vec_free (name);
22314       return 0;
22315     }
22316
22317   print (vam->ofp, "Help is available for the following:");
22318
22319     /* *INDENT-OFF* */
22320     hash_foreach_pair (p, vam->function_by_name,
22321     ({
22322       vec_add1 (cmds, (u8 *)(p->key));
22323     }));
22324     /* *INDENT-ON* */
22325
22326   vec_sort_with_function (cmds, cmd_cmp);
22327
22328   for (j = 0; j < vec_len (cmds); j++)
22329     print (vam->ofp, "%s", cmds[j]);
22330
22331   vec_free (cmds);
22332   return 0;
22333 }
22334
22335 static int
22336 set (vat_main_t * vam)
22337 {
22338   u8 *name = 0, *value = 0;
22339   unformat_input_t *i = vam->input;
22340
22341   if (unformat (i, "%s", &name))
22342     {
22343       /* The input buffer is a vector, not a string. */
22344       value = vec_dup (i->buffer);
22345       vec_delete (value, i->index, 0);
22346       /* Almost certainly has a trailing newline */
22347       if (value[vec_len (value) - 1] == '\n')
22348         value[vec_len (value) - 1] = 0;
22349       /* Make sure it's a proper string, one way or the other */
22350       vec_add1 (value, 0);
22351       (void) clib_macro_set_value (&vam->macro_main,
22352                                    (char *) name, (char *) value);
22353     }
22354   else
22355     errmsg ("usage: set <name> <value>");
22356
22357   vec_free (name);
22358   vec_free (value);
22359   return 0;
22360 }
22361
22362 static int
22363 unset (vat_main_t * vam)
22364 {
22365   u8 *name = 0;
22366
22367   if (unformat (vam->input, "%s", &name))
22368     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22369       errmsg ("unset: %s wasn't set", name);
22370   vec_free (name);
22371   return 0;
22372 }
22373
22374 typedef struct
22375 {
22376   u8 *name;
22377   u8 *value;
22378 } macro_sort_t;
22379
22380
22381 static int
22382 macro_sort_cmp (void *a1, void *a2)
22383 {
22384   macro_sort_t *s1 = a1;
22385   macro_sort_t *s2 = a2;
22386
22387   return strcmp ((char *) (s1->name), (char *) (s2->name));
22388 }
22389
22390 static int
22391 dump_macro_table (vat_main_t * vam)
22392 {
22393   macro_sort_t *sort_me = 0, *sm;
22394   int i;
22395   hash_pair_t *p;
22396
22397     /* *INDENT-OFF* */
22398     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22399     ({
22400       vec_add2 (sort_me, sm, 1);
22401       sm->name = (u8 *)(p->key);
22402       sm->value = (u8 *) (p->value[0]);
22403     }));
22404     /* *INDENT-ON* */
22405
22406   vec_sort_with_function (sort_me, macro_sort_cmp);
22407
22408   if (vec_len (sort_me))
22409     print (vam->ofp, "%-15s%s", "Name", "Value");
22410   else
22411     print (vam->ofp, "The macro table is empty...");
22412
22413   for (i = 0; i < vec_len (sort_me); i++)
22414     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22415   return 0;
22416 }
22417
22418 static int
22419 dump_node_table (vat_main_t * vam)
22420 {
22421   int i, j;
22422   vlib_node_t *node, *next_node;
22423
22424   if (vec_len (vam->graph_nodes) == 0)
22425     {
22426       print (vam->ofp, "Node table empty, issue get_node_graph...");
22427       return 0;
22428     }
22429
22430   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22431     {
22432       node = vam->graph_nodes[i];
22433       print (vam->ofp, "[%d] %s", i, node->name);
22434       for (j = 0; j < vec_len (node->next_nodes); j++)
22435         {
22436           if (node->next_nodes[j] != ~0)
22437             {
22438               next_node = vam->graph_nodes[node->next_nodes[j]];
22439               print (vam->ofp, "  [%d] %s", j, next_node->name);
22440             }
22441         }
22442     }
22443   return 0;
22444 }
22445
22446 static int
22447 value_sort_cmp (void *a1, void *a2)
22448 {
22449   name_sort_t *n1 = a1;
22450   name_sort_t *n2 = a2;
22451
22452   if (n1->value < n2->value)
22453     return -1;
22454   if (n1->value > n2->value)
22455     return 1;
22456   return 0;
22457 }
22458
22459
22460 static int
22461 dump_msg_api_table (vat_main_t * vam)
22462 {
22463   api_main_t *am = &api_main;
22464   name_sort_t *nses = 0, *ns;
22465   hash_pair_t *hp;
22466   int i;
22467
22468   /* *INDENT-OFF* */
22469   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22470   ({
22471     vec_add2 (nses, ns, 1);
22472     ns->name = (u8 *)(hp->key);
22473     ns->value = (u32) hp->value[0];
22474   }));
22475   /* *INDENT-ON* */
22476
22477   vec_sort_with_function (nses, value_sort_cmp);
22478
22479   for (i = 0; i < vec_len (nses); i++)
22480     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22481   vec_free (nses);
22482   return 0;
22483 }
22484
22485 static int
22486 get_msg_id (vat_main_t * vam)
22487 {
22488   u8 *name_and_crc;
22489   u32 message_index;
22490
22491   if (unformat (vam->input, "%s", &name_and_crc))
22492     {
22493       message_index = vl_api_get_msg_index (name_and_crc);
22494       if (message_index == ~0)
22495         {
22496           print (vam->ofp, " '%s' not found", name_and_crc);
22497           return 0;
22498         }
22499       print (vam->ofp, " '%s' has message index %d",
22500              name_and_crc, message_index);
22501       return 0;
22502     }
22503   errmsg ("name_and_crc required...");
22504   return 0;
22505 }
22506
22507 static int
22508 search_node_table (vat_main_t * vam)
22509 {
22510   unformat_input_t *line_input = vam->input;
22511   u8 *node_to_find;
22512   int j;
22513   vlib_node_t *node, *next_node;
22514   uword *p;
22515
22516   if (vam->graph_node_index_by_name == 0)
22517     {
22518       print (vam->ofp, "Node table empty, issue get_node_graph...");
22519       return 0;
22520     }
22521
22522   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22523     {
22524       if (unformat (line_input, "%s", &node_to_find))
22525         {
22526           vec_add1 (node_to_find, 0);
22527           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22528           if (p == 0)
22529             {
22530               print (vam->ofp, "%s not found...", node_to_find);
22531               goto out;
22532             }
22533           node = vam->graph_nodes[p[0]];
22534           print (vam->ofp, "[%d] %s", p[0], node->name);
22535           for (j = 0; j < vec_len (node->next_nodes); j++)
22536             {
22537               if (node->next_nodes[j] != ~0)
22538                 {
22539                   next_node = vam->graph_nodes[node->next_nodes[j]];
22540                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22541                 }
22542             }
22543         }
22544
22545       else
22546         {
22547           clib_warning ("parse error '%U'", format_unformat_error,
22548                         line_input);
22549           return -99;
22550         }
22551
22552     out:
22553       vec_free (node_to_find);
22554
22555     }
22556
22557   return 0;
22558 }
22559
22560
22561 static int
22562 script (vat_main_t * vam)
22563 {
22564 #if (VPP_API_TEST_BUILTIN==0)
22565   u8 *s = 0;
22566   char *save_current_file;
22567   unformat_input_t save_input;
22568   jmp_buf save_jump_buf;
22569   u32 save_line_number;
22570
22571   FILE *new_fp, *save_ifp;
22572
22573   if (unformat (vam->input, "%s", &s))
22574     {
22575       new_fp = fopen ((char *) s, "r");
22576       if (new_fp == 0)
22577         {
22578           errmsg ("Couldn't open script file %s", s);
22579           vec_free (s);
22580           return -99;
22581         }
22582     }
22583   else
22584     {
22585       errmsg ("Missing script name");
22586       return -99;
22587     }
22588
22589   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22590   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22591   save_ifp = vam->ifp;
22592   save_line_number = vam->input_line_number;
22593   save_current_file = (char *) vam->current_file;
22594
22595   vam->input_line_number = 0;
22596   vam->ifp = new_fp;
22597   vam->current_file = s;
22598   do_one_file (vam);
22599
22600   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22601   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22602   vam->ifp = save_ifp;
22603   vam->input_line_number = save_line_number;
22604   vam->current_file = (u8 *) save_current_file;
22605   vec_free (s);
22606
22607   return 0;
22608 #else
22609   clib_warning ("use the exec command...");
22610   return -99;
22611 #endif
22612 }
22613
22614 static int
22615 echo (vat_main_t * vam)
22616 {
22617   print (vam->ofp, "%v", vam->input->buffer);
22618   return 0;
22619 }
22620
22621 /* List of API message constructors, CLI names map to api_xxx */
22622 #define foreach_vpe_api_msg                                             \
22623 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22624 _(sw_interface_dump,"")                                                 \
22625 _(sw_interface_set_flags,                                               \
22626   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22627 _(sw_interface_add_del_address,                                         \
22628   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22629 _(sw_interface_set_rx_mode,                                             \
22630   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22631 _(sw_interface_set_table,                                               \
22632   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22633 _(sw_interface_set_mpls_enable,                                         \
22634   "<intfc> | sw_if_index [disable | dis]")                              \
22635 _(sw_interface_set_vpath,                                               \
22636   "<intfc> | sw_if_index <id> enable | disable")                        \
22637 _(sw_interface_set_vxlan_bypass,                                        \
22638   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22639 _(sw_interface_set_geneve_bypass,                                       \
22640   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22641 _(sw_interface_set_l2_xconnect,                                         \
22642   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22643   "enable | disable")                                                   \
22644 _(sw_interface_set_l2_bridge,                                           \
22645   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22646   "[shg <split-horizon-group>] [bvi]\n"                                 \
22647   "enable | disable")                                                   \
22648 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22649 _(bridge_domain_add_del,                                                \
22650   "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") \
22651 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22652 _(l2fib_add_del,                                                        \
22653   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22654 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22655 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22656 _(l2_flags,                                                             \
22657   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22658 _(bridge_flags,                                                         \
22659   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22660 _(tap_connect,                                                          \
22661   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22662 _(tap_modify,                                                           \
22663   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22664 _(tap_delete,                                                           \
22665   "<vpp-if-name> | sw_if_index <id>")                                   \
22666 _(sw_interface_tap_dump, "")                                            \
22667 _(tap_create_v2,                                                        \
22668   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22669 _(tap_delete_v2,                                                        \
22670   "<vpp-if-name> | sw_if_index <id>")                                   \
22671 _(sw_interface_tap_v2_dump, "")                                         \
22672 _(ip_table_add_del,                                                     \
22673   "table-id <n> [ipv6]\n")                                              \
22674 _(ip_add_del_route,                                                     \
22675   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22676   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22677   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22678   "[multipath] [count <n>]")                                            \
22679 _(ip_mroute_add_del,                                                    \
22680   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22681   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22682 _(mpls_table_add_del,                                                   \
22683   "table-id <n>\n")                                                     \
22684 _(mpls_route_add_del,                                                   \
22685   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22686   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22687   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22688   "[multipath] [count <n>]")                                            \
22689 _(mpls_ip_bind_unbind,                                                  \
22690   "<label> <addr/len>")                                                 \
22691 _(mpls_tunnel_add_del,                                                  \
22692   " via <addr> [table-id <n>]\n"                                        \
22693   "sw_if_index <id>] [l2]  [del]")                                      \
22694 _(bier_table_add_del,                                                   \
22695   "<label> <sub-domain> <set> <bsl> [del]")                             \
22696 _(bier_route_add_del,                                                   \
22697   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22698   "[<intfc> | sw_if_index <id>]"                                        \
22699   "[weight <n>] [del] [multipath]")                                     \
22700 _(proxy_arp_add_del,                                                    \
22701   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22702 _(proxy_arp_intfc_enable_disable,                                       \
22703   "<intfc> | sw_if_index <id> enable | disable")                        \
22704 _(sw_interface_set_unnumbered,                                          \
22705   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22706 _(ip_neighbor_add_del,                                                  \
22707   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22708   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22709 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22710 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22711   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22712   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22713   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22714 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22715 _(reset_fib, "vrf <n> [ipv6]")                                          \
22716 _(dhcp_proxy_config,                                                    \
22717   "svr <v46-address> src <v46-address>\n"                               \
22718    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22719 _(dhcp_proxy_set_vss,                                                   \
22720   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22721 _(dhcp_proxy_dump, "ip6")                                               \
22722 _(dhcp_client_config,                                                   \
22723   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22724 _(set_ip_flow_hash,                                                     \
22725   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22726 _(sw_interface_ip6_enable_disable,                                      \
22727   "<intfc> | sw_if_index <id> enable | disable")                        \
22728 _(sw_interface_ip6_set_link_local_address,                              \
22729   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22730 _(ip6nd_proxy_add_del,                                                  \
22731   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22732 _(ip6nd_proxy_dump, "")                                                 \
22733 _(sw_interface_ip6nd_ra_prefix,                                         \
22734   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22735   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22736   "[nolink] [isno]")                                                    \
22737 _(sw_interface_ip6nd_ra_config,                                         \
22738   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22739   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22740   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22741 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22742 _(l2_patch_add_del,                                                     \
22743   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22744   "enable | disable")                                                   \
22745 _(sr_localsid_add_del,                                                  \
22746   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22747   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22748 _(classify_add_del_table,                                               \
22749   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22750   " [del] [del-chain] mask <mask-value>\n"                              \
22751   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22752   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22753 _(classify_add_del_session,                                             \
22754   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22755   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22756   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22757   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22758 _(classify_set_interface_ip_table,                                      \
22759   "<intfc> | sw_if_index <nn> table <nn>")                              \
22760 _(classify_set_interface_l2_tables,                                     \
22761   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22762   "  [other-table <nn>]")                                               \
22763 _(get_node_index, "node <node-name")                                    \
22764 _(add_node_next, "node <node-name> next <next-node-name>")              \
22765 _(l2tpv3_create_tunnel,                                                 \
22766   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22767   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22768   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22769 _(l2tpv3_set_tunnel_cookies,                                            \
22770   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22771   "[new_remote_cookie <nn>]\n")                                         \
22772 _(l2tpv3_interface_enable_disable,                                      \
22773   "<intfc> | sw_if_index <nn> enable | disable")                        \
22774 _(l2tpv3_set_lookup_key,                                                \
22775   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22776 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22777 _(vxlan_add_del_tunnel,                                                 \
22778   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22779   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22780   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22781 _(geneve_add_del_tunnel,                                                \
22782   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22783   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22784   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22785 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22786 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22787 _(gre_add_del_tunnel,                                                   \
22788   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22789 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22790 _(l2_fib_clear_table, "")                                               \
22791 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22792 _(l2_interface_vlan_tag_rewrite,                                        \
22793   "<intfc> | sw_if_index <nn> \n"                                       \
22794   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22795   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22796 _(create_vhost_user_if,                                                 \
22797         "socket <filename> [server] [renumber <dev_instance>] "         \
22798         "[mac <mac_address>]")                                          \
22799 _(modify_vhost_user_if,                                                 \
22800         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22801         "[server] [renumber <dev_instance>]")                           \
22802 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22803 _(sw_interface_vhost_user_dump, "")                                     \
22804 _(show_version, "")                                                     \
22805 _(vxlan_gpe_add_del_tunnel,                                             \
22806   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22807   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22808   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22809   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22810 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22811 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22812 _(interface_name_renumber,                                              \
22813   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22814 _(input_acl_set_interface,                                              \
22815   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22816   "  [l2-table <nn>] [del]")                                            \
22817 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22818 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22819 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22820 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22821 _(ip_dump, "ipv4 | ipv6")                                               \
22822 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22823 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22824   "  spid_id <n> ")                                                     \
22825 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22826   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22827   "  integ_alg <alg> integ_key <hex>")                                  \
22828 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22829   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22830   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22831   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22832 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22833 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22834   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22835   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22836   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22837 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22838 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22839   "  <alg> <hex>\n")                                                    \
22840 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22841 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22842 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22843   "(auth_data 0x<data> | auth_data <data>)")                            \
22844 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22845   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22846 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22847   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22848   "(local|remote)")                                                     \
22849 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22850 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22851 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22852 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22853 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22854 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22855 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22856 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22857 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22858 _(delete_loopback,"sw_if_index <nn>")                                   \
22859 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22860 _(map_add_domain,                                                       \
22861   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22862   "ip6-src <ip6addr> "                                                  \
22863   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22864 _(map_del_domain, "index <n>")                                          \
22865 _(map_add_del_rule,                                                     \
22866   "index <n> psid <n> dst <ip6addr> [del]")                             \
22867 _(map_domain_dump, "")                                                  \
22868 _(map_rule_dump, "index <map-domain>")                                  \
22869 _(want_interface_events,  "enable|disable")                             \
22870 _(want_stats,"enable|disable")                                          \
22871 _(get_first_msg_id, "client <name>")                                    \
22872 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22873 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22874   "fib-id <nn> [ip4][ip6][default]")                                    \
22875 _(get_node_graph, " ")                                                  \
22876 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22877 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22878 _(ioam_disable, "")                                                     \
22879 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22880                             " sw_if_index <sw_if_index> p <priority> "  \
22881                             "w <weight>] [del]")                        \
22882 _(one_add_del_locator, "locator-set <locator_name> "                    \
22883                         "iface <intf> | sw_if_index <sw_if_index> "     \
22884                         "p <priority> w <weight> [del]")                \
22885 _(one_add_del_local_eid,"vni <vni> eid "                                \
22886                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22887                          "locator-set <locator_name> [del]"             \
22888                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22889 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22890 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22891 _(one_enable_disable, "enable|disable")                                 \
22892 _(one_map_register_enable_disable, "enable|disable")                    \
22893 _(one_map_register_fallback_threshold, "<value>")                       \
22894 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22895 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22896                                "[seid <seid>] "                         \
22897                                "rloc <locator> p <prio> "               \
22898                                "w <weight> [rloc <loc> ... ] "          \
22899                                "action <action> [del-all]")             \
22900 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22901                           "<local-eid>")                                \
22902 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22903 _(one_use_petr, "ip-address> | disable")                                \
22904 _(one_map_request_mode, "src-dst|dst-only")                             \
22905 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22906 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22907 _(one_locator_set_dump, "[local | remote]")                             \
22908 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22909 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22910                        "[local] | [remote]")                            \
22911 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22912 _(one_ndp_bd_get, "")                                                   \
22913 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22914 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22915 _(one_l2_arp_bd_get, "")                                                \
22916 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22917 _(one_stats_enable_disable, "enable|disalbe")                           \
22918 _(show_one_stats_enable_disable, "")                                    \
22919 _(one_eid_table_vni_dump, "")                                           \
22920 _(one_eid_table_map_dump, "l2|l3")                                      \
22921 _(one_map_resolver_dump, "")                                            \
22922 _(one_map_server_dump, "")                                              \
22923 _(one_adjacencies_get, "vni <vni>")                                     \
22924 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22925 _(show_one_rloc_probe_state, "")                                        \
22926 _(show_one_map_register_state, "")                                      \
22927 _(show_one_status, "")                                                  \
22928 _(one_stats_dump, "")                                                   \
22929 _(one_stats_flush, "")                                                  \
22930 _(one_get_map_request_itr_rlocs, "")                                    \
22931 _(one_map_register_set_ttl, "<ttl>")                                    \
22932 _(one_set_transport_protocol, "udp|api")                                \
22933 _(one_get_transport_protocol, "")                                       \
22934 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22935 _(one_show_xtr_mode, "")                                                \
22936 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22937 _(one_show_pitr_mode, "")                                               \
22938 _(one_enable_disable_petr_mode, "enable|disable")                       \
22939 _(one_show_petr_mode, "")                                               \
22940 _(show_one_nsh_mapping, "")                                             \
22941 _(show_one_pitr, "")                                                    \
22942 _(show_one_use_petr, "")                                                \
22943 _(show_one_map_request_mode, "")                                        \
22944 _(show_one_map_register_ttl, "")                                        \
22945 _(show_one_map_register_fallback_threshold, "")                         \
22946 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22947                             " sw_if_index <sw_if_index> p <priority> "  \
22948                             "w <weight>] [del]")                        \
22949 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22950                         "iface <intf> | sw_if_index <sw_if_index> "     \
22951                         "p <priority> w <weight> [del]")                \
22952 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22953                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22954                          "locator-set <locator_name> [del]"             \
22955                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22956 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22957 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22958 _(lisp_enable_disable, "enable|disable")                                \
22959 _(lisp_map_register_enable_disable, "enable|disable")                   \
22960 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22961 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22962                                "[seid <seid>] "                         \
22963                                "rloc <locator> p <prio> "               \
22964                                "w <weight> [rloc <loc> ... ] "          \
22965                                "action <action> [del-all]")             \
22966 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22967                           "<local-eid>")                                \
22968 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22969 _(lisp_use_petr, "<ip-address> | disable")                              \
22970 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22971 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22972 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22973 _(lisp_locator_set_dump, "[local | remote]")                            \
22974 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22975 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22976                        "[local] | [remote]")                            \
22977 _(lisp_eid_table_vni_dump, "")                                          \
22978 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22979 _(lisp_map_resolver_dump, "")                                           \
22980 _(lisp_map_server_dump, "")                                             \
22981 _(lisp_adjacencies_get, "vni <vni>")                                    \
22982 _(gpe_fwd_entry_vnis_get, "")                                           \
22983 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22984 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22985                                 "[table <table-id>]")                   \
22986 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22987 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22988 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22989 _(gpe_get_encap_mode, "")                                               \
22990 _(lisp_gpe_add_del_iface, "up|down")                                    \
22991 _(lisp_gpe_enable_disable, "enable|disable")                            \
22992 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22993   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22994 _(show_lisp_rloc_probe_state, "")                                       \
22995 _(show_lisp_map_register_state, "")                                     \
22996 _(show_lisp_status, "")                                                 \
22997 _(lisp_get_map_request_itr_rlocs, "")                                   \
22998 _(show_lisp_pitr, "")                                                   \
22999 _(show_lisp_use_petr, "")                                               \
23000 _(show_lisp_map_request_mode, "")                                       \
23001 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23002 _(af_packet_delete, "name <host interface name>")                       \
23003 _(policer_add_del, "name <policer name> <params> [del]")                \
23004 _(policer_dump, "[name <policer name>]")                                \
23005 _(policer_classify_set_interface,                                       \
23006   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23007   "  [l2-table <nn>] [del]")                                            \
23008 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23009 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23010     "[master|slave]")                                                   \
23011 _(netmap_delete, "name <interface name>")                               \
23012 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23013 _(mpls_fib_dump, "")                                                    \
23014 _(classify_table_ids, "")                                               \
23015 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23016 _(classify_table_info, "table_id <nn>")                                 \
23017 _(classify_session_dump, "table_id <nn>")                               \
23018 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23019     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23020     "[template_interval <nn>] [udp_checksum]")                          \
23021 _(ipfix_exporter_dump, "")                                              \
23022 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23023 _(ipfix_classify_stream_dump, "")                                       \
23024 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23025 _(ipfix_classify_table_dump, "")                                        \
23026 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23027 _(sw_interface_span_dump, "[l2]")                                           \
23028 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23029 _(pg_create_interface, "if_id <nn>")                                    \
23030 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23031 _(pg_enable_disable, "[stream <id>] disable")                           \
23032 _(ip_source_and_port_range_check_add_del,                               \
23033   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23034 _(ip_source_and_port_range_check_interface_add_del,                     \
23035   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23036   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23037 _(ipsec_gre_add_del_tunnel,                                             \
23038   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23039 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23040 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23041 _(l2_interface_pbb_tag_rewrite,                                         \
23042   "<intfc> | sw_if_index <nn> \n"                                       \
23043   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23044   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23045 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23046 _(flow_classify_set_interface,                                          \
23047   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23048 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23049 _(ip_fib_dump, "")                                                      \
23050 _(ip_mfib_dump, "")                                                     \
23051 _(ip6_fib_dump, "")                                                     \
23052 _(ip6_mfib_dump, "")                                                    \
23053 _(feature_enable_disable, "arc_name <arc_name> "                        \
23054   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23055 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23056 "[disable]")                                                            \
23057 _(l2_xconnect_dump, "")                                                 \
23058 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23059 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23060 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23061 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23062 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23063 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23064 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23065   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23066 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23067 _(memfd_segment_create,"size <nnn>")                                    \
23068 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23069 _(dns_enable_disable, "[enable][disable]")                              \
23070 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23071 _(dns_resolve_name, "<hostname>")                                       \
23072 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23073 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23074 _(dns_resolve_name, "<hostname>")                                       \
23075 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23076   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23077 _(session_rules_dump, "")                                               \
23078 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23079
23080 /* List of command functions, CLI names map directly to functions */
23081 #define foreach_cli_function                                    \
23082 _(comment, "usage: comment <ignore-rest-of-line>")              \
23083 _(dump_interface_table, "usage: dump_interface_table")          \
23084 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23085 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23086 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23087 _(dump_stats_table, "usage: dump_stats_table")                  \
23088 _(dump_macro_table, "usage: dump_macro_table ")                 \
23089 _(dump_node_table, "usage: dump_node_table")                    \
23090 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23091 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23092 _(echo, "usage: echo <message>")                                \
23093 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23094 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23095 _(help, "usage: help")                                          \
23096 _(q, "usage: quit")                                             \
23097 _(quit, "usage: quit")                                          \
23098 _(search_node_table, "usage: search_node_table <name>...")      \
23099 _(set, "usage: set <variable-name> <value>")                    \
23100 _(script, "usage: script <file-name>")                          \
23101 _(unset, "usage: unset <variable-name>")
23102 #define _(N,n)                                  \
23103     static void vl_api_##n##_t_handler_uni      \
23104     (vl_api_##n##_t * mp)                       \
23105     {                                           \
23106         vat_main_t * vam = &vat_main;           \
23107         if (vam->json_output) {                 \
23108             vl_api_##n##_t_handler_json(mp);    \
23109         } else {                                \
23110             vl_api_##n##_t_handler(mp);         \
23111         }                                       \
23112     }
23113 foreach_vpe_api_reply_msg;
23114 #if VPP_API_TEST_BUILTIN == 0
23115 foreach_standalone_reply_msg;
23116 #endif
23117 #undef _
23118
23119 void
23120 vat_api_hookup (vat_main_t * vam)
23121 {
23122 #define _(N,n)                                                  \
23123     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23124                            vl_api_##n##_t_handler_uni,          \
23125                            vl_noop_handler,                     \
23126                            vl_api_##n##_t_endian,               \
23127                            vl_api_##n##_t_print,                \
23128                            sizeof(vl_api_##n##_t), 1);
23129   foreach_vpe_api_reply_msg;
23130 #if VPP_API_TEST_BUILTIN == 0
23131   foreach_standalone_reply_msg;
23132 #endif
23133 #undef _
23134
23135 #if (VPP_API_TEST_BUILTIN==0)
23136   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23137
23138   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23139
23140   vam->function_by_name = hash_create_string (0, sizeof (uword));
23141
23142   vam->help_by_name = hash_create_string (0, sizeof (uword));
23143 #endif
23144
23145   /* API messages we can send */
23146 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23147   foreach_vpe_api_msg;
23148 #undef _
23149
23150   /* Help strings */
23151 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23152   foreach_vpe_api_msg;
23153 #undef _
23154
23155   /* CLI functions */
23156 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23157   foreach_cli_function;
23158 #undef _
23159
23160   /* Help strings */
23161 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23162   foreach_cli_function;
23163 #undef _
23164 }
23165
23166 #if VPP_API_TEST_BUILTIN
23167 static clib_error_t *
23168 vat_api_hookup_shim (vlib_main_t * vm)
23169 {
23170   vat_api_hookup (&vat_main);
23171   return 0;
23172 }
23173
23174 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23175 #endif
23176
23177 /*
23178  * fd.io coding-style-patch-verification: ON
23179  *
23180  * Local Variables:
23181  * eval: (c-set-style "gnu")
23182  * End:
23183  */