Remove the unused 'create VRF if needed' API parameters
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   return vl_socket_client_connect
92     (&vam->socket_client_main, (char *) vam->socket_name,
93      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 void
103 vl_socket_client_read_reply (socket_client_main_t * scm)
104 {
105 };
106 #endif
107
108
109 f64
110 vat_time_now (vat_main_t * vam)
111 {
112 #if VPP_API_TEST_BUILTIN
113   return vlib_time_now (vam->vlib_main);
114 #else
115   return clib_time_now (&vam->clib_time);
116 #endif
117 }
118
119 void
120 errmsg (char *fmt, ...)
121 {
122   vat_main_t *vam = &vat_main;
123   va_list va;
124   u8 *s;
125
126   va_start (va, fmt);
127   s = va_format (0, fmt, &va);
128   va_end (va);
129
130   vec_add1 (s, 0);
131
132 #if VPP_API_TEST_BUILTIN
133   vlib_cli_output (vam->vlib_main, (char *) s);
134 #else
135   {
136     if (vam->ifp != stdin)
137       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
138                vam->input_line_number);
139     fformat (vam->ofp, (char *) s);
140     fflush (vam->ofp);
141   }
142 #endif
143
144   vec_free (s);
145 }
146
147 #if VPP_API_TEST_BUILTIN == 0
148 static uword
149 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
150 {
151   vat_main_t *vam = va_arg (*args, vat_main_t *);
152   u32 *result = va_arg (*args, u32 *);
153   u8 *if_name;
154   uword *p;
155
156   if (!unformat (input, "%s", &if_name))
157     return 0;
158
159   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
160   if (p == 0)
161     return 0;
162   *result = p[0];
163   return 1;
164 }
165
166 /* Parse an IP4 address %d.%d.%d.%d. */
167 uword
168 unformat_ip4_address (unformat_input_t * input, va_list * args)
169 {
170   u8 *result = va_arg (*args, u8 *);
171   unsigned a[4];
172
173   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
174     return 0;
175
176   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
177     return 0;
178
179   result[0] = a[0];
180   result[1] = a[1];
181   result[2] = a[2];
182   result[3] = a[3];
183
184   return 1;
185 }
186
187 uword
188 unformat_ethernet_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   u32 i, a[6];
192
193   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
194                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
195     return 0;
196
197   /* Check range. */
198   for (i = 0; i < 6; i++)
199     if (a[i] >= (1 << 8))
200       return 0;
201
202   for (i = 0; i < 6; i++)
203     result[i] = a[i];
204
205   return 1;
206 }
207
208 /* Returns ethernet type as an int in host byte order. */
209 uword
210 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
211                                         va_list * args)
212 {
213   u16 *result = va_arg (*args, u16 *);
214   int type;
215
216   /* Numeric type. */
217   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
218     {
219       if (type >= (1 << 16))
220         return 0;
221       *result = type;
222       return 1;
223     }
224   return 0;
225 }
226
227 /* Parse an IP6 address. */
228 uword
229 unformat_ip6_address (unformat_input_t * input, va_list * args)
230 {
231   ip6_address_t *result = va_arg (*args, ip6_address_t *);
232   u16 hex_quads[8];
233   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
234   uword c, n_colon, double_colon_index;
235
236   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
237   double_colon_index = ARRAY_LEN (hex_quads);
238   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
239     {
240       hex_digit = 16;
241       if (c >= '0' && c <= '9')
242         hex_digit = c - '0';
243       else if (c >= 'a' && c <= 'f')
244         hex_digit = c + 10 - 'a';
245       else if (c >= 'A' && c <= 'F')
246         hex_digit = c + 10 - 'A';
247       else if (c == ':' && n_colon < 2)
248         n_colon++;
249       else
250         {
251           unformat_put_input (input);
252           break;
253         }
254
255       /* Too many hex quads. */
256       if (n_hex_quads >= ARRAY_LEN (hex_quads))
257         return 0;
258
259       if (hex_digit < 16)
260         {
261           hex_quad = (hex_quad << 4) | hex_digit;
262
263           /* Hex quad must fit in 16 bits. */
264           if (n_hex_digits >= 4)
265             return 0;
266
267           n_colon = 0;
268           n_hex_digits++;
269         }
270
271       /* Save position of :: */
272       if (n_colon == 2)
273         {
274           /* More than one :: ? */
275           if (double_colon_index < ARRAY_LEN (hex_quads))
276             return 0;
277           double_colon_index = n_hex_quads;
278         }
279
280       if (n_colon > 0 && n_hex_digits > 0)
281         {
282           hex_quads[n_hex_quads++] = hex_quad;
283           hex_quad = 0;
284           n_hex_digits = 0;
285         }
286     }
287
288   if (n_hex_digits > 0)
289     hex_quads[n_hex_quads++] = hex_quad;
290
291   {
292     word i;
293
294     /* Expand :: to appropriate number of zero hex quads. */
295     if (double_colon_index < ARRAY_LEN (hex_quads))
296       {
297         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
298
299         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
300           hex_quads[n_zero + i] = hex_quads[i];
301
302         for (i = 0; i < n_zero; i++)
303           hex_quads[double_colon_index + i] = 0;
304
305         n_hex_quads = ARRAY_LEN (hex_quads);
306       }
307
308     /* Too few hex quads given. */
309     if (n_hex_quads < ARRAY_LEN (hex_quads))
310       return 0;
311
312     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
313       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
314
315     return 1;
316   }
317 }
318
319 uword
320 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
321 {
322   u32 *r = va_arg (*args, u32 *);
323
324   if (0);
325 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
326   foreach_ipsec_policy_action
327 #undef _
328     else
329     return 0;
330   return 1;
331 }
332
333 uword
334 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
340   foreach_ipsec_crypto_alg
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 u8 *
348 format_ipsec_crypto_alg (u8 * s, va_list * args)
349 {
350   u32 i = va_arg (*args, u32);
351   u8 *t = 0;
352
353   switch (i)
354     {
355 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
356       foreach_ipsec_crypto_alg
357 #undef _
358     default:
359       return format (s, "unknown");
360     }
361   return format (s, "%s", t);
362 }
363
364 uword
365 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
371   foreach_ipsec_integ_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_integ_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_integ_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
402   foreach_ikev2_auth_method
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
416   foreach_ikev2_id_type
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422 #else /* VPP_API_TEST_BUILTIN == 1 */
423 static uword
424 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
425 {
426   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
427   vnet_main_t *vnm = vnet_get_main ();
428   u32 *result = va_arg (*args, u32 *);
429   u32 sw_if_index;
430
431   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
432     return 0;
433
434   *result = sw_if_index;
435   return 1;
436 }
437 #endif /* VPP_API_TEST_BUILTIN */
438
439 static uword
440 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
441 {
442   u8 *r = va_arg (*args, u8 *);
443
444   if (unformat (input, "kbps"))
445     *r = SSE2_QOS_RATE_KBPS;
446   else if (unformat (input, "pps"))
447     *r = SSE2_QOS_RATE_PPS;
448   else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_round_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "closest"))
459     *r = SSE2_QOS_ROUND_TO_CLOSEST;
460   else if (unformat (input, "up"))
461     *r = SSE2_QOS_ROUND_TO_UP;
462   else if (unformat (input, "down"))
463     *r = SSE2_QOS_ROUND_TO_DOWN;
464   else
465     return 0;
466   return 1;
467 }
468
469 static uword
470 unformat_policer_type (unformat_input_t * input, va_list * args)
471 {
472   u8 *r = va_arg (*args, u8 *);
473
474   if (unformat (input, "1r2c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R2C;
476   else if (unformat (input, "1r3c"))
477     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
478   else if (unformat (input, "2r3c-2698"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
480   else if (unformat (input, "2r3c-4115"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
482   else if (unformat (input, "2r3c-mef5cf1"))
483     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_dscp (unformat_input_t * input, va_list * va)
491 {
492   u8 *r = va_arg (*va, u8 *);
493
494   if (0);
495 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
496   foreach_vnet_dscp
497 #undef _
498     else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_action_type (unformat_input_t * input, va_list * va)
505 {
506   sse2_qos_pol_action_params_st *a
507     = va_arg (*va, sse2_qos_pol_action_params_st *);
508
509   if (unformat (input, "drop"))
510     a->action_type = SSE2_QOS_ACTION_DROP;
511   else if (unformat (input, "transmit"))
512     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
513   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
514     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
515   else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
522 {
523   u32 *r = va_arg (*va, u32 *);
524   u32 tid;
525
526   if (unformat (input, "ip4"))
527     tid = POLICER_CLASSIFY_TABLE_IP4;
528   else if (unformat (input, "ip6"))
529     tid = POLICER_CLASSIFY_TABLE_IP6;
530   else if (unformat (input, "l2"))
531     tid = POLICER_CLASSIFY_TABLE_L2;
532   else
533     return 0;
534
535   *r = tid;
536   return 1;
537 }
538
539 static uword
540 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = FLOW_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = FLOW_CLASSIFY_TABLE_IP6;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
557 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
558 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
559 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
560
561 #if (VPP_API_TEST_BUILTIN==0)
562 uword
563 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
564 {
565   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
566   mfib_itf_attribute_t attr;
567
568   old = *iflags;
569   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
570   {
571     if (unformat (input, mfib_itf_flag_long_names[attr]))
572       *iflags |= (1 << attr);
573   }
574   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
575   {
576     if (unformat (input, mfib_itf_flag_names[attr]))
577       *iflags |= (1 << attr);
578   }
579
580   return (old == *iflags ? 0 : 1);
581 }
582
583 uword
584 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
587   mfib_entry_attribute_t attr;
588
589   old = *eflags;
590   FOR_EACH_MFIB_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_flag_long_names[attr]))
593       *eflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_flag_names[attr]))
598       *eflags |= (1 << attr);
599   }
600
601   return (old == *eflags ? 0 : 1);
602 }
603
604 u8 *
605 format_ip4_address (u8 * s, va_list * args)
606 {
607   u8 *a = va_arg (*args, u8 *);
608   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
609 }
610
611 u8 *
612 format_ip6_address (u8 * s, va_list * args)
613 {
614   ip6_address_t *a = va_arg (*args, ip6_address_t *);
615   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
616
617   i_max_n_zero = ARRAY_LEN (a->as_u16);
618   max_n_zeros = 0;
619   i_first_zero = i_max_n_zero;
620   n_zeros = 0;
621   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
622     {
623       u32 is_zero = a->as_u16[i] == 0;
624       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
625         {
626           i_first_zero = i;
627           n_zeros = 0;
628         }
629       n_zeros += is_zero;
630       if ((!is_zero && n_zeros > max_n_zeros)
631           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
632         {
633           i_max_n_zero = i_first_zero;
634           max_n_zeros = n_zeros;
635           i_first_zero = ARRAY_LEN (a->as_u16);
636           n_zeros = 0;
637         }
638     }
639
640   last_double_colon = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       if (i == i_max_n_zero && max_n_zeros > 1)
644         {
645           s = format (s, "::");
646           i += max_n_zeros - 1;
647           last_double_colon = 1;
648         }
649       else
650         {
651           s = format (s, "%s%x",
652                       (last_double_colon || i == 0) ? "" : ":",
653                       clib_net_to_host_u16 (a->as_u16[i]));
654           last_double_colon = 0;
655         }
656     }
657
658   return s;
659 }
660
661 /* Format an IP46 address. */
662 u8 *
663 format_ip46_address (u8 * s, va_list * args)
664 {
665   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
666   ip46_type_t type = va_arg (*args, ip46_type_t);
667   int is_ip4 = 1;
668
669   switch (type)
670     {
671     case IP46_TYPE_ANY:
672       is_ip4 = ip46_address_is_ip4 (ip46);
673       break;
674     case IP46_TYPE_IP4:
675       is_ip4 = 1;
676       break;
677     case IP46_TYPE_IP6:
678       is_ip4 = 0;
679       break;
680     }
681
682   return is_ip4 ?
683     format (s, "%U", format_ip4_address, &ip46->ip4) :
684     format (s, "%U", format_ip6_address, &ip46->ip6);
685 }
686
687 u8 *
688 format_ethernet_address (u8 * s, va_list * args)
689 {
690   u8 *a = va_arg (*args, u8 *);
691
692   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
693                  a[0], a[1], a[2], a[3], a[4], a[5]);
694 }
695 #endif
696
697 static void
698 increment_v4_address (ip4_address_t * a)
699 {
700   u32 v;
701
702   v = ntohl (a->as_u32) + 1;
703   a->as_u32 = ntohl (v);
704 }
705
706 static void
707 increment_v6_address (ip6_address_t * a)
708 {
709   u64 v0, v1;
710
711   v0 = clib_net_to_host_u64 (a->as_u64[0]);
712   v1 = clib_net_to_host_u64 (a->as_u64[1]);
713
714   v1 += 1;
715   if (v1 == 0)
716     v0 += 1;
717   a->as_u64[0] = clib_net_to_host_u64 (v0);
718   a->as_u64[1] = clib_net_to_host_u64 (v1);
719 }
720
721 static void
722 increment_mac_address (u8 * mac)
723 {
724   u64 tmp = *((u64 *) mac);
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728
729   clib_memcpy (mac, &tmp, 6);
730 }
731
732 static void vl_api_create_loopback_reply_t_handler
733   (vl_api_create_loopback_reply_t * mp)
734 {
735   vat_main_t *vam = &vat_main;
736   i32 retval = ntohl (mp->retval);
737
738   vam->retval = retval;
739   vam->regenerate_interface_table = 1;
740   vam->sw_if_index = ntohl (mp->sw_if_index);
741   vam->result_ready = 1;
742 }
743
744 static void vl_api_create_loopback_reply_t_handler_json
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   vat_json_node_t node;
749
750   vat_json_init_object (&node);
751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
753
754   vat_json_print (vam->ofp, &node);
755   vat_json_free (&node);
756   vam->retval = ntohl (mp->retval);
757   vam->result_ready = 1;
758 }
759
760 static void vl_api_create_loopback_instance_reply_t_handler
761   (vl_api_create_loopback_instance_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler_json
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_af_packet_create_reply_t_handler
789   (vl_api_af_packet_create_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler_json
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_create_vlan_subif_reply_t_handler
818   (vl_api_create_vlan_subif_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler_json
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_subif_reply_t_handler
847   (vl_api_create_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler_json
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_interface_name_renumber_reply_t_handler
876   (vl_api_interface_name_renumber_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_interface_name_renumber_reply_t_handler_json
887   (vl_api_interface_name_renumber_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894
895   vat_json_print (vam->ofp, &node);
896   vat_json_free (&node);
897
898   vam->retval = ntohl (mp->retval);
899   vam->result_ready = 1;
900 }
901
902 /*
903  * Special-case: build the interface table, maintain
904  * the next loopback sw_if_index vbl.
905  */
906 static void vl_api_sw_interface_details_t_handler
907   (vl_api_sw_interface_details_t * mp)
908 {
909   vat_main_t *vam = &vat_main;
910   u8 *s = format (0, "%s%c", mp->interface_name, 0);
911
912   hash_set_mem (vam->sw_if_index_by_interface_name, s,
913                 ntohl (mp->sw_if_index));
914
915   /* In sub interface case, fill the sub interface table entry */
916   if (mp->sw_if_index != mp->sup_sw_if_index)
917     {
918       sw_interface_subif_t *sub = NULL;
919
920       vec_add2 (vam->sw_if_subif_table, sub, 1);
921
922       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
923       strncpy ((char *) sub->interface_name, (char *) s,
924                vec_len (sub->interface_name));
925       sub->sw_if_index = ntohl (mp->sw_if_index);
926       sub->sub_id = ntohl (mp->sub_id);
927
928       sub->sub_dot1ad = mp->sub_dot1ad;
929       sub->sub_number_of_tags = mp->sub_number_of_tags;
930       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
931       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
932       sub->sub_exact_match = mp->sub_exact_match;
933       sub->sub_default = mp->sub_default;
934       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
935       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
936
937       /* vlan tag rewrite */
938       sub->vtr_op = ntohl (mp->vtr_op);
939       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
940       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
941       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
942     }
943 }
944
945 static void vl_api_sw_interface_details_t_handler_json
946   (vl_api_sw_interface_details_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t *node = NULL;
950
951   if (VAT_JSON_ARRAY != vam->json_tree.type)
952     {
953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
954       vat_json_init_array (&vam->json_tree);
955     }
956   node = vat_json_array_add (&vam->json_tree);
957
958   vat_json_init_object (node);
959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
960   vat_json_object_add_uint (node, "sup_sw_if_index",
961                             ntohl (mp->sup_sw_if_index));
962   vat_json_object_add_uint (node, "l2_address_length",
963                             ntohl (mp->l2_address_length));
964   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
965                              sizeof (mp->l2_address));
966   vat_json_object_add_string_copy (node, "interface_name",
967                                    mp->interface_name);
968   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
969   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
970   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
971   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
972   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
973   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
974   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
975   vat_json_object_add_uint (node, "sub_number_of_tags",
976                             mp->sub_number_of_tags);
977   vat_json_object_add_uint (node, "sub_outer_vlan_id",
978                             ntohs (mp->sub_outer_vlan_id));
979   vat_json_object_add_uint (node, "sub_inner_vlan_id",
980                             ntohs (mp->sub_inner_vlan_id));
981   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
982   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
983   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
984                             mp->sub_outer_vlan_id_any);
985   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
986                             mp->sub_inner_vlan_id_any);
987   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
988   vat_json_object_add_uint (node, "vtr_push_dot1q",
989                             ntohl (mp->vtr_push_dot1q));
990   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
991   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
992   if (mp->sub_dot1ah)
993     {
994       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
995                                        format (0, "%U",
996                                                format_ethernet_address,
997                                                &mp->b_dmac));
998       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
999                                        format (0, "%U",
1000                                                format_ethernet_address,
1001                                                &mp->b_smac));
1002       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1003       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1004     }
1005 }
1006
1007 #if VPP_API_TEST_BUILTIN == 0
1008 static void vl_api_sw_interface_event_t_handler
1009   (vl_api_sw_interface_event_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   if (vam->interface_event_display)
1013     errmsg ("interface flags: sw_if_index %d %s %s",
1014             ntohl (mp->sw_if_index),
1015             mp->admin_up_down ? "admin-up" : "admin-down",
1016             mp->link_up_down ? "link-up" : "link-down");
1017 }
1018 #endif
1019
1020 static void vl_api_sw_interface_event_t_handler_json
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   /* JSON output not supported */
1024 }
1025
1026 static void
1027 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031
1032   vam->retval = retval;
1033   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void
1038 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   vat_json_node_t node;
1042   api_main_t *am = &api_main;
1043   void *oldheap;
1044   u8 *reply;
1045
1046   vat_json_init_object (&node);
1047   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1048   vat_json_object_add_uint (&node, "reply_in_shmem",
1049                             ntohl (mp->reply_in_shmem));
1050   /* Toss the shared-memory original... */
1051   pthread_mutex_lock (&am->vlib_rp->mutex);
1052   oldheap = svm_push_data_heap (am->vlib_rp);
1053
1054   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1055   vec_free (reply);
1056
1057   svm_pop_heap (oldheap);
1058   pthread_mutex_unlock (&am->vlib_rp->mutex);
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void
1068 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   u32 length = ntohl (mp->length);
1073
1074   vec_reset_length (vam->cmd_reply);
1075
1076   vam->retval = retval;
1077   if (retval == 0)
1078     {
1079       vec_validate (vam->cmd_reply, length);
1080       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void vl_api_classify_add_del_table_reply_t_handler
1106   (vl_api_classify_add_del_table_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   i32 retval = ntohl (mp->retval);
1110   if (vam->async_mode)
1111     {
1112       vam->async_errors += (retval < 0);
1113     }
1114   else
1115     {
1116       vam->retval = retval;
1117       if (retval == 0 &&
1118           ((mp->new_table_index != 0xFFFFFFFF) ||
1119            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1120            (mp->match_n_vectors != 0xFFFFFFFF)))
1121         /*
1122          * Note: this is just barely thread-safe, depends on
1123          * the main thread spinning waiting for an answer...
1124          */
1125         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1126                 ntohl (mp->new_table_index),
1127                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1128       vam->result_ready = 1;
1129     }
1130 }
1131
1132 static void vl_api_classify_add_del_table_reply_t_handler_json
1133   (vl_api_classify_add_del_table_reply_t * mp)
1134 {
1135   vat_main_t *vam = &vat_main;
1136   vat_json_node_t node;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "new_table_index",
1141                             ntohl (mp->new_table_index));
1142   vat_json_object_add_uint (&node, "skip_n_vectors",
1143                             ntohl (mp->skip_n_vectors));
1144   vat_json_object_add_uint (&node, "match_n_vectors",
1145                             ntohl (mp->match_n_vectors));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_get_node_index_reply_t_handler
1155   (vl_api_get_node_index_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("node index %d", ntohl (mp->node_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_get_node_index_reply_t_handler_json
1173   (vl_api_get_node_index_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_next_index_reply_t_handler
1190   (vl_api_get_next_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("next node index %d", ntohl (mp->next_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_next_index_reply_t_handler_json
1208   (vl_api_get_next_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_add_node_next_reply_t_handler
1225   (vl_api_add_node_next_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_add_node_next_reply_t_handler_json
1243   (vl_api_add_node_next_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_show_version_reply_t_handler
1260   (vl_api_show_version_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264
1265   if (retval >= 0)
1266     {
1267       errmsg ("        program: %s", mp->program);
1268       errmsg ("        version: %s", mp->version);
1269       errmsg ("     build date: %s", mp->build_date);
1270       errmsg ("build directory: %s", mp->build_directory);
1271     }
1272   vam->retval = retval;
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_show_version_reply_t_handler_json
1277   (vl_api_show_version_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_string_copy (&node, "program", mp->program);
1285   vat_json_object_add_string_copy (&node, "version", mp->version);
1286   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1287   vat_json_object_add_string_copy (&node, "build_directory",
1288                                    mp->build_directory);
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void
1298 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1299 {
1300   u32 sw_if_index = ntohl (mp->sw_if_index);
1301   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1302           mp->mac_ip ? "mac/ip binding" : "address resolution",
1303           ntohl (mp->pid), format_ip4_address, &mp->address,
1304           format_ethernet_address, mp->new_mac, sw_if_index);
1305 }
1306
1307 static void
1308 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1309 {
1310   /* JSON output not supported */
1311 }
1312
1313 static void
1314 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1315 {
1316   u32 sw_if_index = ntohl (mp->sw_if_index);
1317   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1318           mp->mac_ip ? "mac/ip binding" : "address resolution",
1319           ntohl (mp->pid), format_ip6_address, mp->address,
1320           format_ethernet_address, mp->new_mac, sw_if_index);
1321 }
1322
1323 static void
1324 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1325 {
1326   /* JSON output not supported */
1327 }
1328
1329 static void
1330 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1331 {
1332   u32 n_macs = ntohl (mp->n_macs);
1333   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1334           ntohl (mp->pid), mp->client_index, n_macs);
1335   int i;
1336   for (i = 0; i < n_macs; i++)
1337     {
1338       vl_api_mac_entry_t *mac = &mp->mac[i];
1339       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1340               i + 1, ntohl (mac->sw_if_index),
1341               format_ethernet_address, mac->mac_addr, mac->is_del);
1342       if (i == 1000)
1343         break;
1344     }
1345 }
1346
1347 static void
1348 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1349 {
1350   /* JSON output not supported */
1351 }
1352
1353 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1354 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1355
1356 /*
1357  * Special-case: build the bridge domain table, maintain
1358  * the next bd id vbl.
1359  */
1360 static void vl_api_bridge_domain_details_t_handler
1361   (vl_api_bridge_domain_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1365   int i;
1366
1367   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1368          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1369
1370   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1371          ntohl (mp->bd_id), mp->learn, mp->forward,
1372          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1373
1374   if (n_sw_ifs)
1375     {
1376       vl_api_bridge_domain_sw_if_t *sw_ifs;
1377       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1378              "Interface Name");
1379
1380       sw_ifs = mp->sw_if_details;
1381       for (i = 0; i < n_sw_ifs; i++)
1382         {
1383           u8 *sw_if_name = 0;
1384           u32 sw_if_index;
1385           hash_pair_t *p;
1386
1387           sw_if_index = ntohl (sw_ifs->sw_if_index);
1388
1389           /* *INDENT-OFF* */
1390           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1391                              ({
1392                                if ((u32) p->value[0] == sw_if_index)
1393                                  {
1394                                    sw_if_name = (u8 *)(p->key);
1395                                    break;
1396                                  }
1397                              }));
1398           /* *INDENT-ON* */
1399           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1400                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1401                  "sw_if_index not found!");
1402
1403           sw_ifs++;
1404         }
1405     }
1406 }
1407
1408 static void vl_api_bridge_domain_details_t_handler_json
1409   (vl_api_bridge_domain_details_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t *node, *array = NULL;
1413   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1414
1415   if (VAT_JSON_ARRAY != vam->json_tree.type)
1416     {
1417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1418       vat_json_init_array (&vam->json_tree);
1419     }
1420   node = vat_json_array_add (&vam->json_tree);
1421
1422   vat_json_init_object (node);
1423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1424   vat_json_object_add_uint (node, "flood", mp->flood);
1425   vat_json_object_add_uint (node, "forward", mp->forward);
1426   vat_json_object_add_uint (node, "learn", mp->learn);
1427   vat_json_object_add_uint (node, "bvi_sw_if_index",
1428                             ntohl (mp->bvi_sw_if_index));
1429   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1430   array = vat_json_object_add (node, "sw_if");
1431   vat_json_init_array (array);
1432
1433
1434
1435   if (n_sw_ifs)
1436     {
1437       vl_api_bridge_domain_sw_if_t *sw_ifs;
1438       int i;
1439
1440       sw_ifs = mp->sw_if_details;
1441       for (i = 0; i < n_sw_ifs; i++)
1442         {
1443           node = vat_json_array_add (array);
1444           vat_json_init_object (node);
1445           vat_json_object_add_uint (node, "sw_if_index",
1446                                     ntohl (sw_ifs->sw_if_index));
1447           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1448           sw_ifs++;
1449         }
1450     }
1451 }
1452
1453 static void vl_api_control_ping_reply_t_handler
1454   (vl_api_control_ping_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467   vam->socket_client_main.control_pings_outstanding--;
1468 }
1469
1470 static void vl_api_control_ping_reply_t_handler_json
1471   (vl_api_control_ping_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   i32 retval = ntohl (mp->retval);
1475
1476   if (VAT_JSON_NONE != vam->json_tree.type)
1477     {
1478       vat_json_print (vam->ofp, &vam->json_tree);
1479       vat_json_free (&vam->json_tree);
1480       vam->json_tree.type = VAT_JSON_NONE;
1481     }
1482   else
1483     {
1484       /* just print [] */
1485       vat_json_init_array (&vam->json_tree);
1486       vat_json_print (vam->ofp, &vam->json_tree);
1487       vam->json_tree.type = VAT_JSON_NONE;
1488     }
1489
1490   vam->retval = retval;
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495   vl_api_bridge_domain_set_mac_age_reply_t_handler
1496   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1512   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void
1528 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->result_ready = 1;
1540     }
1541 }
1542
1543 static void vl_api_l2_flags_reply_t_handler_json
1544   (vl_api_l2_flags_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t node;
1548
1549   vat_json_init_object (&node);
1550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1551   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1552                             ntohl (mp->resulting_feature_bitmap));
1553
1554   vat_json_print (vam->ofp, &node);
1555   vat_json_free (&node);
1556
1557   vam->retval = ntohl (mp->retval);
1558   vam->result_ready = 1;
1559 }
1560
1561 static void vl_api_bridge_flags_reply_t_handler
1562   (vl_api_bridge_flags_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   i32 retval = ntohl (mp->retval);
1566   if (vam->async_mode)
1567     {
1568       vam->async_errors += (retval < 0);
1569     }
1570   else
1571     {
1572       vam->retval = retval;
1573       vam->result_ready = 1;
1574     }
1575 }
1576
1577 static void vl_api_bridge_flags_reply_t_handler_json
1578   (vl_api_bridge_flags_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   vat_json_node_t node;
1582
1583   vat_json_init_object (&node);
1584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1585   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1586                             ntohl (mp->resulting_feature_bitmap));
1587
1588   vat_json_print (vam->ofp, &node);
1589   vat_json_free (&node);
1590
1591   vam->retval = ntohl (mp->retval);
1592   vam->result_ready = 1;
1593 }
1594
1595 static void vl_api_tap_connect_reply_t_handler
1596   (vl_api_tap_connect_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->sw_if_index = ntohl (mp->sw_if_index);
1608       vam->result_ready = 1;
1609     }
1610
1611 }
1612
1613 static void vl_api_tap_connect_reply_t_handler_json
1614   (vl_api_tap_connect_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628
1629 }
1630
1631 static void
1632 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->sw_if_index = ntohl (mp->sw_if_index);
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_modify_reply_t_handler_json
1649   (vl_api_tap_modify_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_tap_delete_reply_t_handler_json
1682   (vl_api_tap_delete_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void
1698 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->sw_if_index = ntohl (mp->sw_if_index);
1710       vam->result_ready = 1;
1711     }
1712
1713 }
1714
1715 static void vl_api_tap_create_v2_reply_t_handler_json
1716   (vl_api_tap_create_v2_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730
1731 }
1732
1733 static void
1734 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_delete_v2_reply_t_handler_json
1750   (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1766   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1782   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1790                             ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1800   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1817   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1834   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1850   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "fwd_entry_index",
1858                             clib_net_to_host_u32 (mp->fwd_entry_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 u8 *
1868 format_lisp_transport_protocol (u8 * s, va_list * args)
1869 {
1870   u32 proto = va_arg (*args, u32);
1871
1872   switch (proto)
1873     {
1874     case 1:
1875       return format (s, "udp");
1876     case 2:
1877       return format (s, "api");
1878     default:
1879       return 0;
1880     }
1881   return 0;
1882 }
1883
1884 static void vl_api_one_get_transport_protocol_reply_t_handler
1885   (vl_api_one_get_transport_protocol_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   i32 retval = ntohl (mp->retval);
1889   if (vam->async_mode)
1890     {
1891       vam->async_errors += (retval < 0);
1892     }
1893   else
1894     {
1895       u32 proto = mp->protocol;
1896       print (vam->ofp, "Transport protocol: %U",
1897              format_lisp_transport_protocol, proto);
1898       vam->retval = retval;
1899       vam->result_ready = 1;
1900     }
1901 }
1902
1903 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1904   (vl_api_one_get_transport_protocol_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   vat_json_node_t node;
1908   u8 *s;
1909
1910   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1911   vec_add1 (s, 0);
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1916
1917   vec_free (s);
1918   vat_json_print (vam->ofp, &node);
1919   vat_json_free (&node);
1920
1921   vam->retval = ntohl (mp->retval);
1922   vam->result_ready = 1;
1923 }
1924
1925 static void vl_api_one_add_del_locator_set_reply_t_handler
1926   (vl_api_one_add_del_locator_set_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   i32 retval = ntohl (mp->retval);
1930   if (vam->async_mode)
1931     {
1932       vam->async_errors += (retval < 0);
1933     }
1934   else
1935     {
1936       vam->retval = retval;
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1942   (vl_api_one_add_del_locator_set_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   vat_json_node_t node;
1946
1947   vat_json_init_object (&node);
1948   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1949   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1950
1951   vat_json_print (vam->ofp, &node);
1952   vat_json_free (&node);
1953
1954   vam->retval = ntohl (mp->retval);
1955   vam->result_ready = 1;
1956 }
1957
1958 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   i32 retval = ntohl (mp->retval);
1963   if (vam->async_mode)
1964     {
1965       vam->async_errors += (retval < 0);
1966     }
1967   else
1968     {
1969       vam->retval = retval;
1970       vam->sw_if_index = ntohl (mp->sw_if_index);
1971       vam->result_ready = 1;
1972     }
1973 }
1974
1975 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   vat_json_node_t node;
1980
1981   vat_json_init_object (&node);
1982   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1983   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1984
1985   vat_json_print (vam->ofp, &node);
1986   vat_json_free (&node);
1987
1988   vam->retval = ntohl (mp->retval);
1989   vam->result_ready = 1;
1990 }
1991
1992 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1993   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   i32 retval = ntohl (mp->retval);
1997   if (vam->async_mode)
1998     {
1999       vam->async_errors += (retval < 0);
2000     }
2001   else
2002     {
2003       vam->retval = retval;
2004       vam->sw_if_index = ntohl (mp->sw_if_index);
2005       vam->result_ready = 1;
2006     }
2007 }
2008
2009 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2010   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t node;
2014
2015   vat_json_init_object (&node);
2016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2017   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2018
2019   vat_json_print (vam->ofp, &node);
2020   vat_json_free (&node);
2021
2022   vam->retval = ntohl (mp->retval);
2023   vam->result_ready = 1;
2024 }
2025
2026 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2027   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   i32 retval = ntohl (mp->retval);
2031   if (vam->async_mode)
2032     {
2033       vam->async_errors += (retval < 0);
2034     }
2035   else
2036     {
2037       vam->retval = retval;
2038       vam->sw_if_index = ntohl (mp->sw_if_index);
2039       vam->result_ready = 1;
2040     }
2041 }
2042
2043 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2044   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vat_json_node_t node;
2048
2049   vat_json_init_object (&node);
2050   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2051   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2052
2053   vat_json_print (vam->ofp, &node);
2054   vat_json_free (&node);
2055
2056   vam->retval = ntohl (mp->retval);
2057   vam->result_ready = 1;
2058 }
2059
2060 static void vl_api_gre_add_del_tunnel_reply_t_handler
2061   (vl_api_gre_add_del_tunnel_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->sw_if_index = ntohl (mp->sw_if_index);
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2078   (vl_api_gre_add_del_tunnel_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_create_vhost_user_if_reply_t_handler
2095   (vl_api_create_vhost_user_if_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_create_vhost_user_if_reply_t_handler_json
2112   (vl_api_create_vhost_user_if_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static clib_error_t *
2129 receive_fd_msg (int socket_fd, int *my_fd)
2130 {
2131   char msgbuf[16];
2132   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2133   struct msghdr mh = { 0 };
2134   struct iovec iov[1];
2135   ssize_t size;
2136   struct ucred *cr = 0;
2137   struct cmsghdr *cmsg;
2138   pid_t pid __attribute__ ((unused));
2139   uid_t uid __attribute__ ((unused));
2140   gid_t gid __attribute__ ((unused));
2141
2142   iov[0].iov_base = msgbuf;
2143   iov[0].iov_len = 5;
2144   mh.msg_iov = iov;
2145   mh.msg_iovlen = 1;
2146   mh.msg_control = ctl;
2147   mh.msg_controllen = sizeof (ctl);
2148
2149   memset (ctl, 0, sizeof (ctl));
2150
2151   /* receive the incoming message */
2152   size = recvmsg (socket_fd, &mh, 0);
2153   if (size != 5)
2154     {
2155       return (size == 0) ? clib_error_return (0, "disconnected") :
2156         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2157                                 socket_fd);
2158     }
2159
2160   cmsg = CMSG_FIRSTHDR (&mh);
2161   while (cmsg)
2162     {
2163       if (cmsg->cmsg_level == SOL_SOCKET)
2164         {
2165           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2166             {
2167               cr = (struct ucred *) CMSG_DATA (cmsg);
2168               uid = cr->uid;
2169               gid = cr->gid;
2170               pid = cr->pid;
2171             }
2172           else if (cmsg->cmsg_type == SCM_RIGHTS)
2173             {
2174               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2175             }
2176         }
2177       cmsg = CMSG_NXTHDR (&mh, cmsg);
2178     }
2179   return 0;
2180 }
2181
2182 static void vl_api_memfd_segment_create_reply_t_handler
2183   (vl_api_memfd_segment_create_reply_t * mp)
2184 {
2185   /* Dont bother in the builtin version */
2186 #if VPP_API_TEST_BUILTIN == 0
2187   vat_main_t *vam = &vat_main;
2188   api_main_t *am = &api_main;
2189   socket_client_main_t *scm = &vam->socket_client_main;
2190   int my_fd = -1;
2191   clib_error_t *error;
2192   memfd_private_t memfd;
2193   i32 retval = ntohl (mp->retval);
2194
2195   if (retval == 0)
2196     {
2197       error = receive_fd_msg (scm->socket_fd, &my_fd);
2198       if (error)
2199         {
2200           retval = -99;
2201           goto out;
2202         }
2203
2204       memset (&memfd, 0, sizeof (memfd));
2205       memfd.fd = my_fd;
2206
2207       vam->client_index_invalid = 1;
2208
2209       /* Note: this closes memfd.fd */
2210       retval = memfd_slave_init (&memfd);
2211       if (retval)
2212         clib_warning ("WARNING: segment map returned %d", retval);
2213
2214       /* Pivot to the memory client segment that vpp just created */
2215
2216       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2217
2218       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2219
2220       vl_client_install_client_message_handlers ();
2221
2222       vl_client_connect_to_vlib_no_map ("pvt",
2223                                         "vpp_api_test(p)",
2224                                         32 /* input_queue_length */ );
2225       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2226
2227       vl_socket_client_enable_disable (&vam->socket_client_main,
2228                                        0 /* disable socket */ );
2229     }
2230
2231 out:
2232   if (vam->async_mode)
2233     {
2234       vam->async_errors += (retval < 0);
2235     }
2236   else
2237     {
2238       vam->retval = retval;
2239       vam->result_ready = 1;
2240     }
2241 #endif
2242 }
2243
2244 static void vl_api_memfd_segment_create_reply_t_handler_json
2245   (vl_api_memfd_segment_create_reply_t * mp)
2246 {
2247   clib_warning ("no");
2248 }
2249
2250 static void vl_api_dns_resolve_name_reply_t_handler
2251   (vl_api_dns_resolve_name_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263
2264       if (retval == 0)
2265         {
2266           if (mp->ip4_set)
2267             clib_warning ("ip4 address %U", format_ip4_address,
2268                           (ip4_address_t *) mp->ip4_address);
2269           if (mp->ip6_set)
2270             clib_warning ("ip6 address %U", format_ip6_address,
2271                           (ip6_address_t *) mp->ip6_address);
2272         }
2273       else
2274         clib_warning ("retval %d", retval);
2275     }
2276 }
2277
2278 static void vl_api_dns_resolve_name_reply_t_handler_json
2279   (vl_api_dns_resolve_name_reply_t * mp)
2280 {
2281   clib_warning ("not implemented");
2282 }
2283
2284 static void vl_api_dns_resolve_ip_reply_t_handler
2285   (vl_api_dns_resolve_ip_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   i32 retval = ntohl (mp->retval);
2289   if (vam->async_mode)
2290     {
2291       vam->async_errors += (retval < 0);
2292     }
2293   else
2294     {
2295       vam->retval = retval;
2296       vam->result_ready = 1;
2297
2298       if (retval == 0)
2299         {
2300           clib_warning ("canonical name %s", mp->name);
2301         }
2302       else
2303         clib_warning ("retval %d", retval);
2304     }
2305 }
2306
2307 static void vl_api_dns_resolve_ip_reply_t_handler_json
2308   (vl_api_dns_resolve_ip_reply_t * mp)
2309 {
2310   clib_warning ("not implemented");
2311 }
2312
2313
2314 static void vl_api_ip_address_details_t_handler
2315   (vl_api_ip_address_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   static ip_address_details_t empty_ip_address_details = { {0} };
2319   ip_address_details_t *address = NULL;
2320   ip_details_t *current_ip_details = NULL;
2321   ip_details_t *details = NULL;
2322
2323   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2324
2325   if (!details || vam->current_sw_if_index >= vec_len (details)
2326       || !details[vam->current_sw_if_index].present)
2327     {
2328       errmsg ("ip address details arrived but not stored");
2329       errmsg ("ip_dump should be called first");
2330       return;
2331     }
2332
2333   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2334
2335 #define addresses (current_ip_details->addr)
2336
2337   vec_validate_init_empty (addresses, vec_len (addresses),
2338                            empty_ip_address_details);
2339
2340   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2341
2342   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2343   address->prefix_length = mp->prefix_length;
2344 #undef addresses
2345 }
2346
2347 static void vl_api_ip_address_details_t_handler_json
2348   (vl_api_ip_address_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   vat_json_node_t *node = NULL;
2352   struct in6_addr ip6;
2353   struct in_addr ip4;
2354
2355   if (VAT_JSON_ARRAY != vam->json_tree.type)
2356     {
2357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2358       vat_json_init_array (&vam->json_tree);
2359     }
2360   node = vat_json_array_add (&vam->json_tree);
2361
2362   vat_json_init_object (node);
2363   if (vam->is_ipv6)
2364     {
2365       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2366       vat_json_object_add_ip6 (node, "ip", ip6);
2367     }
2368   else
2369     {
2370       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2371       vat_json_object_add_ip4 (node, "ip", ip4);
2372     }
2373   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2374 }
2375
2376 static void
2377 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   static ip_details_t empty_ip_details = { 0 };
2381   ip_details_t *ip = NULL;
2382   u32 sw_if_index = ~0;
2383
2384   sw_if_index = ntohl (mp->sw_if_index);
2385
2386   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2387                            sw_if_index, empty_ip_details);
2388
2389   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2390                          sw_if_index);
2391
2392   ip->present = 1;
2393 }
2394
2395 static void
2396 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   if (VAT_JSON_ARRAY != vam->json_tree.type)
2401     {
2402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2403       vat_json_init_array (&vam->json_tree);
2404     }
2405   vat_json_array_add_uint (&vam->json_tree,
2406                            clib_net_to_host_u32 (mp->sw_if_index));
2407 }
2408
2409 static void vl_api_map_domain_details_t_handler_json
2410   (vl_api_map_domain_details_t * mp)
2411 {
2412   vat_json_node_t *node = NULL;
2413   vat_main_t *vam = &vat_main;
2414   struct in6_addr ip6;
2415   struct in_addr ip4;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422
2423   node = vat_json_array_add (&vam->json_tree);
2424   vat_json_init_object (node);
2425
2426   vat_json_object_add_uint (node, "domain_index",
2427                             clib_net_to_host_u32 (mp->domain_index));
2428   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2429   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2430   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2431   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2432   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2433   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2434   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2435   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2436   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2437   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2438   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2439   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2440   vat_json_object_add_uint (node, "flags", mp->flags);
2441   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2442   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2443 }
2444
2445 static void vl_api_map_domain_details_t_handler
2446   (vl_api_map_domain_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   if (mp->is_translation)
2451     {
2452       print (vam->ofp,
2453              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2454              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2455              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2456              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2457              clib_net_to_host_u32 (mp->domain_index));
2458     }
2459   else
2460     {
2461       print (vam->ofp,
2462              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2463              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2464              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2465              format_ip6_address, mp->ip6_src,
2466              clib_net_to_host_u32 (mp->domain_index));
2467     }
2468   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2469          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2470          mp->is_translation ? "map-t" : "");
2471 }
2472
2473 static void vl_api_map_rule_details_t_handler_json
2474   (vl_api_map_rule_details_t * mp)
2475 {
2476   struct in6_addr ip6;
2477   vat_json_node_t *node = NULL;
2478   vat_main_t *vam = &vat_main;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485
2486   node = vat_json_array_add (&vam->json_tree);
2487   vat_json_init_object (node);
2488
2489   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2490   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2491   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2492 }
2493
2494 static void
2495 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2499          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2500 }
2501
2502 static void
2503 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2504 {
2505   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2506           "router_addr %U host_mac %U",
2507           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2508           format_ip4_address, &mp->host_address,
2509           format_ip4_address, &mp->router_address,
2510           format_ethernet_address, mp->host_mac);
2511 }
2512
2513 static void vl_api_dhcp_compl_event_t_handler_json
2514   (vl_api_dhcp_compl_event_t * mp)
2515 {
2516   /* JSON output not supported */
2517 }
2518
2519 static void
2520 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2521                               u32 counter)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   static u64 default_counter = 0;
2525
2526   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2527                            NULL);
2528   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2529                            sw_if_index, default_counter);
2530   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2531 }
2532
2533 static void
2534 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2535                                 interface_counter_t counter)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   static interface_counter_t default_counter = { 0, };
2539
2540   vec_validate_init_empty (vam->combined_interface_counters,
2541                            vnet_counter_type, NULL);
2542   vec_validate_init_empty (vam->combined_interface_counters
2543                            [vnet_counter_type], sw_if_index, default_counter);
2544   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2545 }
2546
2547 static void vl_api_vnet_interface_simple_counters_t_handler
2548   (vl_api_vnet_interface_simple_counters_t * mp)
2549 {
2550   /* not supported */
2551 }
2552
2553 static void vl_api_vnet_interface_combined_counters_t_handler
2554   (vl_api_vnet_interface_combined_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler_json
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   u64 *v_packets;
2563   u64 packets;
2564   u32 count;
2565   u32 first_sw_if_index;
2566   int i;
2567
2568   count = ntohl (mp->count);
2569   first_sw_if_index = ntohl (mp->first_sw_if_index);
2570
2571   v_packets = (u64 *) & mp->data;
2572   for (i = 0; i < count; i++)
2573     {
2574       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2575       set_simple_interface_counter (mp->vnet_counter_type,
2576                                     first_sw_if_index + i, packets);
2577       v_packets++;
2578     }
2579 }
2580
2581 static void vl_api_vnet_interface_combined_counters_t_handler_json
2582   (vl_api_vnet_interface_combined_counters_t * mp)
2583 {
2584   interface_counter_t counter;
2585   vlib_counter_t *v;
2586   u32 first_sw_if_index;
2587   int i;
2588   u32 count;
2589
2590   count = ntohl (mp->count);
2591   first_sw_if_index = ntohl (mp->first_sw_if_index);
2592
2593   v = (vlib_counter_t *) & mp->data;
2594   for (i = 0; i < count; i++)
2595     {
2596       counter.packets =
2597         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2598       counter.bytes =
2599         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2600       set_combined_interface_counter (mp->vnet_counter_type,
2601                                       first_sw_if_index + i, counter);
2602       v++;
2603     }
2604 }
2605
2606 static u32
2607 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i;
2611
2612   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2613     {
2614       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2615         {
2616           return i;
2617         }
2618     }
2619   return ~0;
2620 }
2621
2622 static u32
2623 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static void vl_api_vnet_ip4_fib_counters_t_handler
2639   (vl_api_vnet_ip4_fib_counters_t * mp)
2640 {
2641   /* not supported */
2642 }
2643
2644 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2645   (vl_api_vnet_ip4_fib_counters_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vl_api_ip4_fib_counter_t *v;
2649   ip4_fib_counter_t *counter;
2650   struct in_addr ip4;
2651   u32 vrf_id;
2652   u32 vrf_index;
2653   u32 count;
2654   int i;
2655
2656   vrf_id = ntohl (mp->vrf_id);
2657   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2658   if (~0 == vrf_index)
2659     {
2660       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2661       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2662       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2663       vec_validate (vam->ip4_fib_counters, vrf_index);
2664       vam->ip4_fib_counters[vrf_index] = NULL;
2665     }
2666
2667   vec_free (vam->ip4_fib_counters[vrf_index]);
2668   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2669   count = ntohl (mp->count);
2670   for (i = 0; i < count; i++)
2671     {
2672       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2673       counter = &vam->ip4_fib_counters[vrf_index][i];
2674       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2675       counter->address = ip4;
2676       counter->address_length = v->address_length;
2677       counter->packets = clib_net_to_host_u64 (v->packets);
2678       counter->bytes = clib_net_to_host_u64 (v->bytes);
2679       v++;
2680     }
2681 }
2682
2683 static void vl_api_vnet_ip4_nbr_counters_t_handler
2684   (vl_api_vnet_ip4_nbr_counters_t * mp)
2685 {
2686   /* not supported */
2687 }
2688
2689 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2690   (vl_api_vnet_ip4_nbr_counters_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vl_api_ip4_nbr_counter_t *v;
2694   ip4_nbr_counter_t *counter;
2695   u32 sw_if_index;
2696   u32 count;
2697   int i;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700   count = ntohl (mp->count);
2701   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2702
2703   if (mp->begin)
2704     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2705
2706   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2707   for (i = 0; i < count; i++)
2708     {
2709       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2710       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2711       counter->address.s_addr = v->address;
2712       counter->packets = clib_net_to_host_u64 (v->packets);
2713       counter->bytes = clib_net_to_host_u64 (v->bytes);
2714       counter->linkt = v->link_type;
2715       v++;
2716     }
2717 }
2718
2719 static void vl_api_vnet_ip6_fib_counters_t_handler
2720   (vl_api_vnet_ip6_fib_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2726   (vl_api_vnet_ip6_fib_counters_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   vl_api_ip6_fib_counter_t *v;
2730   ip6_fib_counter_t *counter;
2731   struct in6_addr ip6;
2732   u32 vrf_id;
2733   u32 vrf_index;
2734   u32 count;
2735   int i;
2736
2737   vrf_id = ntohl (mp->vrf_id);
2738   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2739   if (~0 == vrf_index)
2740     {
2741       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2742       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2743       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2744       vec_validate (vam->ip6_fib_counters, vrf_index);
2745       vam->ip6_fib_counters[vrf_index] = NULL;
2746     }
2747
2748   vec_free (vam->ip6_fib_counters[vrf_index]);
2749   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2750   count = ntohl (mp->count);
2751   for (i = 0; i < count; i++)
2752     {
2753       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2754       counter = &vam->ip6_fib_counters[vrf_index][i];
2755       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2756       counter->address = ip6;
2757       counter->address_length = v->address_length;
2758       counter->packets = clib_net_to_host_u64 (v->packets);
2759       counter->bytes = clib_net_to_host_u64 (v->bytes);
2760       v++;
2761     }
2762 }
2763
2764 static void vl_api_vnet_ip6_nbr_counters_t_handler
2765   (vl_api_vnet_ip6_nbr_counters_t * mp)
2766 {
2767   /* not supported */
2768 }
2769
2770 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2771   (vl_api_vnet_ip6_nbr_counters_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vl_api_ip6_nbr_counter_t *v;
2775   ip6_nbr_counter_t *counter;
2776   struct in6_addr ip6;
2777   u32 sw_if_index;
2778   u32 count;
2779   int i;
2780
2781   sw_if_index = ntohl (mp->sw_if_index);
2782   count = ntohl (mp->count);
2783   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2784
2785   if (mp->begin)
2786     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2787
2788   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2789   for (i = 0; i < count; i++)
2790     {
2791       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2792       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2793       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2794       counter->address = ip6;
2795       counter->packets = clib_net_to_host_u64 (v->packets);
2796       counter->bytes = clib_net_to_host_u64 (v->bytes);
2797       v++;
2798     }
2799 }
2800
2801 static void vl_api_get_first_msg_id_reply_t_handler
2802   (vl_api_get_first_msg_id_reply_t * mp)
2803 {
2804   vat_main_t *vam = &vat_main;
2805   i32 retval = ntohl (mp->retval);
2806
2807   if (vam->async_mode)
2808     {
2809       vam->async_errors += (retval < 0);
2810     }
2811   else
2812     {
2813       vam->retval = retval;
2814       vam->result_ready = 1;
2815     }
2816   if (retval >= 0)
2817     {
2818       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2819     }
2820 }
2821
2822 static void vl_api_get_first_msg_id_reply_t_handler_json
2823   (vl_api_get_first_msg_id_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t node;
2827
2828   vat_json_init_object (&node);
2829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2830   vat_json_object_add_uint (&node, "first_msg_id",
2831                             (uint) ntohs (mp->first_msg_id));
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void vl_api_get_node_graph_reply_t_handler
2841   (vl_api_get_node_graph_reply_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   api_main_t *am = &api_main;
2845   i32 retval = ntohl (mp->retval);
2846   u8 *pvt_copy, *reply;
2847   void *oldheap;
2848   vlib_node_t *node;
2849   int i;
2850
2851   if (vam->async_mode)
2852     {
2853       vam->async_errors += (retval < 0);
2854     }
2855   else
2856     {
2857       vam->retval = retval;
2858       vam->result_ready = 1;
2859     }
2860
2861   /* "Should never happen..." */
2862   if (retval != 0)
2863     return;
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866   pvt_copy = vec_dup (reply);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   if (vam->graph_nodes)
2878     {
2879       hash_free (vam->graph_node_index_by_name);
2880
2881       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2882         {
2883           node = vam->graph_nodes[i];
2884           vec_free (node->name);
2885           vec_free (node->next_nodes);
2886           vec_free (node);
2887         }
2888       vec_free (vam->graph_nodes);
2889     }
2890
2891   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2892   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2893   vec_free (pvt_copy);
2894
2895   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2896     {
2897       node = vam->graph_nodes[i];
2898       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2899     }
2900 }
2901
2902 static void vl_api_get_node_graph_reply_t_handler_json
2903   (vl_api_get_node_graph_reply_t * mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   api_main_t *am = &api_main;
2907   void *oldheap;
2908   vat_json_node_t node;
2909   u8 *reply;
2910
2911   /* $$$$ make this real? */
2912   vat_json_init_object (&node);
2913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2914   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2915
2916   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2917
2918   /* Toss the shared-memory original... */
2919   pthread_mutex_lock (&am->vlib_rp->mutex);
2920   oldheap = svm_push_data_heap (am->vlib_rp);
2921
2922   vec_free (reply);
2923
2924   svm_pop_heap (oldheap);
2925   pthread_mutex_unlock (&am->vlib_rp->mutex);
2926
2927   vat_json_print (vam->ofp, &node);
2928   vat_json_free (&node);
2929
2930   vam->retval = ntohl (mp->retval);
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   u8 *s = 0;
2939
2940   if (mp->local)
2941     {
2942       s = format (s, "%=16d%=16d%=16d",
2943                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2944     }
2945   else
2946     {
2947       s = format (s, "%=16U%=16d%=16d",
2948                   mp->is_ipv6 ? format_ip6_address :
2949                   format_ip4_address,
2950                   mp->ip_address, mp->priority, mp->weight);
2951     }
2952
2953   print (vam->ofp, "%v", s);
2954   vec_free (s);
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = NULL;
2962   struct in6_addr ip6;
2963   struct in_addr ip4;
2964
2965   if (VAT_JSON_ARRAY != vam->json_tree.type)
2966     {
2967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2968       vat_json_init_array (&vam->json_tree);
2969     }
2970   node = vat_json_array_add (&vam->json_tree);
2971   vat_json_init_object (node);
2972
2973   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2974   vat_json_object_add_uint (node, "priority", mp->priority);
2975   vat_json_object_add_uint (node, "weight", mp->weight);
2976
2977   if (mp->local)
2978     vat_json_object_add_uint (node, "sw_if_index",
2979                               clib_net_to_host_u32 (mp->sw_if_index));
2980   else
2981     {
2982       if (mp->is_ipv6)
2983         {
2984           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2985           vat_json_object_add_ip6 (node, "address", ip6);
2986         }
2987       else
2988         {
2989           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2990           vat_json_object_add_ip4 (node, "address", ip4);
2991         }
2992     }
2993 }
2994
2995 static void
2996 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2997                                           mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   u8 *ls_name = 0;
3001
3002   ls_name = format (0, "%s", mp->ls_name);
3003
3004   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3005          ls_name);
3006   vec_free (ls_name);
3007 }
3008
3009 static void
3010   vl_api_one_locator_set_details_t_handler_json
3011   (vl_api_one_locator_set_details_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t *node = 0;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018   vec_add1 (ls_name, 0);
3019
3020   if (VAT_JSON_ARRAY != vam->json_tree.type)
3021     {
3022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3023       vat_json_init_array (&vam->json_tree);
3024     }
3025   node = vat_json_array_add (&vam->json_tree);
3026
3027   vat_json_init_object (node);
3028   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3029   vat_json_object_add_uint (node, "ls_index",
3030                             clib_net_to_host_u32 (mp->ls_index));
3031   vec_free (ls_name);
3032 }
3033
3034 typedef struct
3035 {
3036   u32 spi;
3037   u8 si;
3038 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3039
3040 uword
3041 unformat_nsh_address (unformat_input_t * input, va_list * args)
3042 {
3043   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3044   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3045 }
3046
3047 u8 *
3048 format_nsh_address_vat (u8 * s, va_list * args)
3049 {
3050   nsh_t *a = va_arg (*args, nsh_t *);
3051   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3052 }
3053
3054 static u8 *
3055 format_lisp_flat_eid (u8 * s, va_list * args)
3056 {
3057   u32 type = va_arg (*args, u32);
3058   u8 *eid = va_arg (*args, u8 *);
3059   u32 eid_len = va_arg (*args, u32);
3060
3061   switch (type)
3062     {
3063     case 0:
3064       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3065     case 1:
3066       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3067     case 2:
3068       return format (s, "%U", format_ethernet_address, eid);
3069     case 3:
3070       return format (s, "%U", format_nsh_address_vat, eid);
3071     }
3072   return 0;
3073 }
3074
3075 static u8 *
3076 format_lisp_eid_vat (u8 * s, va_list * args)
3077 {
3078   u32 type = va_arg (*args, u32);
3079   u8 *eid = va_arg (*args, u8 *);
3080   u32 eid_len = va_arg (*args, u32);
3081   u8 *seid = va_arg (*args, u8 *);
3082   u32 seid_len = va_arg (*args, u32);
3083   u32 is_src_dst = va_arg (*args, u32);
3084
3085   if (is_src_dst)
3086     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3087
3088   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3089
3090   return s;
3091 }
3092
3093 static void
3094 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   u8 *s = 0, *eid = 0;
3098
3099   if (~0 == mp->locator_set_index)
3100     s = format (0, "action: %d", mp->action);
3101   else
3102     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3103
3104   eid = format (0, "%U", format_lisp_eid_vat,
3105                 mp->eid_type,
3106                 mp->eid,
3107                 mp->eid_prefix_len,
3108                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109   vec_add1 (eid, 0);
3110
3111   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3112          clib_net_to_host_u32 (mp->vni),
3113          eid,
3114          mp->is_local ? "local" : "remote",
3115          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3116          clib_net_to_host_u16 (mp->key_id), mp->key);
3117
3118   vec_free (s);
3119   vec_free (eid);
3120 }
3121
3122 static void
3123 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3124                                              * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = 0;
3128   u8 *eid = 0;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136
3137   vat_json_init_object (node);
3138   if (~0 == mp->locator_set_index)
3139     vat_json_object_add_uint (node, "action", mp->action);
3140   else
3141     vat_json_object_add_uint (node, "locator_set_index",
3142                               clib_net_to_host_u32 (mp->locator_set_index));
3143
3144   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3145   if (mp->eid_type == 3)
3146     {
3147       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3148       vat_json_init_object (nsh_json);
3149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3150       vat_json_object_add_uint (nsh_json, "spi",
3151                                 clib_net_to_host_u32 (nsh->spi));
3152       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3153     }
3154   else
3155     {
3156       eid = format (0, "%U", format_lisp_eid_vat,
3157                     mp->eid_type,
3158                     mp->eid,
3159                     mp->eid_prefix_len,
3160                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3161       vec_add1 (eid, 0);
3162       vat_json_object_add_string_copy (node, "eid", eid);
3163       vec_free (eid);
3164     }
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3167   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3168
3169   if (mp->key_id)
3170     {
3171       vat_json_object_add_uint (node, "key_id",
3172                                 clib_net_to_host_u16 (mp->key_id));
3173       vat_json_object_add_string_copy (node, "key", mp->key);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   u8 *seid = 0, *deid = 0;
3182   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3183
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   if (mp->is_ip4)
3194     format_ip_address_fcn = format_ip4_address;
3195   else
3196     format_ip_address_fcn = format_ip6_address;
3197
3198
3199   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3200          clib_net_to_host_u32 (mp->vni),
3201          seid, deid,
3202          format_ip_address_fcn, mp->lloc,
3203          format_ip_address_fcn, mp->rloc,
3204          clib_net_to_host_u32 (mp->pkt_count),
3205          clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3213 {
3214   struct in6_addr ip6;
3215   struct in_addr ip4;
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = 0;
3218   u8 *deid = 0, *seid = 0;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   deid = format (0, "%U", format_lisp_eid_vat,
3229                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3230
3231   seid = format (0, "%U", format_lisp_eid_vat,
3232                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3233
3234   vec_add1 (deid, 0);
3235   vec_add1 (seid, 0);
3236
3237   vat_json_object_add_string_copy (node, "seid", seid);
3238   vat_json_object_add_string_copy (node, "deid", deid);
3239   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3240
3241   if (mp->is_ip4)
3242     {
3243       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3244       vat_json_object_add_ip4 (node, "lloc", ip4);
3245       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "rloc", ip4);
3247     }
3248   else
3249     {
3250       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3251       vat_json_object_add_ip6 (node, "lloc", ip6);
3252       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3253       vat_json_object_add_ip6 (node, "rloc", ip6);
3254     }
3255   vat_json_object_add_uint (node, "pkt_count",
3256                             clib_net_to_host_u32 (mp->pkt_count));
3257   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3258
3259   vec_free (deid);
3260   vec_free (seid);
3261 }
3262
3263 static void
3264   vl_api_one_eid_table_map_details_t_handler
3265   (vl_api_one_eid_table_map_details_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268
3269   u8 *line = format (0, "%=10d%=10d",
3270                      clib_net_to_host_u32 (mp->vni),
3271                      clib_net_to_host_u32 (mp->dp_table));
3272   print (vam->ofp, "%v", line);
3273   vec_free (line);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler_json
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node = NULL;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "dp_table",
3291                             clib_net_to_host_u32 (mp->dp_table));
3292   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3293 }
3294
3295 static void
3296   vl_api_one_eid_table_vni_details_t_handler
3297   (vl_api_one_eid_table_vni_details_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3302   print (vam->ofp, "%v", line);
3303   vec_free (line);
3304 }
3305
3306 static void
3307   vl_api_one_eid_table_vni_details_t_handler_json
3308   (vl_api_one_eid_table_vni_details_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t *node = NULL;
3312
3313   if (VAT_JSON_ARRAY != vam->json_tree.type)
3314     {
3315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3316       vat_json_init_array (&vam->json_tree);
3317     }
3318   node = vat_json_array_add (&vam->json_tree);
3319   vat_json_init_object (node);
3320   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3325   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3331   print (vam->ofp, "fallback threshold value: %d", mp->value);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3339   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   vat_json_init_object (node);
3347   vat_json_object_add_uint (node, "value", mp->value);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_map_register_state_reply_t_handler
3358   (vl_api_show_one_map_register_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler_json
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t _node, *node = &_node;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3378
3379   vat_json_init_object (node);
3380   vat_json_object_add_string_copy (node, "state", s);
3381
3382   vat_json_print (vam->ofp, node);
3383   vat_json_free (node);
3384
3385   vam->retval = retval;
3386   vam->result_ready = 1;
3387   vec_free (s);
3388 }
3389
3390 static void
3391   vl_api_show_one_rloc_probe_state_reply_t_handler
3392   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   int retval = clib_net_to_host_u32 (mp->retval);
3396
3397   if (retval)
3398     goto end;
3399
3400   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t _node, *node = &_node;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3415   vat_json_init_object (node);
3416   vat_json_object_add_string_copy (node, "state", s);
3417
3418   vat_json_print (vam->ofp, node);
3419   vat_json_free (node);
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423   vec_free (s);
3424 }
3425
3426 static void
3427   vl_api_show_one_stats_enable_disable_reply_t_handler
3428   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432
3433   if (retval)
3434     goto end;
3435
3436   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3437 end:
3438   vam->retval = retval;
3439   vam->result_ready = 1;
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t _node, *node = &_node;
3448   int retval = clib_net_to_host_u32 (mp->retval);
3449
3450   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3451   vat_json_init_object (node);
3452   vat_json_object_add_string_copy (node, "state", s);
3453
3454   vat_json_print (vam->ofp, node);
3455   vat_json_free (node);
3456
3457   vam->retval = retval;
3458   vam->result_ready = 1;
3459   vec_free (s);
3460 }
3461
3462 static void
3463 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3464 {
3465   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3466   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3467   e->vni = clib_net_to_host_u32 (e->vni);
3468 }
3469
3470 static void
3471   gpe_fwd_entries_get_reply_t_net_to_host
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u32 i;
3475
3476   mp->count = clib_net_to_host_u32 (mp->count);
3477   for (i = 0; i < mp->count; i++)
3478     {
3479       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3480     }
3481 }
3482
3483 static u8 *
3484 format_gpe_encap_mode (u8 * s, va_list * args)
3485 {
3486   u32 mode = va_arg (*args, u32);
3487
3488   switch (mode)
3489     {
3490     case 0:
3491       return format (s, "lisp");
3492     case 1:
3493       return format (s, "vxlan");
3494     }
3495   return 0;
3496 }
3497
3498 static void
3499   vl_api_gpe_get_encap_mode_reply_t_handler
3500   (vl_api_gpe_get_encap_mode_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503
3504   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3505   vam->retval = ntohl (mp->retval);
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510   vl_api_gpe_get_encap_mode_reply_t_handler_json
3511   (vl_api_gpe_get_encap_mode_reply_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t node;
3515
3516   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3517   vec_add1 (encap_mode, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3521
3522   vec_free (encap_mode);
3523   vat_json_print (vam->ofp, &node);
3524   vat_json_free (&node);
3525
3526   vam->retval = ntohl (mp->retval);
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_fwd_entry_path_details_t_handler
3532   (vl_api_gpe_fwd_entry_path_details_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3536
3537   if (mp->lcl_loc.is_ip4)
3538     format_ip_address_fcn = format_ip4_address;
3539   else
3540     format_ip_address_fcn = format_ip6_address;
3541
3542   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3543          format_ip_address_fcn, &mp->lcl_loc,
3544          format_ip_address_fcn, &mp->rmt_loc);
3545 }
3546
3547 static void
3548 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3549 {
3550   struct in6_addr ip6;
3551   struct in_addr ip4;
3552
3553   if (loc->is_ip4)
3554     {
3555       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3556       vat_json_object_add_ip4 (n, "address", ip4);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3561       vat_json_object_add_ip6 (n, "address", ip6);
3562     }
3563   vat_json_object_add_uint (n, "weight", loc->weight);
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entry_path_details_t_handler_json
3568   (vl_api_gpe_fwd_entry_path_details_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   vat_json_node_t *node = NULL;
3572   vat_json_node_t *loc_node;
3573
3574   if (VAT_JSON_ARRAY != vam->json_tree.type)
3575     {
3576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3577       vat_json_init_array (&vam->json_tree);
3578     }
3579   node = vat_json_array_add (&vam->json_tree);
3580   vat_json_init_object (node);
3581
3582   loc_node = vat_json_object_add (node, "local_locator");
3583   vat_json_init_object (loc_node);
3584   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3585
3586   loc_node = vat_json_object_add (node, "remote_locator");
3587   vat_json_init_object (loc_node);
3588   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3589 }
3590
3591 static void
3592   vl_api_gpe_fwd_entries_get_reply_t_handler
3593   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_fwd_entry_t *e;
3599
3600   if (retval)
3601     goto end;
3602
3603   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3604
3605   for (i = 0; i < mp->count; i++)
3606     {
3607       e = &mp->entries[i];
3608       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3609              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3610              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3611     }
3612
3613 end:
3614   vam->retval = retval;
3615   vam->result_ready = 1;
3616 }
3617
3618 static void
3619   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3620   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3621 {
3622   u8 *s = 0;
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t *e = 0, root;
3625   u32 i;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_fwd_entry_t *fwd;
3628
3629   if (retval)
3630     goto end;
3631
3632   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < mp->count; i++)
3636     {
3637       e = vat_json_array_add (&root);
3638       fwd = &mp->entries[i];
3639
3640       vat_json_init_object (e);
3641       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3642       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3643       vat_json_object_add_int (e, "vni", fwd->vni);
3644       vat_json_object_add_int (e, "action", fwd->action);
3645
3646       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3647                   fwd->leid_prefix_len);
3648       vec_add1 (s, 0);
3649       vat_json_object_add_string_copy (e, "leid", s);
3650       vec_free (s);
3651
3652       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3653                   fwd->reid_prefix_len);
3654       vec_add1 (s, 0);
3655       vat_json_object_add_string_copy (e, "reid", s);
3656       vec_free (s);
3657     }
3658
3659   vat_json_print (vam->ofp, &root);
3660   vat_json_free (&root);
3661
3662 end:
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3669   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_gpe_native_fwd_rpath_t *r;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     {
3683       r = &mp->entries[i];
3684       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3685              clib_net_to_host_u32 (r->fib_index),
3686              clib_net_to_host_u32 (r->nh_sw_if_index),
3687              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3688     }
3689
3690 end:
3691   vam->retval = retval;
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3697   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   vat_json_node_t root, *e;
3701   u32 i, n;
3702   int retval = clib_net_to_host_u32 (mp->retval);
3703   vl_api_gpe_native_fwd_rpath_t *r;
3704   u8 *s;
3705
3706   if (retval)
3707     goto end;
3708
3709   n = clib_net_to_host_u32 (mp->count);
3710   vat_json_init_array (&root);
3711
3712   for (i = 0; i < n; i++)
3713     {
3714       e = vat_json_array_add (&root);
3715       vat_json_init_object (e);
3716       r = &mp->entries[i];
3717       s =
3718         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3719                 r->nh_addr);
3720       vec_add1 (s, 0);
3721       vat_json_object_add_string_copy (e, "ip4", s);
3722       vec_free (s);
3723
3724       vat_json_object_add_uint (e, "fib_index",
3725                                 clib_net_to_host_u32 (r->fib_index));
3726       vat_json_object_add_uint (e, "nh_sw_if_index",
3727                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3728     }
3729
3730   vat_json_print (vam->ofp, &root);
3731   vat_json_free (&root);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3740   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743   u32 i, n;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745
3746   if (retval)
3747     goto end;
3748
3749   n = clib_net_to_host_u32 (mp->count);
3750
3751   for (i = 0; i < n; i++)
3752     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3761   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_ndp_entries_get_reply_t_handler
3787   (vl_api_one_ndp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_entries_get_reply_t_handler_json
3809   (vl_api_one_ndp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_ndp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip6", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_entries_get_reply_t_handler
3852   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   u32 i, n;
3856   int retval = clib_net_to_host_u32 (mp->retval);
3857
3858   if (retval)
3859     goto end;
3860
3861   n = clib_net_to_host_u32 (mp->count);
3862
3863   for (i = 0; i < n; i++)
3864     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3865            format_ethernet_address, mp->entries[i].mac);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3874   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3875 {
3876   u8 *s = 0;
3877   vat_main_t *vam = &vat_main;
3878   vat_json_node_t *e = 0, root;
3879   u32 i, n;
3880   int retval = clib_net_to_host_u32 (mp->retval);
3881   vl_api_one_l2_arp_entry_t *arp_entry;
3882
3883   if (retval)
3884     goto end;
3885
3886   n = clib_net_to_host_u32 (mp->count);
3887   vat_json_init_array (&root);
3888
3889   for (i = 0; i < n; i++)
3890     {
3891       e = vat_json_array_add (&root);
3892       arp_entry = &mp->entries[i];
3893
3894       vat_json_init_object (e);
3895       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3896       vec_add1 (s, 0);
3897
3898       vat_json_object_add_string_copy (e, "mac", s);
3899       vec_free (s);
3900
3901       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3902       vec_add1 (s, 0);
3903       vat_json_object_add_string_copy (e, "ip4", s);
3904       vec_free (s);
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_ndp_bd_get_reply_t_handler_json
3939   (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_l2_arp_bd_get_reply_t_handler
3968   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973
3974   if (retval)
3975     goto end;
3976
3977   n = clib_net_to_host_u32 (mp->count);
3978
3979   for (i = 0; i < n; i++)
3980     {
3981       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3982     }
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002   vat_json_init_array (&root);
4003
4004   for (i = 0; i < n; i++)
4005     {
4006       vat_json_array_add_uint (&root,
4007                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4008     }
4009
4010   vat_json_print (vam->ofp, &root);
4011   vat_json_free (&root);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_adjacencies_get_reply_t_handler
4020   (vl_api_one_adjacencies_get_reply_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   u32 i, n;
4024   int retval = clib_net_to_host_u32 (mp->retval);
4025   vl_api_one_adjacency_t *a;
4026
4027   if (retval)
4028     goto end;
4029
4030   n = clib_net_to_host_u32 (mp->count);
4031
4032   for (i = 0; i < n; i++)
4033     {
4034       a = &mp->adjacencies[i];
4035       print (vam->ofp, "%U %40U",
4036              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4037              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4038     }
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_adjacencies_get_reply_t_handler_json
4047   (vl_api_one_adjacencies_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_adjacency_t *a;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       a = &mp->adjacencies[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4069                   a->leid_prefix_len);
4070       vec_add1 (s, 0);
4071       vat_json_object_add_string_copy (e, "leid", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4075                   a->reid_prefix_len);
4076       vec_add1 (s, 0);
4077       vat_json_object_add_string_copy (e, "reid", s);
4078       vec_free (s);
4079     }
4080
4081   vat_json_print (vam->ofp, &root);
4082   vat_json_free (&root);
4083
4084 end:
4085   vam->retval = retval;
4086   vam->result_ready = 1;
4087 }
4088
4089 static void
4090 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093
4094   print (vam->ofp, "%=20U",
4095          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4096          mp->ip_address);
4097 }
4098
4099 static void
4100   vl_api_one_map_server_details_t_handler_json
4101   (vl_api_one_map_server_details_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105   struct in6_addr ip6;
4106   struct in_addr ip4;
4107
4108   if (VAT_JSON_ARRAY != vam->json_tree.type)
4109     {
4110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4111       vat_json_init_array (&vam->json_tree);
4112     }
4113   node = vat_json_array_add (&vam->json_tree);
4114
4115   vat_json_init_object (node);
4116   if (mp->is_ipv6)
4117     {
4118       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4119       vat_json_object_add_ip6 (node, "map-server", ip6);
4120     }
4121   else
4122     {
4123       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4124       vat_json_object_add_ip4 (node, "map-server", ip4);
4125     }
4126 }
4127
4128 static void
4129 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4130                                            * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133
4134   print (vam->ofp, "%=20U",
4135          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4136          mp->ip_address);
4137 }
4138
4139 static void
4140   vl_api_one_map_resolver_details_t_handler_json
4141   (vl_api_one_map_resolver_details_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t *node = NULL;
4145   struct in6_addr ip6;
4146   struct in_addr ip4;
4147
4148   if (VAT_JSON_ARRAY != vam->json_tree.type)
4149     {
4150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4151       vat_json_init_array (&vam->json_tree);
4152     }
4153   node = vat_json_array_add (&vam->json_tree);
4154
4155   vat_json_init_object (node);
4156   if (mp->is_ipv6)
4157     {
4158       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4159       vat_json_object_add_ip6 (node, "map resolver", ip6);
4160     }
4161   else
4162     {
4163       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4164       vat_json_object_add_ip4 (node, "map resolver", ip4);
4165     }
4166 }
4167
4168 static void
4169 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4170 {
4171   vat_main_t *vam = &vat_main;
4172   i32 retval = ntohl (mp->retval);
4173
4174   if (0 <= retval)
4175     {
4176       print (vam->ofp, "feature: %s\ngpe: %s",
4177              mp->feature_status ? "enabled" : "disabled",
4178              mp->gpe_status ? "enabled" : "disabled");
4179     }
4180
4181   vam->retval = retval;
4182   vam->result_ready = 1;
4183 }
4184
4185 static void
4186   vl_api_show_one_status_reply_t_handler_json
4187   (vl_api_show_one_status_reply_t * mp)
4188 {
4189   vat_main_t *vam = &vat_main;
4190   vat_json_node_t node;
4191   u8 *gpe_status = NULL;
4192   u8 *feature_status = NULL;
4193
4194   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4195   feature_status = format (0, "%s",
4196                            mp->feature_status ? "enabled" : "disabled");
4197   vec_add1 (gpe_status, 0);
4198   vec_add1 (feature_status, 0);
4199
4200   vat_json_init_object (&node);
4201   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4202   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4203
4204   vec_free (gpe_status);
4205   vec_free (feature_status);
4206
4207   vat_json_print (vam->ofp, &node);
4208   vat_json_free (&node);
4209
4210   vam->retval = ntohl (mp->retval);
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4216   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   i32 retval = ntohl (mp->retval);
4220
4221   if (retval >= 0)
4222     {
4223       print (vam->ofp, "%=20s", mp->locator_set_name);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t *node = NULL;
4236
4237   if (VAT_JSON_ARRAY != vam->json_tree.type)
4238     {
4239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4240       vat_json_init_array (&vam->json_tree);
4241     }
4242   node = vat_json_array_add (&vam->json_tree);
4243
4244   vat_json_init_object (node);
4245   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4246
4247   vat_json_print (vam->ofp, node);
4248   vat_json_free (node);
4249
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static u8 *
4255 format_lisp_map_request_mode (u8 * s, va_list * args)
4256 {
4257   u32 mode = va_arg (*args, u32);
4258
4259   switch (mode)
4260     {
4261     case 0:
4262       return format (0, "dst-only");
4263     case 1:
4264       return format (0, "src-dst");
4265     }
4266   return 0;
4267 }
4268
4269 static void
4270   vl_api_show_one_map_request_mode_reply_t_handler
4271   (vl_api_show_one_map_request_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   i32 retval = ntohl (mp->retval);
4275
4276   if (0 <= retval)
4277     {
4278       u32 mode = mp->mode;
4279       print (vam->ofp, "map_request_mode: %U",
4280              format_lisp_map_request_mode, mode);
4281     }
4282
4283   vam->retval = retval;
4284   vam->result_ready = 1;
4285 }
4286
4287 static void
4288   vl_api_show_one_map_request_mode_reply_t_handler_json
4289   (vl_api_show_one_map_request_mode_reply_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t node;
4293   u8 *s = 0;
4294   u32 mode;
4295
4296   mode = mp->mode;
4297   s = format (0, "%U", format_lisp_map_request_mode, mode);
4298   vec_add1 (s, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vec_free (s);
4306   vam->retval = ntohl (mp->retval);
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_one_show_xtr_mode_reply_t_handler
4312   (vl_api_one_show_xtr_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316
4317   if (0 <= retval)
4318     {
4319       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4320     }
4321
4322   vam->retval = retval;
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler_json
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   vat_json_node_t node;
4332   u8 *status = 0;
4333
4334   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4335   vec_add1 (status, 0);
4336
4337   vat_json_init_object (&node);
4338   vat_json_object_add_string_copy (&node, "status", status);
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_pitr_mode_reply_t_handler
4351   (vl_api_one_show_pitr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler_json
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371   u8 *status = 0;
4372
4373   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4374   vec_add1 (status, 0);
4375
4376   vat_json_init_object (&node);
4377   vat_json_object_add_string_copy (&node, "status", status);
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_petr_mode_reply_t_handler
4390   (vl_api_one_show_petr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   if (0 <= retval)
4396     {
4397       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler_json
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *status = 0;
4411
4412   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4413   vec_add1 (status, 0);
4414
4415   vat_json_init_object (&node);
4416   vat_json_object_add_string_copy (&node, "status", status);
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_use_petr_reply_t_handler
4429   (vl_api_show_one_use_petr_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4437       if (mp->status)
4438         {
4439           print (vam->ofp, "Proxy-ETR address; %U",
4440                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4441                  mp->address);
4442         }
4443     }
4444
4445   vam->retval = retval;
4446   vam->result_ready = 1;
4447 }
4448
4449 static void
4450   vl_api_show_one_use_petr_reply_t_handler_json
4451   (vl_api_show_one_use_petr_reply_t * mp)
4452 {
4453   vat_main_t *vam = &vat_main;
4454   vat_json_node_t node;
4455   u8 *status = 0;
4456   struct in_addr ip4;
4457   struct in6_addr ip6;
4458
4459   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4460   vec_add1 (status, 0);
4461
4462   vat_json_init_object (&node);
4463   vat_json_object_add_string_copy (&node, "status", status);
4464   if (mp->status)
4465     {
4466       if (mp->is_ip4)
4467         {
4468           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4469           vat_json_object_add_ip6 (&node, "address", ip6);
4470         }
4471       else
4472         {
4473           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4474           vat_json_object_add_ip4 (&node, "address", ip4);
4475         }
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_nsh_mapping_reply_t_handler
4489   (vl_api_show_one_nsh_mapping_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "%-20s%-16s",
4497              mp->is_set ? "set" : "not-set",
4498              mp->is_set ? (char *) mp->locator_set_name : "");
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_nsh_mapping_reply_t_handler_json
4507   (vl_api_show_one_nsh_mapping_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511   u8 *status = 0;
4512
4513   status = format (0, "%s", mp->is_set ? "yes" : "no");
4514   vec_add1 (status, 0);
4515
4516   vat_json_init_object (&node);
4517   vat_json_object_add_string_copy (&node, "is_set", status);
4518   if (mp->is_set)
4519     {
4520       vat_json_object_add_string_copy (&node, "locator_set",
4521                                        mp->locator_set_name);
4522     }
4523
4524   vec_free (status);
4525
4526   vat_json_print (vam->ofp, &node);
4527   vat_json_free (&node);
4528
4529   vam->retval = ntohl (mp->retval);
4530   vam->result_ready = 1;
4531 }
4532
4533 static void
4534   vl_api_show_one_map_register_ttl_reply_t_handler
4535   (vl_api_show_one_map_register_ttl_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   i32 retval = ntohl (mp->retval);
4539
4540   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4541
4542   if (0 <= retval)
4543     {
4544       print (vam->ofp, "ttl: %u", mp->ttl);
4545     }
4546
4547   vam->retval = retval;
4548   vam->result_ready = 1;
4549 }
4550
4551 static void
4552   vl_api_show_one_map_register_ttl_reply_t_handler_json
4553   (vl_api_show_one_map_register_ttl_reply_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   vat_json_node_t node;
4557
4558   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4559   vat_json_init_object (&node);
4560   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   i32 retval = ntohl (mp->retval);
4574
4575   if (0 <= retval)
4576     {
4577       print (vam->ofp, "%-20s%-16s",
4578              mp->status ? "enabled" : "disabled",
4579              mp->status ? (char *) mp->locator_set_name : "");
4580     }
4581
4582   vam->retval = retval;
4583   vam->result_ready = 1;
4584 }
4585
4586 static void
4587 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4588 {
4589   vat_main_t *vam = &vat_main;
4590   vat_json_node_t node;
4591   u8 *status = 0;
4592
4593   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4594   vec_add1 (status, 0);
4595
4596   vat_json_init_object (&node);
4597   vat_json_object_add_string_copy (&node, "status", status);
4598   if (mp->status)
4599     {
4600       vat_json_object_add_string_copy (&node, "locator_set",
4601                                        mp->locator_set_name);
4602     }
4603
4604   vec_free (status);
4605
4606   vat_json_print (vam->ofp, &node);
4607   vat_json_free (&node);
4608
4609   vam->retval = ntohl (mp->retval);
4610   vam->result_ready = 1;
4611 }
4612
4613 static u8 *
4614 format_policer_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4619     s = format (s, "1r2c");
4620   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4621     s = format (s, "1r3c");
4622   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4623     s = format (s, "2r3c-2698");
4624   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4625     s = format (s, "2r3c-4115");
4626   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4627     s = format (s, "2r3c-mef5cf1");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_policer_rate_type (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637
4638   if (i == SSE2_QOS_RATE_KBPS)
4639     s = format (s, "kbps");
4640   else if (i == SSE2_QOS_RATE_PPS)
4641     s = format (s, "pps");
4642   else
4643     s = format (s, "ILLEGAL");
4644   return s;
4645 }
4646
4647 static u8 *
4648 format_policer_round_type (u8 * s, va_list * va)
4649 {
4650   u32 i = va_arg (*va, u32);
4651
4652   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4653     s = format (s, "closest");
4654   else if (i == SSE2_QOS_ROUND_TO_UP)
4655     s = format (s, "up");
4656   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4657     s = format (s, "down");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_action_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ACTION_DROP)
4669     s = format (s, "drop");
4670   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4671     s = format (s, "transmit");
4672   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4673     s = format (s, "mark-and-transmit");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_dscp (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683   char *t = 0;
4684
4685   switch (i)
4686     {
4687 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4688       foreach_vnet_dscp
4689 #undef _
4690     default:
4691       return format (s, "ILLEGAL");
4692     }
4693   s = format (s, "%s", t);
4694   return s;
4695 }
4696
4697 static void
4698 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4702
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705   else
4706     conform_dscp_str = format (0, "");
4707
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710   else
4711     exceed_dscp_str = format (0, "");
4712
4713   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4714     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4715   else
4716     violate_dscp_str = format (0, "");
4717
4718   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4719          "rate type %U, round type %U, %s rate, %s color-aware, "
4720          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4721          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4722          "conform action %U%s, exceed action %U%s, violate action %U%s",
4723          mp->name,
4724          format_policer_type, mp->type,
4725          ntohl (mp->cir),
4726          ntohl (mp->eir),
4727          clib_net_to_host_u64 (mp->cb),
4728          clib_net_to_host_u64 (mp->eb),
4729          format_policer_rate_type, mp->rate_type,
4730          format_policer_round_type, mp->round_type,
4731          mp->single_rate ? "single" : "dual",
4732          mp->color_aware ? "is" : "not",
4733          ntohl (mp->cir_tokens_per_period),
4734          ntohl (mp->pir_tokens_per_period),
4735          ntohl (mp->scale),
4736          ntohl (mp->current_limit),
4737          ntohl (mp->current_bucket),
4738          ntohl (mp->extended_limit),
4739          ntohl (mp->extended_bucket),
4740          clib_net_to_host_u64 (mp->last_update_time),
4741          format_policer_action_type, mp->conform_action_type,
4742          conform_dscp_str,
4743          format_policer_action_type, mp->exceed_action_type,
4744          exceed_dscp_str,
4745          format_policer_action_type, mp->violate_action_type,
4746          violate_dscp_str);
4747
4748   vec_free (conform_dscp_str);
4749   vec_free (exceed_dscp_str);
4750   vec_free (violate_dscp_str);
4751 }
4752
4753 static void vl_api_policer_details_t_handler_json
4754   (vl_api_policer_details_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t *node;
4758   u8 *rate_type_str, *round_type_str, *type_str;
4759   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4760
4761   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4762   round_type_str =
4763     format (0, "%U", format_policer_round_type, mp->round_type);
4764   type_str = format (0, "%U", format_policer_type, mp->type);
4765   conform_action_str = format (0, "%U", format_policer_action_type,
4766                                mp->conform_action_type);
4767   exceed_action_str = format (0, "%U", format_policer_action_type,
4768                               mp->exceed_action_type);
4769   violate_action_str = format (0, "%U", format_policer_action_type,
4770                                mp->violate_action_type);
4771
4772   if (VAT_JSON_ARRAY != vam->json_tree.type)
4773     {
4774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4775       vat_json_init_array (&vam->json_tree);
4776     }
4777   node = vat_json_array_add (&vam->json_tree);
4778
4779   vat_json_init_object (node);
4780   vat_json_object_add_string_copy (node, "name", mp->name);
4781   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4782   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4783   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4784   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4785   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4786   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4787   vat_json_object_add_string_copy (node, "type", type_str);
4788   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4789   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4790   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4791   vat_json_object_add_uint (node, "cir_tokens_per_period",
4792                             ntohl (mp->cir_tokens_per_period));
4793   vat_json_object_add_uint (node, "eir_tokens_per_period",
4794                             ntohl (mp->pir_tokens_per_period));
4795   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4796   vat_json_object_add_uint (node, "current_bucket",
4797                             ntohl (mp->current_bucket));
4798   vat_json_object_add_uint (node, "extended_limit",
4799                             ntohl (mp->extended_limit));
4800   vat_json_object_add_uint (node, "extended_bucket",
4801                             ntohl (mp->extended_bucket));
4802   vat_json_object_add_uint (node, "last_update_time",
4803                             ntohl (mp->last_update_time));
4804   vat_json_object_add_string_copy (node, "conform_action",
4805                                    conform_action_str);
4806   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4807     {
4808       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4809       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4810       vec_free (dscp_str);
4811     }
4812   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4813   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4814     {
4815       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4816       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4817       vec_free (dscp_str);
4818     }
4819   vat_json_object_add_string_copy (node, "violate_action",
4820                                    violate_action_str);
4821   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4824       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827
4828   vec_free (rate_type_str);
4829   vec_free (round_type_str);
4830   vec_free (type_str);
4831   vec_free (conform_action_str);
4832   vec_free (exceed_action_str);
4833   vec_free (violate_action_str);
4834 }
4835
4836 static void
4837 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4838                                            mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   int i, count = ntohl (mp->count);
4842
4843   if (count > 0)
4844     print (vam->ofp, "classify table ids (%d) : ", count);
4845   for (i = 0; i < count; i++)
4846     {
4847       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4848       print (vam->ofp, (i < count - 1) ? "," : "");
4849     }
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855   vl_api_classify_table_ids_reply_t_handler_json
4856   (vl_api_classify_table_ids_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   int i, count = ntohl (mp->count);
4860
4861   if (count > 0)
4862     {
4863       vat_json_node_t node;
4864
4865       vat_json_init_object (&node);
4866       for (i = 0; i < count; i++)
4867         {
4868           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4869         }
4870       vat_json_print (vam->ofp, &node);
4871       vat_json_free (&node);
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_by_interface_reply_t_handler
4879   (vl_api_classify_table_by_interface_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   u32 table_id;
4883
4884   table_id = ntohl (mp->l2_table_id);
4885   if (table_id != ~0)
4886     print (vam->ofp, "l2 table id : %d", table_id);
4887   else
4888     print (vam->ofp, "l2 table id : No input ACL tables configured");
4889   table_id = ntohl (mp->ip4_table_id);
4890   if (table_id != ~0)
4891     print (vam->ofp, "ip4 table id : %d", table_id);
4892   else
4893     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4894   table_id = ntohl (mp->ip6_table_id);
4895   if (table_id != ~0)
4896     print (vam->ofp, "ip6 table id : %d", table_id);
4897   else
4898     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4899   vam->retval = ntohl (mp->retval);
4900   vam->result_ready = 1;
4901 }
4902
4903 static void
4904   vl_api_classify_table_by_interface_reply_t_handler_json
4905   (vl_api_classify_table_by_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   vat_json_init_object (&node);
4911
4912   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4913   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4914   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_policer_add_del_reply_t_handler
4924   (vl_api_policer_add_del_reply_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (vam->async_mode)
4929     {
4930       vam->async_errors += (retval < 0);
4931     }
4932   else
4933     {
4934       vam->retval = retval;
4935       vam->result_ready = 1;
4936       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4937         /*
4938          * Note: this is just barely thread-safe, depends on
4939          * the main thread spinning waiting for an answer...
4940          */
4941         errmsg ("policer index %d", ntohl (mp->policer_index));
4942     }
4943 }
4944
4945 static void vl_api_policer_add_del_reply_t_handler_json
4946   (vl_api_policer_add_del_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   vat_json_init_object (&node);
4952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4953   vat_json_object_add_uint (&node, "policer_index",
4954                             ntohl (mp->policer_index));
4955
4956   vat_json_print (vam->ofp, &node);
4957   vat_json_free (&node);
4958
4959   vam->retval = ntohl (mp->retval);
4960   vam->result_ready = 1;
4961 }
4962
4963 /* Format hex dump. */
4964 u8 *
4965 format_hex_bytes (u8 * s, va_list * va)
4966 {
4967   u8 *bytes = va_arg (*va, u8 *);
4968   int n_bytes = va_arg (*va, int);
4969   uword i;
4970
4971   /* Print short or long form depending on byte count. */
4972   uword short_form = n_bytes <= 32;
4973   u32 indent = format_get_indent (s);
4974
4975   if (n_bytes == 0)
4976     return s;
4977
4978   for (i = 0; i < n_bytes; i++)
4979     {
4980       if (!short_form && (i % 32) == 0)
4981         s = format (s, "%08x: ", i);
4982       s = format (s, "%02x", bytes[i]);
4983       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4984         s = format (s, "\n%U", format_white_space, indent);
4985     }
4986
4987   return s;
4988 }
4989
4990 static void
4991 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4992                                             * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   i32 retval = ntohl (mp->retval);
4996   if (retval == 0)
4997     {
4998       print (vam->ofp, "classify table info :");
4999       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5000              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5001              ntohl (mp->miss_next_index));
5002       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5003              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5004              ntohl (mp->match_n_vectors));
5005       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5006              ntohl (mp->mask_length));
5007     }
5008   vam->retval = retval;
5009   vam->result_ready = 1;
5010 }
5011
5012 static void
5013   vl_api_classify_table_info_reply_t_handler_json
5014   (vl_api_classify_table_info_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t node;
5018
5019   i32 retval = ntohl (mp->retval);
5020   if (retval == 0)
5021     {
5022       vat_json_init_object (&node);
5023
5024       vat_json_object_add_int (&node, "sessions",
5025                                ntohl (mp->active_sessions));
5026       vat_json_object_add_int (&node, "nexttbl",
5027                                ntohl (mp->next_table_index));
5028       vat_json_object_add_int (&node, "nextnode",
5029                                ntohl (mp->miss_next_index));
5030       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5031       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5032       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5033       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5034                       ntohl (mp->mask_length), 0);
5035       vat_json_object_add_string_copy (&node, "mask", s);
5036
5037       vat_json_print (vam->ofp, &node);
5038       vat_json_free (&node);
5039     }
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void
5045 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5046                                            mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049
5050   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5051          ntohl (mp->hit_next_index), ntohl (mp->advance),
5052          ntohl (mp->opaque_index));
5053   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5054          ntohl (mp->match_length));
5055 }
5056
5057 static void
5058   vl_api_classify_session_details_t_handler_json
5059   (vl_api_classify_session_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   vat_json_node_t *node = NULL;
5063
5064   if (VAT_JSON_ARRAY != vam->json_tree.type)
5065     {
5066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5067       vat_json_init_array (&vam->json_tree);
5068     }
5069   node = vat_json_array_add (&vam->json_tree);
5070
5071   vat_json_init_object (node);
5072   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5073   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5074   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5075   u8 *s =
5076     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5077             0);
5078   vat_json_object_add_string_copy (node, "match", s);
5079 }
5080
5081 static void vl_api_pg_create_interface_reply_t_handler
5082   (vl_api_pg_create_interface_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085
5086   vam->retval = ntohl (mp->retval);
5087   vam->result_ready = 1;
5088 }
5089
5090 static void vl_api_pg_create_interface_reply_t_handler_json
5091   (vl_api_pg_create_interface_reply_t * mp)
5092 {
5093   vat_main_t *vam = &vat_main;
5094   vat_json_node_t node;
5095
5096   i32 retval = ntohl (mp->retval);
5097   if (retval == 0)
5098     {
5099       vat_json_init_object (&node);
5100
5101       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5102
5103       vat_json_print (vam->ofp, &node);
5104       vat_json_free (&node);
5105     }
5106   vam->retval = ntohl (mp->retval);
5107   vam->result_ready = 1;
5108 }
5109
5110 static void vl_api_policer_classify_details_t_handler
5111   (vl_api_policer_classify_details_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114
5115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5116          ntohl (mp->table_index));
5117 }
5118
5119 static void vl_api_policer_classify_details_t_handler_json
5120   (vl_api_policer_classify_details_t * mp)
5121 {
5122   vat_main_t *vam = &vat_main;
5123   vat_json_node_t *node;
5124
5125   if (VAT_JSON_ARRAY != vam->json_tree.type)
5126     {
5127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5128       vat_json_init_array (&vam->json_tree);
5129     }
5130   node = vat_json_array_add (&vam->json_tree);
5131
5132   vat_json_init_object (node);
5133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5138   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   i32 retval = ntohl (mp->retval);
5142   if (vam->async_mode)
5143     {
5144       vam->async_errors += (retval < 0);
5145     }
5146   else
5147     {
5148       vam->retval = retval;
5149       vam->sw_if_index = ntohl (mp->sw_if_index);
5150       vam->result_ready = 1;
5151     }
5152 }
5153
5154 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5155   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5156 {
5157   vat_main_t *vam = &vat_main;
5158   vat_json_node_t node;
5159
5160   vat_json_init_object (&node);
5161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5162   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5163
5164   vat_json_print (vam->ofp, &node);
5165   vat_json_free (&node);
5166
5167   vam->retval = ntohl (mp->retval);
5168   vam->result_ready = 1;
5169 }
5170
5171 static void vl_api_flow_classify_details_t_handler
5172   (vl_api_flow_classify_details_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175
5176   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5177          ntohl (mp->table_index));
5178 }
5179
5180 static void vl_api_flow_classify_details_t_handler_json
5181   (vl_api_flow_classify_details_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t *node;
5185
5186   if (VAT_JSON_ARRAY != vam->json_tree.type)
5187     {
5188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5189       vat_json_init_array (&vam->json_tree);
5190     }
5191   node = vat_json_array_add (&vam->json_tree);
5192
5193   vat_json_init_object (node);
5194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5195   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5196 }
5197
5198 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5199 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5200 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5201 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5202 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5203 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5204 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5205 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5206 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5207 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5208 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5209 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5210 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5211 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5212 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5213 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5214 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5215 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5216 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5217 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5218 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5219 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5220
5221 /*
5222  * Generate boilerplate reply handlers, which
5223  * dig the return value out of the xxx_reply_t API message,
5224  * stick it into vam->retval, and set vam->result_ready
5225  *
5226  * Could also do this by pointing N message decode slots at
5227  * a single function, but that could break in subtle ways.
5228  */
5229
5230 #define foreach_standard_reply_retval_handler           \
5231 _(sw_interface_set_flags_reply)                         \
5232 _(sw_interface_add_del_address_reply)                   \
5233 _(sw_interface_set_rx_mode_reply)                       \
5234 _(sw_interface_set_table_reply)                         \
5235 _(sw_interface_set_mpls_enable_reply)                   \
5236 _(sw_interface_set_vpath_reply)                         \
5237 _(sw_interface_set_vxlan_bypass_reply)                  \
5238 _(sw_interface_set_geneve_bypass_reply)                 \
5239 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5240 _(sw_interface_set_l2_bridge_reply)                     \
5241 _(bridge_domain_add_del_reply)                          \
5242 _(sw_interface_set_l2_xconnect_reply)                   \
5243 _(l2fib_add_del_reply)                                  \
5244 _(l2fib_flush_int_reply)                                \
5245 _(l2fib_flush_bd_reply)                                 \
5246 _(ip_add_del_route_reply)                               \
5247 _(ip_table_add_del_reply)                               \
5248 _(ip_mroute_add_del_reply)                              \
5249 _(mpls_route_add_del_reply)                             \
5250 _(mpls_table_add_del_reply)                             \
5251 _(mpls_ip_bind_unbind_reply)                            \
5252 _(bier_route_add_del_reply)                             \
5253 _(bier_table_add_del_reply)                             \
5254 _(proxy_arp_add_del_reply)                              \
5255 _(proxy_arp_intfc_enable_disable_reply)                 \
5256 _(sw_interface_set_unnumbered_reply)                    \
5257 _(ip_neighbor_add_del_reply)                            \
5258 _(oam_add_del_reply)                                    \
5259 _(reset_fib_reply)                                      \
5260 _(dhcp_proxy_config_reply)                              \
5261 _(dhcp_proxy_set_vss_reply)                             \
5262 _(dhcp_client_config_reply)                             \
5263 _(set_ip_flow_hash_reply)                               \
5264 _(sw_interface_ip6_enable_disable_reply)                \
5265 _(sw_interface_ip6_set_link_local_address_reply)        \
5266 _(ip6nd_proxy_add_del_reply)                            \
5267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5268 _(sw_interface_ip6nd_ra_config_reply)                   \
5269 _(set_arp_neighbor_limit_reply)                         \
5270 _(l2_patch_add_del_reply)                               \
5271 _(sr_policy_add_reply)                                  \
5272 _(sr_policy_mod_reply)                                  \
5273 _(sr_policy_del_reply)                                  \
5274 _(sr_localsid_add_del_reply)                            \
5275 _(sr_steering_add_del_reply)                            \
5276 _(classify_add_del_session_reply)                       \
5277 _(classify_set_interface_ip_table_reply)                \
5278 _(classify_set_interface_l2_tables_reply)               \
5279 _(l2tpv3_set_tunnel_cookies_reply)                      \
5280 _(l2tpv3_interface_enable_disable_reply)                \
5281 _(l2tpv3_set_lookup_key_reply)                          \
5282 _(l2_fib_clear_table_reply)                             \
5283 _(l2_interface_efp_filter_reply)                        \
5284 _(l2_interface_vlan_tag_rewrite_reply)                  \
5285 _(modify_vhost_user_if_reply)                           \
5286 _(delete_vhost_user_if_reply)                           \
5287 _(want_ip4_arp_events_reply)                            \
5288 _(want_ip6_nd_events_reply)                             \
5289 _(want_l2_macs_events_reply)                            \
5290 _(input_acl_set_interface_reply)                        \
5291 _(ipsec_spd_add_del_reply)                              \
5292 _(ipsec_interface_add_del_spd_reply)                    \
5293 _(ipsec_spd_add_del_entry_reply)                        \
5294 _(ipsec_sad_add_del_entry_reply)                        \
5295 _(ipsec_sa_set_key_reply)                               \
5296 _(ipsec_tunnel_if_add_del_reply)                        \
5297 _(ipsec_tunnel_if_set_key_reply)                        \
5298 _(ipsec_tunnel_if_set_sa_reply)                         \
5299 _(ikev2_profile_add_del_reply)                          \
5300 _(ikev2_profile_set_auth_reply)                         \
5301 _(ikev2_profile_set_id_reply)                           \
5302 _(ikev2_profile_set_ts_reply)                           \
5303 _(ikev2_set_local_key_reply)                            \
5304 _(ikev2_set_responder_reply)                            \
5305 _(ikev2_set_ike_transforms_reply)                       \
5306 _(ikev2_set_esp_transforms_reply)                       \
5307 _(ikev2_set_sa_lifetime_reply)                          \
5308 _(ikev2_initiate_sa_init_reply)                         \
5309 _(ikev2_initiate_del_ike_sa_reply)                      \
5310 _(ikev2_initiate_del_child_sa_reply)                    \
5311 _(ikev2_initiate_rekey_child_sa_reply)                  \
5312 _(delete_loopback_reply)                                \
5313 _(bd_ip_mac_add_del_reply)                              \
5314 _(map_del_domain_reply)                                 \
5315 _(map_add_del_rule_reply)                               \
5316 _(want_interface_events_reply)                          \
5317 _(want_stats_reply)                                     \
5318 _(cop_interface_enable_disable_reply)                   \
5319 _(cop_whitelist_enable_disable_reply)                   \
5320 _(sw_interface_clear_stats_reply)                       \
5321 _(ioam_enable_reply)                                    \
5322 _(ioam_disable_reply)                                   \
5323 _(one_add_del_locator_reply)                            \
5324 _(one_add_del_local_eid_reply)                          \
5325 _(one_add_del_remote_mapping_reply)                     \
5326 _(one_add_del_adjacency_reply)                          \
5327 _(one_add_del_map_resolver_reply)                       \
5328 _(one_add_del_map_server_reply)                         \
5329 _(one_enable_disable_reply)                             \
5330 _(one_rloc_probe_enable_disable_reply)                  \
5331 _(one_map_register_enable_disable_reply)                \
5332 _(one_map_register_set_ttl_reply)                       \
5333 _(one_set_transport_protocol_reply)                     \
5334 _(one_map_register_fallback_threshold_reply)            \
5335 _(one_pitr_set_locator_set_reply)                       \
5336 _(one_map_request_mode_reply)                           \
5337 _(one_add_del_map_request_itr_rlocs_reply)              \
5338 _(one_eid_table_add_del_map_reply)                      \
5339 _(one_use_petr_reply)                                   \
5340 _(one_stats_enable_disable_reply)                       \
5341 _(one_add_del_l2_arp_entry_reply)                       \
5342 _(one_add_del_ndp_entry_reply)                          \
5343 _(one_stats_flush_reply)                                \
5344 _(one_enable_disable_xtr_mode_reply)                    \
5345 _(one_enable_disable_pitr_mode_reply)                   \
5346 _(one_enable_disable_petr_mode_reply)                   \
5347 _(gpe_enable_disable_reply)                             \
5348 _(gpe_set_encap_mode_reply)                             \
5349 _(gpe_add_del_iface_reply)                              \
5350 _(gpe_add_del_native_fwd_rpath_reply)                   \
5351 _(af_packet_delete_reply)                               \
5352 _(policer_classify_set_interface_reply)                 \
5353 _(netmap_create_reply)                                  \
5354 _(netmap_delete_reply)                                  \
5355 _(set_ipfix_exporter_reply)                             \
5356 _(set_ipfix_classify_stream_reply)                      \
5357 _(ipfix_classify_table_add_del_reply)                   \
5358 _(flow_classify_set_interface_reply)                    \
5359 _(sw_interface_span_enable_disable_reply)               \
5360 _(pg_capture_reply)                                     \
5361 _(pg_enable_disable_reply)                              \
5362 _(ip_source_and_port_range_check_add_del_reply)         \
5363 _(ip_source_and_port_range_check_interface_add_del_reply)\
5364 _(delete_subif_reply)                                   \
5365 _(l2_interface_pbb_tag_rewrite_reply)                   \
5366 _(punt_reply)                                           \
5367 _(feature_enable_disable_reply)                         \
5368 _(sw_interface_tag_add_del_reply)                       \
5369 _(sw_interface_set_mtu_reply)                           \
5370 _(p2p_ethernet_add_reply)                               \
5371 _(p2p_ethernet_del_reply)                               \
5372 _(lldp_config_reply)                                    \
5373 _(sw_interface_set_lldp_reply)                          \
5374 _(tcp_configure_src_addresses_reply)                    \
5375 _(dns_enable_disable_reply)                             \
5376 _(dns_name_server_add_del_reply)                        \
5377 _(session_rule_add_del_reply)                           \
5378 _(ip_container_proxy_add_del_reply)
5379
5380 #define _(n)                                    \
5381     static void vl_api_##n##_t_handler          \
5382     (vl_api_##n##_t * mp)                       \
5383     {                                           \
5384         vat_main_t * vam = &vat_main;           \
5385         i32 retval = ntohl(mp->retval);         \
5386         if (vam->async_mode) {                  \
5387             vam->async_errors += (retval < 0);  \
5388         } else {                                \
5389             vam->retval = retval;               \
5390             vam->result_ready = 1;              \
5391         }                                       \
5392     }
5393 foreach_standard_reply_retval_handler;
5394 #undef _
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler_json     \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         vat_json_node_t node;                   \
5402         vat_json_init_object(&node);            \
5403         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5404         vat_json_print(vam->ofp, &node);        \
5405         vam->retval = ntohl(mp->retval);        \
5406         vam->result_ready = 1;                  \
5407     }
5408 foreach_standard_reply_retval_handler;
5409 #undef _
5410
5411 /*
5412  * Table of message reply handlers, must include boilerplate handlers
5413  * we just generated
5414  */
5415
5416 #define foreach_vpe_api_reply_msg                                       \
5417 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5418 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5419 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5420 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5421 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5422 _(CLI_REPLY, cli_reply)                                                 \
5423 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5424 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5425   sw_interface_add_del_address_reply)                                   \
5426 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5427 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5428 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5429 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5430 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5431 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5432 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5433 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5434   sw_interface_set_l2_xconnect_reply)                                   \
5435 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5436   sw_interface_set_l2_bridge_reply)                                     \
5437 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5438 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5439 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5440 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5441 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5442 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5443 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5444 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5445 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5446 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5447 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5448 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5449 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5450 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5451 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5453 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5454 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5455 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5456 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5457 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5458 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5459 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5460 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5461 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5462   proxy_arp_intfc_enable_disable_reply)                                 \
5463 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5465   sw_interface_set_unnumbered_reply)                                    \
5466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5472 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5473 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5477   sw_interface_ip6_enable_disable_reply)                                \
5478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5479   sw_interface_ip6_set_link_local_address_reply)                        \
5480 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5481 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5483   sw_interface_ip6nd_ra_prefix_reply)                                   \
5484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5485   sw_interface_ip6nd_ra_config_reply)                                   \
5486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5488 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5489 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5490 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5491 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5492 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5493 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5494 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5495 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5496 classify_set_interface_ip_table_reply)                                  \
5497 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5498   classify_set_interface_l2_tables_reply)                               \
5499 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5500 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5501 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5502 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5503 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5504   l2tpv3_interface_enable_disable_reply)                                \
5505 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5506 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5507 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5508 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5509 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5510 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5511 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5512 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5513 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5514 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5515 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5516 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5517 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5518 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5519 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5520 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5521 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5522 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5523 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5524 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5525 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5526 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5527 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5528 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5529 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5530 _(L2_MACS_EVENT, l2_macs_event)                                         \
5531 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5532 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5533 _(IP_DETAILS, ip_details)                                               \
5534 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5535 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5536 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5537 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5538 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5539 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5540 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5541 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5542 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5543 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5544 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5545 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5546 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5547 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5548 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5549 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5550 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5551 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5552 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5553 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5554 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5555 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5556 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5557 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5558 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5571 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5572 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5573 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5574 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5575 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5576 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5577 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5578 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5579 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5580 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5581 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5582   one_map_register_enable_disable_reply)                                \
5583 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5584 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5585 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5586 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5587   one_map_register_fallback_threshold_reply)                            \
5588 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5589   one_rloc_probe_enable_disable_reply)                                  \
5590 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5591 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5592 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5593 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5594 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5595 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5596 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5597 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5598 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5599 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5600 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5601 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5602 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5603 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5604 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5605 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5606   show_one_stats_enable_disable_reply)                                  \
5607 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5608 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5609 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5610 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5611 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5612 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5613 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5614 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5615   one_enable_disable_pitr_mode_reply)                                   \
5616 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5617   one_enable_disable_petr_mode_reply)                                   \
5618 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5619 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5620 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5621 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5622 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5623 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5624 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5625 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5626 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5627 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5628 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5629 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5630   gpe_add_del_native_fwd_rpath_reply)                                   \
5631 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5632   gpe_fwd_entry_path_details)                                           \
5633 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5634 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5635   one_add_del_map_request_itr_rlocs_reply)                              \
5636 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5637   one_get_map_request_itr_rlocs_reply)                                  \
5638 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5639 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5640 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5641 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5642 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5643 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5644   show_one_map_register_state_reply)                                    \
5645 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5646 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5647   show_one_map_register_fallback_threshold_reply)                       \
5648 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5649 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5650 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5651 _(POLICER_DETAILS, policer_details)                                     \
5652 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5653 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5654 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5655 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5656 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5657 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5658 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5659 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5660 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5661 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5662 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5663 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5664 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5665 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5666 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5667 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5668 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5669 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5670 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5671 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5672 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5673 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5674 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5675 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5676 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5677  ip_source_and_port_range_check_add_del_reply)                          \
5678 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5679  ip_source_and_port_range_check_interface_add_del_reply)                \
5680 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5681 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5682 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5683 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5684 _(PUNT_REPLY, punt_reply)                                               \
5685 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5686 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5687 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5688 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5689 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5690 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5691 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5692 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5693 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5694 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5695 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5696 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5697 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5698 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5699 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5700 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5701 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5702 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5703 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5704 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5705 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5706
5707 #define foreach_standalone_reply_msg                                    \
5708 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5709 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5710 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5713 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5714 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5715 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5716
5717 typedef struct
5718 {
5719   u8 *name;
5720   u32 value;
5721 } name_sort_t;
5722
5723
5724 #define STR_VTR_OP_CASE(op)     \
5725     case L2_VTR_ ## op:         \
5726         return "" # op;
5727
5728 static const char *
5729 str_vtr_op (u32 vtr_op)
5730 {
5731   switch (vtr_op)
5732     {
5733       STR_VTR_OP_CASE (DISABLED);
5734       STR_VTR_OP_CASE (PUSH_1);
5735       STR_VTR_OP_CASE (PUSH_2);
5736       STR_VTR_OP_CASE (POP_1);
5737       STR_VTR_OP_CASE (POP_2);
5738       STR_VTR_OP_CASE (TRANSLATE_1_1);
5739       STR_VTR_OP_CASE (TRANSLATE_1_2);
5740       STR_VTR_OP_CASE (TRANSLATE_2_1);
5741       STR_VTR_OP_CASE (TRANSLATE_2_2);
5742     }
5743
5744   return "UNKNOWN";
5745 }
5746
5747 static int
5748 dump_sub_interface_table (vat_main_t * vam)
5749 {
5750   const sw_interface_subif_t *sub = NULL;
5751
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   print (vam->ofp,
5760          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5761          "Interface", "sw_if_index",
5762          "sub id", "dot1ad", "tags", "outer id",
5763          "inner id", "exact", "default", "outer any", "inner any");
5764
5765   vec_foreach (sub, vam->sw_if_subif_table)
5766   {
5767     print (vam->ofp,
5768            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5769            sub->interface_name,
5770            sub->sw_if_index,
5771            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5772            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5773            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5774            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5775     if (sub->vtr_op != L2_VTR_DISABLED)
5776       {
5777         print (vam->ofp,
5778                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5779                "tag1: %d tag2: %d ]",
5780                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5781                sub->vtr_tag1, sub->vtr_tag2);
5782       }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 name_sort_cmp (void *a1, void *a2)
5790 {
5791   name_sort_t *n1 = a1;
5792   name_sort_t *n2 = a2;
5793
5794   return strcmp ((char *) n1->name, (char *) n2->name);
5795 }
5796
5797 static int
5798 dump_interface_table (vat_main_t * vam)
5799 {
5800   hash_pair_t *p;
5801   name_sort_t *nses = 0, *ns;
5802
5803   if (vam->json_output)
5804     {
5805       clib_warning
5806         ("JSON output supported only for VPE API calls and dump_stats_table");
5807       return -99;
5808     }
5809
5810   /* *INDENT-OFF* */
5811   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5812   ({
5813     vec_add2 (nses, ns, 1);
5814     ns->name = (u8 *)(p->key);
5815     ns->value = (u32) p->value[0];
5816   }));
5817   /* *INDENT-ON* */
5818
5819   vec_sort_with_function (nses, name_sort_cmp);
5820
5821   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5822   vec_foreach (ns, nses)
5823   {
5824     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5825   }
5826   vec_free (nses);
5827   return 0;
5828 }
5829
5830 static int
5831 dump_ip_table (vat_main_t * vam, int is_ipv6)
5832 {
5833   const ip_details_t *det = NULL;
5834   const ip_address_details_t *address = NULL;
5835   u32 i = ~0;
5836
5837   print (vam->ofp, "%-12s", "sw_if_index");
5838
5839   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5840   {
5841     i++;
5842     if (!det->present)
5843       {
5844         continue;
5845       }
5846     print (vam->ofp, "%-12d", i);
5847     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5848     if (!det->addr)
5849       {
5850         continue;
5851       }
5852     vec_foreach (address, det->addr)
5853     {
5854       print (vam->ofp,
5855              "            %-30U%-13d",
5856              is_ipv6 ? format_ip6_address : format_ip4_address,
5857              address->ip, address->prefix_length);
5858     }
5859   }
5860
5861   return 0;
5862 }
5863
5864 static int
5865 dump_ipv4_table (vat_main_t * vam)
5866 {
5867   if (vam->json_output)
5868     {
5869       clib_warning
5870         ("JSON output supported only for VPE API calls and dump_stats_table");
5871       return -99;
5872     }
5873
5874   return dump_ip_table (vam, 0);
5875 }
5876
5877 static int
5878 dump_ipv6_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 1);
5888 }
5889
5890 static char *
5891 counter_type_to_str (u8 counter_type, u8 is_combined)
5892 {
5893   if (!is_combined)
5894     {
5895       switch (counter_type)
5896         {
5897         case VNET_INTERFACE_COUNTER_DROP:
5898           return "drop";
5899         case VNET_INTERFACE_COUNTER_PUNT:
5900           return "punt";
5901         case VNET_INTERFACE_COUNTER_IP4:
5902           return "ip4";
5903         case VNET_INTERFACE_COUNTER_IP6:
5904           return "ip6";
5905         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5906           return "rx-no-buf";
5907         case VNET_INTERFACE_COUNTER_RX_MISS:
5908           return "rx-miss";
5909         case VNET_INTERFACE_COUNTER_RX_ERROR:
5910           return "rx-error";
5911         case VNET_INTERFACE_COUNTER_TX_ERROR:
5912           return "tx-error";
5913         default:
5914           return "INVALID-COUNTER-TYPE";
5915         }
5916     }
5917   else
5918     {
5919       switch (counter_type)
5920         {
5921         case VNET_INTERFACE_COUNTER_RX:
5922           return "rx";
5923         case VNET_INTERFACE_COUNTER_TX:
5924           return "tx";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929 }
5930
5931 static int
5932 dump_stats_table (vat_main_t * vam)
5933 {
5934   vat_json_node_t node;
5935   vat_json_node_t *msg_array;
5936   vat_json_node_t *msg;
5937   vat_json_node_t *counter_array;
5938   vat_json_node_t *counter;
5939   interface_counter_t c;
5940   u64 packets;
5941   ip4_fib_counter_t *c4;
5942   ip6_fib_counter_t *c6;
5943   ip4_nbr_counter_t *n4;
5944   ip6_nbr_counter_t *n6;
5945   int i, j;
5946
5947   if (!vam->json_output)
5948     {
5949       clib_warning ("dump_stats_table supported only in JSON format");
5950       return -99;
5951     }
5952
5953   vat_json_init_object (&node);
5954
5955   /* interface counters */
5956   msg_array = vat_json_object_add (&node, "interface_counters");
5957   vat_json_init_array (msg_array);
5958   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5959     {
5960       msg = vat_json_array_add (msg_array);
5961       vat_json_init_object (msg);
5962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5963                                        (u8 *) counter_type_to_str (i, 0));
5964       vat_json_object_add_int (msg, "is_combined", 0);
5965       counter_array = vat_json_object_add (msg, "data");
5966       vat_json_init_array (counter_array);
5967       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5968         {
5969           packets = vam->simple_interface_counters[i][j];
5970           vat_json_array_add_uint (counter_array, packets);
5971         }
5972     }
5973   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5978                                        (u8 *) counter_type_to_str (i, 1));
5979       vat_json_object_add_int (msg, "is_combined", 1);
5980       counter_array = vat_json_object_add (msg, "data");
5981       vat_json_init_array (counter_array);
5982       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5983         {
5984           c = vam->combined_interface_counters[i][j];
5985           counter = vat_json_array_add (counter_array);
5986           vat_json_init_object (counter);
5987           vat_json_object_add_uint (counter, "packets", c.packets);
5988           vat_json_object_add_uint (counter, "bytes", c.bytes);
5989         }
5990     }
5991
5992   /* ip4 fib counters */
5993   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "vrf_id",
6000                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           c4 = &vam->ip4_fib_counters[i][j];
6008           vat_json_object_add_ip4 (counter, "address", c4->address);
6009           vat_json_object_add_uint (counter, "address_length",
6010                                     c4->address_length);
6011           vat_json_object_add_uint (counter, "packets", c4->packets);
6012           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6013         }
6014     }
6015
6016   /* ip6 fib counters */
6017   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6018   vat_json_init_array (msg_array);
6019   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6020     {
6021       msg = vat_json_array_add (msg_array);
6022       vat_json_init_object (msg);
6023       vat_json_object_add_uint (msg, "vrf_id",
6024                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6025       counter_array = vat_json_object_add (msg, "c");
6026       vat_json_init_array (counter_array);
6027       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6028         {
6029           counter = vat_json_array_add (counter_array);
6030           vat_json_init_object (counter);
6031           c6 = &vam->ip6_fib_counters[i][j];
6032           vat_json_object_add_ip6 (counter, "address", c6->address);
6033           vat_json_object_add_uint (counter, "address_length",
6034                                     c6->address_length);
6035           vat_json_object_add_uint (counter, "packets", c6->packets);
6036           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6037         }
6038     }
6039
6040   /* ip4 nbr counters */
6041   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6042   vat_json_init_array (msg_array);
6043   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6044     {
6045       msg = vat_json_array_add (msg_array);
6046       vat_json_init_object (msg);
6047       vat_json_object_add_uint (msg, "sw_if_index", i);
6048       counter_array = vat_json_object_add (msg, "c");
6049       vat_json_init_array (counter_array);
6050       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6051         {
6052           counter = vat_json_array_add (counter_array);
6053           vat_json_init_object (counter);
6054           n4 = &vam->ip4_nbr_counters[i][j];
6055           vat_json_object_add_ip4 (counter, "address", n4->address);
6056           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6057           vat_json_object_add_uint (counter, "packets", n4->packets);
6058           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6059         }
6060     }
6061
6062   /* ip6 nbr counters */
6063   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6064   vat_json_init_array (msg_array);
6065   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6066     {
6067       msg = vat_json_array_add (msg_array);
6068       vat_json_init_object (msg);
6069       vat_json_object_add_uint (msg, "sw_if_index", i);
6070       counter_array = vat_json_object_add (msg, "c");
6071       vat_json_init_array (counter_array);
6072       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6073         {
6074           counter = vat_json_array_add (counter_array);
6075           vat_json_init_object (counter);
6076           n6 = &vam->ip6_nbr_counters[i][j];
6077           vat_json_object_add_ip6 (counter, "address", n6->address);
6078           vat_json_object_add_uint (counter, "packets", n6->packets);
6079           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6080         }
6081     }
6082
6083   vat_json_print (vam->ofp, &node);
6084   vat_json_free (&node);
6085
6086   return 0;
6087 }
6088
6089 /*
6090  * Pass CLI buffers directly in the CLI_INBAND API message,
6091  * instead of an additional shared memory area.
6092  */
6093 static int
6094 exec_inband (vat_main_t * vam)
6095 {
6096   vl_api_cli_inband_t *mp;
6097   unformat_input_t *i = vam->input;
6098   int ret;
6099
6100   if (vec_len (i->buffer) == 0)
6101     return -1;
6102
6103   if (vam->exec_mode == 0 && unformat (i, "mode"))
6104     {
6105       vam->exec_mode = 1;
6106       return 0;
6107     }
6108   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6109     {
6110       vam->exec_mode = 0;
6111       return 0;
6112     }
6113
6114   /*
6115    * In order for the CLI command to work, it
6116    * must be a vector ending in \n, not a C-string ending
6117    * in \n\0.
6118    */
6119   u32 len = vec_len (vam->input->buffer);
6120   M2 (CLI_INBAND, mp, len);
6121   clib_memcpy (mp->cmd, vam->input->buffer, len);
6122   mp->length = htonl (len);
6123
6124   S (mp);
6125   W (ret);
6126   /* json responses may or may not include a useful reply... */
6127   if (vec_len (vam->cmd_reply))
6128     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6129   return ret;
6130 }
6131
6132 int
6133 exec (vat_main_t * vam)
6134 {
6135   return exec_inband (vam);
6136 }
6137
6138 static int
6139 api_create_loopback (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_create_loopback_t *mp;
6143   vl_api_create_loopback_instance_t *mp_lbi;
6144   u8 mac_address[6];
6145   u8 mac_set = 0;
6146   u8 is_specified = 0;
6147   u32 user_instance = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6155         mac_set = 1;
6156       if (unformat (i, "instance %d", &user_instance))
6157         is_specified = 1;
6158       else
6159         break;
6160     }
6161
6162   if (is_specified)
6163     {
6164       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6165       mp_lbi->is_specified = is_specified;
6166       if (is_specified)
6167         mp_lbi->user_instance = htonl (user_instance);
6168       if (mac_set)
6169         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6170       S (mp_lbi);
6171     }
6172   else
6173     {
6174       /* Construct the API message */
6175       M (CREATE_LOOPBACK, mp);
6176       if (mac_set)
6177         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6178       S (mp);
6179     }
6180
6181   W (ret);
6182   return ret;
6183 }
6184
6185 static int
6186 api_delete_loopback (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_delete_loopback_t *mp;
6190   u32 sw_if_index = ~0;
6191   int ret;
6192
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         ;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index == ~0)
6202     {
6203       errmsg ("missing sw_if_index");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (DELETE_LOOPBACK, mp);
6209   mp->sw_if_index = ntohl (sw_if_index);
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_want_stats (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_want_stats_t *mp;
6221   int enable = -1;
6222   int ret;
6223
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (enable == -1)
6235     {
6236       errmsg ("missing enable|disable");
6237       return -99;
6238     }
6239
6240   M (WANT_STATS, mp);
6241   mp->enable_disable = enable;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_want_interface_events (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_want_interface_events_t *mp;
6253   int enable = -1;
6254   int ret;
6255
6256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6257     {
6258       if (unformat (i, "enable"))
6259         enable = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (enable == -1)
6267     {
6268       errmsg ("missing enable|disable");
6269       return -99;
6270     }
6271
6272   M (WANT_INTERFACE_EVENTS, mp);
6273   mp->enable_disable = enable;
6274
6275   vam->interface_event_display = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282
6283 /* Note: non-static, called once to set up the initial intfc table */
6284 int
6285 api_sw_interface_dump (vat_main_t * vam)
6286 {
6287   vl_api_sw_interface_dump_t *mp;
6288   vl_api_control_ping_t *mp_ping;
6289   hash_pair_t *p;
6290   name_sort_t *nses = 0, *ns;
6291   sw_interface_subif_t *sub = NULL;
6292   int ret;
6293
6294   /* Toss the old name table */
6295   /* *INDENT-OFF* */
6296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6297   ({
6298     vec_add2 (nses, ns, 1);
6299     ns->name = (u8 *)(p->key);
6300     ns->value = (u32) p->value[0];
6301   }));
6302   /* *INDENT-ON* */
6303
6304   hash_free (vam->sw_if_index_by_interface_name);
6305
6306   vec_foreach (ns, nses) vec_free (ns->name);
6307
6308   vec_free (nses);
6309
6310   vec_foreach (sub, vam->sw_if_subif_table)
6311   {
6312     vec_free (sub->interface_name);
6313   }
6314   vec_free (vam->sw_if_subif_table);
6315
6316   /* recreate the interface name hash table */
6317   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6318
6319   /* Get list of ethernets */
6320   M (SW_INTERFACE_DUMP, mp);
6321   mp->name_filter_valid = 1;
6322   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6323   S (mp);
6324
6325   /* and local / loopback interfaces */
6326   M (SW_INTERFACE_DUMP, mp);
6327   mp->name_filter_valid = 1;
6328   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6329   S (mp);
6330
6331   /* and packet-generator interfaces */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and vxlan-gpe tunnel interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6341            sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and vxlan tunnel interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and geneve tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and host (af_packet) interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and l2tpv3 tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6366            sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and GRE tunnel interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and LISP-GPE interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "lisp_gpe",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and IPSEC tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* Use a control ping for synchronization */
6389   MPING (CONTROL_PING, mp_ping);
6390   S (mp_ping);
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_flags (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_flags_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   u8 admin_up = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "admin-up"))
6410         admin_up = 1;
6411       else if (unformat (i, "admin-down"))
6412         admin_up = 0;
6413       else
6414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         sw_if_index_set = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_FLAGS, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->admin_up_down = admin_up;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply, return the good/bad news... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_rx_mode (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_rx_mode_t *mp;
6446   u32 sw_if_index;
6447   u8 sw_if_index_set = 0;
6448   int ret;
6449   u8 queue_id_valid = 0;
6450   u32 queue_id;
6451   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "queue %d", &queue_id))
6457         queue_id_valid = 1;
6458       else if (unformat (i, "polling"))
6459         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6460       else if (unformat (i, "interrupt"))
6461         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6462       else if (unformat (i, "adaptive"))
6463         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6464       else
6465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6479     {
6480       errmsg ("missing rx-mode");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (SW_INTERFACE_SET_RX_MODE, mp);
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->mode = mode;
6488   mp->queue_id_valid = queue_id_valid;
6489   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6490
6491   /* send it... */
6492   S (mp);
6493
6494   /* Wait for a reply, return the good/bad news... */
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_clear_stats (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_clear_stats_t *mp;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else
6516         break;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_CLEAR_STATS, mp);
6521
6522   if (sw_if_index_set == 1)
6523     mp->sw_if_index = ntohl (sw_if_index);
6524   else
6525     mp->sw_if_index = ~0;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply, return the good/bad news... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_add_del_address (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_add_del_address_t *mp;
6540   u32 sw_if_index;
6541   u8 sw_if_index_set = 0;
6542   u8 is_add = 1, del_all = 0;
6543   u32 address_length = 0;
6544   u8 v4_address_set = 0;
6545   u8 v6_address_set = 0;
6546   ip4_address_t v4address;
6547   ip6_address_t v6address;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "del-all"))
6554         del_all = 1;
6555       else if (unformat (i, "del"))
6556         is_add = 0;
6557       else
6558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "%U/%d",
6563                          unformat_ip4_address, &v4address, &address_length))
6564         v4_address_set = 1;
6565       else if (unformat (i, "%U/%d",
6566                          unformat_ip6_address, &v6address, &address_length))
6567         v6_address_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577   if (v4_address_set && v6_address_set)
6578     {
6579       errmsg ("both v4 and v6 addresses set");
6580       return -99;
6581     }
6582   if (!v4_address_set && !v6_address_set && !del_all)
6583     {
6584       errmsg ("no addresses set");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6590
6591   mp->sw_if_index = ntohl (sw_if_index);
6592   mp->is_add = is_add;
6593   mp->del_all = del_all;
6594   if (v6_address_set)
6595     {
6596       mp->is_ipv6 = 1;
6597       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6598     }
6599   else
6600     {
6601       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6602     }
6603   mp->address_length = address_length;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return good/bad news  */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_mpls_enable_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "disable"))
6631         enable = 0;
6632       else if (unformat (i, "dis"))
6633         enable = 0;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->enable = enable;
6649
6650   /* send it... */
6651   S (mp);
6652
6653   /* Wait for a reply... */
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_sw_interface_set_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_set_table_t *mp;
6663   u32 sw_if_index, vrf_id = 0;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "vrf %d", &vrf_id))
6676         ;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   /* Construct the API message */
6690   M (SW_INTERFACE_SET_TABLE, mp);
6691
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694   mp->vrf_id = ntohl (vrf_id);
6695
6696   /* send it... */
6697   S (mp);
6698
6699   /* Wait for a reply... */
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static void vl_api_sw_interface_get_table_reply_t_handler
6705   (vl_api_sw_interface_get_table_reply_t * mp)
6706 {
6707   vat_main_t *vam = &vat_main;
6708
6709   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6710
6711   vam->retval = ntohl (mp->retval);
6712   vam->result_ready = 1;
6713
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler_json
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t node;
6721
6722   vat_json_init_object (&node);
6723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6724   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6725
6726   vat_json_print (vam->ofp, &node);
6727   vat_json_free (&node);
6728
6729   vam->retval = ntohl (mp->retval);
6730   vam->result_ready = 1;
6731 }
6732
6733 static int
6734 api_sw_interface_get_table (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_get_table_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 is_ipv6 = 0;
6741   int ret;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "ipv6"))
6750         is_ipv6 = 1;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   M (SW_INTERFACE_GET_TABLE, mp);
6762   mp->sw_if_index = htonl (sw_if_index);
6763   mp->is_ipv6 = is_ipv6;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vpath (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vpath_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "enable"))
6788         is_enable = 1;
6789       else if (unformat (i, "disable"))
6790         is_enable = 0;
6791       else
6792         break;
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (SW_INTERFACE_SET_VPATH, mp);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->enable = is_enable;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply... */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6820   u32 sw_if_index = 0;
6821   u8 sw_if_index_set = 0;
6822   u8 is_enable = 1;
6823   u8 is_ipv6 = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "enable"))
6834         is_enable = 1;
6835       else if (unformat (i, "disable"))
6836         is_enable = 0;
6837       else if (unformat (i, "ip4"))
6838         is_ipv6 = 0;
6839       else if (unformat (i, "ip6"))
6840         is_ipv6 = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855   mp->enable = is_enable;
6856   mp->is_ipv6 = is_ipv6;
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863   return ret;
6864 }
6865
6866 static int
6867 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_geneve_bypass_t *mp;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_enable = 1;
6874   u8 is_ipv6 = 0;
6875   int ret;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "enable"))
6885         is_enable = 1;
6886       else if (unformat (i, "disable"))
6887         is_enable = 0;
6888       else if (unformat (i, "ip4"))
6889         is_ipv6 = 0;
6890       else if (unformat (i, "ip6"))
6891         is_ipv6 = 1;
6892       else
6893         break;
6894     }
6895
6896   if (sw_if_index_set == 0)
6897     {
6898       errmsg ("missing interface name or sw_if_index");
6899       return -99;
6900     }
6901
6902   /* Construct the API message */
6903   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6904
6905   mp->sw_if_index = ntohl (sw_if_index);
6906   mp->enable = is_enable;
6907   mp->is_ipv6 = is_ipv6;
6908
6909   /* send it... */
6910   S (mp);
6911
6912   /* Wait for a reply... */
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_xconnect_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 tx_sw_if_index;
6925   u8 tx_sw_if_index_set = 0;
6926   u8 enable = 1;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6933         rx_sw_if_index_set = 1;
6934       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6935         tx_sw_if_index_set = 1;
6936       else if (unformat (i, "rx"))
6937         {
6938           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939             {
6940               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6941                             &rx_sw_if_index))
6942                 rx_sw_if_index_set = 1;
6943             }
6944           else
6945             break;
6946         }
6947       else if (unformat (i, "tx"))
6948         {
6949           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950             {
6951               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6952                             &tx_sw_if_index))
6953                 tx_sw_if_index_set = 1;
6954             }
6955           else
6956             break;
6957         }
6958       else if (unformat (i, "enable"))
6959         enable = 1;
6960       else if (unformat (i, "disable"))
6961         enable = 0;
6962       else
6963         break;
6964     }
6965
6966   if (rx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing rx interface name or rx_sw_if_index");
6969       return -99;
6970     }
6971
6972   if (enable && (tx_sw_if_index_set == 0))
6973     {
6974       errmsg ("missing tx interface name or tx_sw_if_index");
6975       return -99;
6976     }
6977
6978   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6979
6980   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6981   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6982   mp->enable = enable;
6983
6984   S (mp);
6985   W (ret);
6986   return ret;
6987 }
6988
6989 static int
6990 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_sw_interface_set_l2_bridge_t *mp;
6994   u32 rx_sw_if_index;
6995   u8 rx_sw_if_index_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u8 bvi = 0;
6999   u32 shg = 0;
7000   u8 enable = 1;
7001   int ret;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7007         rx_sw_if_index_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else
7011         if (unformat
7012             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7013         rx_sw_if_index_set = 1;
7014       else if (unformat (i, "shg %d", &shg))
7015         ;
7016       else if (unformat (i, "bvi"))
7017         bvi = 1;
7018       else if (unformat (i, "enable"))
7019         enable = 1;
7020       else if (unformat (i, "disable"))
7021         enable = 0;
7022       else
7023         break;
7024     }
7025
7026   if (rx_sw_if_index_set == 0)
7027     {
7028       errmsg ("missing rx interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   if (enable && (bd_id_set == 0))
7033     {
7034       errmsg ("missing bridge domain");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7039
7040   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7041   mp->bd_id = ntohl (bd_id);
7042   mp->shg = (u8) shg;
7043   mp->bvi = bvi;
7044   mp->enable = enable;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_bridge_domain_dump (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_bridge_domain_dump_t *mp;
7056   vl_api_control_ping_t *mp_ping;
7057   u32 bd_id = ~0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "bd_id %d", &bd_id))
7064         ;
7065       else
7066         break;
7067     }
7068
7069   M (BRIDGE_DOMAIN_DUMP, mp);
7070   mp->bd_id = ntohl (bd_id);
7071   S (mp);
7072
7073   /* Use a control ping for synchronization */
7074   MPING (CONTROL_PING, mp_ping);
7075   S (mp_ping);
7076
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_bridge_domain_add_del (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_bridge_domain_add_del_t *mp;
7086   u32 bd_id = ~0;
7087   u8 is_add = 1;
7088   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7089   u8 *bd_tag = NULL;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id))
7097         ;
7098       else if (unformat (i, "flood %d", &flood))
7099         ;
7100       else if (unformat (i, "uu-flood %d", &uu_flood))
7101         ;
7102       else if (unformat (i, "forward %d", &forward))
7103         ;
7104       else if (unformat (i, "learn %d", &learn))
7105         ;
7106       else if (unformat (i, "arp-term %d", &arp_term))
7107         ;
7108       else if (unformat (i, "mac-age %d", &mac_age))
7109         ;
7110       else if (unformat (i, "bd-tag %s", &bd_tag))
7111         ;
7112       else if (unformat (i, "del"))
7113         {
7114           is_add = 0;
7115           flood = uu_flood = forward = learn = 0;
7116         }
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       ret = -99;
7125       goto done;
7126     }
7127
7128   if (mac_age > 255)
7129     {
7130       errmsg ("mac age must be less than 256 ");
7131       ret = -99;
7132       goto done;
7133     }
7134
7135   if ((bd_tag) && (vec_len (bd_tag) > 63))
7136     {
7137       errmsg ("bd-tag cannot be longer than 63");
7138       ret = -99;
7139       goto done;
7140     }
7141
7142   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7143
7144   mp->bd_id = ntohl (bd_id);
7145   mp->flood = flood;
7146   mp->uu_flood = uu_flood;
7147   mp->forward = forward;
7148   mp->learn = learn;
7149   mp->arp_term = arp_term;
7150   mp->is_add = is_add;
7151   mp->mac_age = (u8) mac_age;
7152   if (bd_tag)
7153     {
7154       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7155       mp->bd_tag[vec_len (bd_tag)] = 0;
7156     }
7157   S (mp);
7158   W (ret);
7159
7160 done:
7161   vec_free (bd_tag);
7162   return ret;
7163 }
7164
7165 static int
7166 api_l2fib_flush_bd (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_l2fib_flush_bd_t *mp;
7170   u32 bd_id = ~0;
7171   int ret;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id));
7177       else
7178         break;
7179     }
7180
7181   if (bd_id == ~0)
7182     {
7183       errmsg ("missing bridge domain");
7184       return -99;
7185     }
7186
7187   M (L2FIB_FLUSH_BD, mp);
7188
7189   mp->bd_id = htonl (bd_id);
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_l2fib_flush_int (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_l2fib_flush_int_t *mp;
7201   u32 sw_if_index = ~0;
7202   int ret;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "sw_if_index %d", &sw_if_index));
7208       else
7209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7210       else
7211         break;
7212     }
7213
7214   if (sw_if_index == ~0)
7215     {
7216       errmsg ("missing interface name or sw_if_index");
7217       return -99;
7218     }
7219
7220   M (L2FIB_FLUSH_INT, mp);
7221
7222   mp->sw_if_index = ntohl (sw_if_index);
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_add_del (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_add_del_t *mp;
7234   f64 timeout;
7235   u8 mac[6] = { 0 };
7236   u8 mac_set = 0;
7237   u32 bd_id;
7238   u8 bd_id_set = 0;
7239   u32 sw_if_index = ~0;
7240   u8 sw_if_index_set = 0;
7241   u8 is_add = 1;
7242   u8 static_mac = 0;
7243   u8 filter_mac = 0;
7244   u8 bvi_mac = 0;
7245   int count = 1;
7246   f64 before = 0;
7247   int j;
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7253         mac_set = 1;
7254       else if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7257         sw_if_index_set = 1;
7258       else if (unformat (i, "sw_if"))
7259         {
7260           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261             {
7262               if (unformat
7263                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7264                 sw_if_index_set = 1;
7265             }
7266           else
7267             break;
7268         }
7269       else if (unformat (i, "static"))
7270         static_mac = 1;
7271       else if (unformat (i, "filter"))
7272         {
7273           filter_mac = 1;
7274           static_mac = 1;
7275         }
7276       else if (unformat (i, "bvi"))
7277         {
7278           bvi_mac = 1;
7279           static_mac = 1;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "count %d", &count))
7284         ;
7285       else
7286         break;
7287     }
7288
7289   if (mac_set == 0)
7290     {
7291       errmsg ("missing mac address");
7292       return -99;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7302     {
7303       errmsg ("missing interface name or sw_if_index");
7304       return -99;
7305     }
7306
7307   if (count > 1)
7308     {
7309       /* Turn on async mode */
7310       vam->async_mode = 1;
7311       vam->async_errors = 0;
7312       before = vat_time_now (vam);
7313     }
7314
7315   for (j = 0; j < count; j++)
7316     {
7317       M (L2FIB_ADD_DEL, mp);
7318
7319       clib_memcpy (mp->mac, mac, 6);
7320       mp->bd_id = ntohl (bd_id);
7321       mp->is_add = is_add;
7322
7323       if (is_add)
7324         {
7325           mp->sw_if_index = ntohl (sw_if_index);
7326           mp->static_mac = static_mac;
7327           mp->filter_mac = filter_mac;
7328           mp->bvi_mac = bvi_mac;
7329         }
7330       increment_mac_address (mac);
7331       /* send it... */
7332       S (mp);
7333     }
7334
7335   if (count > 1)
7336     {
7337       vl_api_control_ping_t *mp_ping;
7338       f64 after;
7339
7340       /* Shut off async mode */
7341       vam->async_mode = 0;
7342
7343       MPING (CONTROL_PING, mp_ping);
7344       S (mp_ping);
7345
7346       timeout = vat_time_now (vam) + 1.0;
7347       while (vat_time_now (vam) < timeout)
7348         if (vam->result_ready == 1)
7349           goto out;
7350       vam->retval = -99;
7351
7352     out:
7353       if (vam->retval == -99)
7354         errmsg ("timeout");
7355
7356       if (vam->async_errors > 0)
7357         {
7358           errmsg ("%d asynchronous errors", vam->async_errors);
7359           vam->retval = -98;
7360         }
7361       vam->async_errors = 0;
7362       after = vat_time_now (vam);
7363
7364       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7365              count, after - before, count / (after - before));
7366     }
7367   else
7368     {
7369       int ret;
7370
7371       /* Wait for a reply... */
7372       W (ret);
7373       return ret;
7374     }
7375   /* Return the good/bad news */
7376   return (vam->retval);
7377 }
7378
7379 static int
7380 api_bridge_domain_set_mac_age (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bridge_domain_set_mac_age_t *mp;
7384   u32 bd_id = ~0;
7385   u32 mac_age = 0;
7386   int ret;
7387
7388   /* Parse args required to build the message */
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id));
7392       else if (unformat (i, "mac-age %d", &mac_age));
7393       else
7394         break;
7395     }
7396
7397   if (bd_id == ~0)
7398     {
7399       errmsg ("missing bridge domain");
7400       return -99;
7401     }
7402
7403   if (mac_age > 255)
7404     {
7405       errmsg ("mac age must be less than 256 ");
7406       return -99;
7407     }
7408
7409   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7410
7411   mp->bd_id = htonl (bd_id);
7412   mp->mac_age = (u8) mac_age;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_l2_flags (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_l2_flags_t *mp;
7424   u32 sw_if_index;
7425   u32 flags = 0;
7426   u8 sw_if_index_set = 0;
7427   u8 is_set = 0;
7428   int ret;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "sw_if_index %d", &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if"))
7436         {
7437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438             {
7439               if (unformat
7440                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7441                 sw_if_index_set = 1;
7442             }
7443           else
7444             break;
7445         }
7446       else if (unformat (i, "learn"))
7447         flags |= L2_LEARN;
7448       else if (unformat (i, "forward"))
7449         flags |= L2_FWD;
7450       else if (unformat (i, "flood"))
7451         flags |= L2_FLOOD;
7452       else if (unformat (i, "uu-flood"))
7453         flags |= L2_UU_FLOOD;
7454       else if (unformat (i, "arp-term"))
7455         flags |= L2_ARP_TERM;
7456       else if (unformat (i, "off"))
7457         is_set = 0;
7458       else if (unformat (i, "disable"))
7459         is_set = 0;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing interface name or sw_if_index");
7467       return -99;
7468     }
7469
7470   M (L2_FLAGS, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473   mp->feature_bitmap = ntohl (flags);
7474   mp->is_set = is_set;
7475
7476   S (mp);
7477   W (ret);
7478   return ret;
7479 }
7480
7481 static int
7482 api_bridge_flags (vat_main_t * vam)
7483 {
7484   unformat_input_t *i = vam->input;
7485   vl_api_bridge_flags_t *mp;
7486   u32 bd_id;
7487   u8 bd_id_set = 0;
7488   u8 is_set = 1;
7489   u32 flags = 0;
7490   int ret;
7491
7492   /* Parse args required to build the message */
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "bd_id %d", &bd_id))
7496         bd_id_set = 1;
7497       else if (unformat (i, "learn"))
7498         flags |= L2_LEARN;
7499       else if (unformat (i, "forward"))
7500         flags |= L2_FWD;
7501       else if (unformat (i, "flood"))
7502         flags |= L2_FLOOD;
7503       else if (unformat (i, "uu-flood"))
7504         flags |= L2_UU_FLOOD;
7505       else if (unformat (i, "arp-term"))
7506         flags |= L2_ARP_TERM;
7507       else if (unformat (i, "off"))
7508         is_set = 0;
7509       else if (unformat (i, "disable"))
7510         is_set = 0;
7511       else
7512         break;
7513     }
7514
7515   if (bd_id_set == 0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   M (BRIDGE_FLAGS, mp);
7522
7523   mp->bd_id = ntohl (bd_id);
7524   mp->feature_bitmap = ntohl (flags);
7525   mp->is_set = is_set;
7526
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_bd_ip_mac_add_del (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_bd_ip_mac_add_del_t *mp;
7537   u32 bd_id;
7538   u8 is_ipv6 = 0;
7539   u8 is_add = 1;
7540   u8 bd_id_set = 0;
7541   u8 ip_set = 0;
7542   u8 mac_set = 0;
7543   ip4_address_t v4addr;
7544   ip6_address_t v6addr;
7545   u8 macaddr[6];
7546   int ret;
7547
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "bd_id %d", &bd_id))
7553         {
7554           bd_id_set++;
7555         }
7556       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7557         {
7558           ip_set++;
7559         }
7560       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7561         {
7562           ip_set++;
7563           is_ipv6++;
7564         }
7565       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7566         {
7567           mac_set++;
7568         }
7569       else if (unformat (i, "del"))
7570         is_add = 0;
7571       else
7572         break;
7573     }
7574
7575   if (bd_id_set == 0)
7576     {
7577       errmsg ("missing bridge domain");
7578       return -99;
7579     }
7580   else if (ip_set == 0)
7581     {
7582       errmsg ("missing IP address");
7583       return -99;
7584     }
7585   else if (mac_set == 0)
7586     {
7587       errmsg ("missing MAC address");
7588       return -99;
7589     }
7590
7591   M (BD_IP_MAC_ADD_DEL, mp);
7592
7593   mp->bd_id = ntohl (bd_id);
7594   mp->is_ipv6 = is_ipv6;
7595   mp->is_add = is_add;
7596   if (is_ipv6)
7597     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7598   else
7599     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7600   clib_memcpy (mp->mac_address, macaddr, 6);
7601   S (mp);
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_connect (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_connect_t *mp;
7611   u8 mac_address[6];
7612   u8 random_mac = 1;
7613   u8 name_set = 0;
7614   u8 *tap_name;
7615   u8 *tag = 0;
7616   ip4_address_t ip4_address;
7617   u32 ip4_mask_width;
7618   int ip4_address_set = 0;
7619   ip6_address_t ip6_address;
7620   u32 ip6_mask_width;
7621   int ip6_address_set = 0;
7622   int ret;
7623
7624   memset (mac_address, 0, sizeof (mac_address));
7625
7626   /* Parse args required to build the message */
7627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7630         {
7631           random_mac = 0;
7632         }
7633       else if (unformat (i, "random-mac"))
7634         random_mac = 1;
7635       else if (unformat (i, "tapname %s", &tap_name))
7636         name_set = 1;
7637       else if (unformat (i, "tag %s", &tag))
7638         ;
7639       else if (unformat (i, "address %U/%d",
7640                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7641         ip4_address_set = 1;
7642       else if (unformat (i, "address %U/%d",
7643                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7644         ip6_address_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (name_set == 0)
7650     {
7651       errmsg ("missing tap name");
7652       return -99;
7653     }
7654   if (vec_len (tap_name) > 63)
7655     {
7656       errmsg ("tap name too long");
7657       return -99;
7658     }
7659   vec_add1 (tap_name, 0);
7660
7661   if (vec_len (tag) > 63)
7662     {
7663       errmsg ("tag too long");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_CONNECT, mp);
7669
7670   mp->use_random_mac = random_mac;
7671   clib_memcpy (mp->mac_address, mac_address, 6);
7672   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7673   if (tag)
7674     clib_memcpy (mp->tag, tag, vec_len (tag));
7675
7676   if (ip4_address_set)
7677     {
7678       mp->ip4_address_set = 1;
7679       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7680       mp->ip4_mask_width = ip4_mask_width;
7681     }
7682   if (ip6_address_set)
7683     {
7684       mp->ip6_address_set = 1;
7685       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7686       mp->ip6_mask_width = ip6_mask_width;
7687     }
7688
7689   vec_free (tap_name);
7690   vec_free (tag);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_tap_modify (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_tap_modify_t *mp;
7705   u8 mac_address[6];
7706   u8 random_mac = 1;
7707   u8 name_set = 0;
7708   u8 *tap_name;
7709   u32 sw_if_index = ~0;
7710   u8 sw_if_index_set = 0;
7711   int ret;
7712
7713   memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7723         {
7724           random_mac = 0;
7725         }
7726       else if (unformat (i, "random-mac"))
7727         random_mac = 1;
7728       else if (unformat (i, "tapname %s", &tap_name))
7729         name_set = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing vpp interface name");
7737       return -99;
7738     }
7739   if (name_set == 0)
7740     {
7741       errmsg ("missing tap name");
7742       return -99;
7743     }
7744   if (vec_len (tap_name) > 63)
7745     {
7746       errmsg ("tap name too long");
7747     }
7748   vec_add1 (tap_name, 0);
7749
7750   /* Construct the API message */
7751   M (TAP_MODIFY, mp);
7752
7753   mp->use_random_mac = random_mac;
7754   mp->sw_if_index = ntohl (sw_if_index);
7755   clib_memcpy (mp->mac_address, mac_address, 6);
7756   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7757   vec_free (tap_name);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_tap_delete (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_tap_delete_t *mp;
7772   u32 sw_if_index = ~0;
7773   u8 sw_if_index_set = 0;
7774   int ret;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing vpp interface name");
7790       return -99;
7791     }
7792
7793   /* Construct the API message */
7794   M (TAP_DELETE, mp);
7795
7796   mp->sw_if_index = ntohl (sw_if_index);
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply... */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 static int
7807 api_tap_create_v2 (vat_main_t * vam)
7808 {
7809   unformat_input_t *i = vam->input;
7810   vl_api_tap_create_v2_t *mp;
7811   u8 mac_address[6];
7812   u8 random_mac = 1;
7813   u32 id = ~0;
7814   u8 *host_if_name = 0;
7815   u8 *host_ns = 0;
7816   u8 host_mac_addr[6];
7817   u8 host_mac_addr_set = 0;
7818   u8 *host_bridge = 0;
7819   ip4_address_t host_ip4_addr;
7820   u32 host_ip4_prefix_len = 0;
7821   ip6_address_t host_ip6_addr;
7822   u32 host_ip6_prefix_len = 0;
7823   int ret;
7824   int rx_ring_sz = 0, tx_ring_sz = 0;
7825
7826   memset (mac_address, 0, sizeof (mac_address));
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7832         {
7833           random_mac = 0;
7834         }
7835       else if (unformat (i, "id %s", &id))
7836         ;
7837       else if (unformat (i, "host-if-name %s", &host_if_name))
7838         ;
7839       else if (unformat (i, "host-ns %s", &host_ns))
7840         ;
7841       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7842                          host_mac_addr))
7843         host_mac_addr_set = 1;
7844       else if (unformat (i, "host-bridge %s", &host_bridge))
7845         ;
7846       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7847                          &host_ip4_addr, &host_ip4_prefix_len))
7848         ;
7849       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7850                          &host_ip6_addr, &host_ip6_prefix_len))
7851         ;
7852       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7853         ;
7854       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7855         ;
7856       else
7857         break;
7858     }
7859
7860   if (vec_len (host_if_name) > 63)
7861     {
7862       errmsg ("tap name too long. ");
7863       return -99;
7864     }
7865   if (vec_len (host_ns) > 63)
7866     {
7867       errmsg ("host name space too long. ");
7868       return -99;
7869     }
7870   if (vec_len (host_bridge) > 63)
7871     {
7872       errmsg ("host bridge name too long. ");
7873       return -99;
7874     }
7875   if (host_ip4_prefix_len > 32)
7876     {
7877       errmsg ("host ip4 prefix length not valid. ");
7878       return -99;
7879     }
7880   if (host_ip6_prefix_len > 128)
7881     {
7882       errmsg ("host ip6 prefix length not valid. ");
7883       return -99;
7884     }
7885   if (!is_pow2 (rx_ring_sz))
7886     {
7887       errmsg ("rx ring size must be power of 2. ");
7888       return -99;
7889     }
7890   if (rx_ring_sz > 32768)
7891     {
7892       errmsg ("rx ring size must be 32768 or lower. ");
7893       return -99;
7894     }
7895   if (!is_pow2 (tx_ring_sz))
7896     {
7897       errmsg ("tx ring size must be power of 2. ");
7898       return -99;
7899     }
7900   if (tx_ring_sz > 32768)
7901     {
7902       errmsg ("tx ring size must be 32768 or lower. ");
7903       return -99;
7904     }
7905
7906   /* Construct the API message */
7907   M (TAP_CREATE_V2, mp);
7908
7909   mp->use_random_mac = random_mac;
7910
7911   mp->id = id;
7912   mp->host_namespace_set = host_ns != 0;
7913   mp->host_bridge_set = host_bridge != 0;
7914   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7915   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7916   mp->rx_ring_sz = rx_ring_sz;
7917   mp->tx_ring_sz = tx_ring_sz;
7918
7919   if (random_mac)
7920     clib_memcpy (mp->mac_address, mac_address, 6);
7921   if (host_mac_addr_set)
7922     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7923   if (host_if_name)
7924     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7925   if (host_ns)
7926     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7927   if (host_bridge)
7928     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7929   if (host_ip4_prefix_len)
7930     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7931   if (host_ip4_prefix_len)
7932     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7933
7934
7935   vec_free (host_ns);
7936   vec_free (host_if_name);
7937   vec_free (host_bridge);
7938
7939   /* send it... */
7940   S (mp);
7941
7942   /* Wait for a reply... */
7943   W (ret);
7944   return ret;
7945 }
7946
7947 static int
7948 api_tap_delete_v2 (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_tap_delete_v2_t *mp;
7952   u32 sw_if_index = ~0;
7953   u8 sw_if_index_set = 0;
7954   int ret;
7955
7956   /* Parse args required to build the message */
7957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7960         sw_if_index_set = 1;
7961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7962         sw_if_index_set = 1;
7963       else
7964         break;
7965     }
7966
7967   if (sw_if_index_set == 0)
7968     {
7969       errmsg ("missing vpp interface name. ");
7970       return -99;
7971     }
7972
7973   /* Construct the API message */
7974   M (TAP_DELETE_V2, mp);
7975
7976   mp->sw_if_index = ntohl (sw_if_index);
7977
7978   /* send it... */
7979   S (mp);
7980
7981   /* Wait for a reply... */
7982   W (ret);
7983   return ret;
7984 }
7985
7986 static int
7987 api_ip_table_add_del (vat_main_t * vam)
7988 {
7989   unformat_input_t *i = vam->input;
7990   vl_api_ip_table_add_del_t *mp;
7991   u32 table_id = ~0;
7992   u8 is_ipv6 = 0;
7993   u8 is_add = 1;
7994   int ret = 0;
7995
7996   /* Parse args required to build the message */
7997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7998     {
7999       if (unformat (i, "ipv6"))
8000         is_ipv6 = 1;
8001       else if (unformat (i, "del"))
8002         is_add = 0;
8003       else if (unformat (i, "add"))
8004         is_add = 1;
8005       else if (unformat (i, "table %d", &table_id))
8006         ;
8007       else
8008         {
8009           clib_warning ("parse error '%U'", format_unformat_error, i);
8010           return -99;
8011         }
8012     }
8013
8014   if (~0 == table_id)
8015     {
8016       errmsg ("missing table-ID");
8017       return -99;
8018     }
8019
8020   /* Construct the API message */
8021   M (IP_TABLE_ADD_DEL, mp);
8022
8023   mp->table_id = ntohl (table_id);
8024   mp->is_ipv6 = is_ipv6;
8025   mp->is_add = is_add;
8026
8027   /* send it... */
8028   S (mp);
8029
8030   /* Wait for a reply... */
8031   W (ret);
8032
8033   return ret;
8034 }
8035
8036 static int
8037 api_ip_add_del_route (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_add_del_route_t *mp;
8041   u32 sw_if_index = ~0, vrf_id = 0;
8042   u8 is_ipv6 = 0;
8043   u8 is_local = 0, is_drop = 0;
8044   u8 is_unreach = 0, is_prohibit = 0;
8045   u8 is_add = 1;
8046   u32 next_hop_weight = 1;
8047   u8 is_multipath = 0;
8048   u8 address_set = 0;
8049   u8 address_length_set = 0;
8050   u32 next_hop_table_id = 0;
8051   u32 resolve_attempts = 0;
8052   u32 dst_address_length = 0;
8053   u8 next_hop_set = 0;
8054   ip4_address_t v4_dst_address, v4_next_hop_address;
8055   ip6_address_t v6_dst_address, v6_next_hop_address;
8056   int count = 1;
8057   int j;
8058   f64 before = 0;
8059   u32 random_add_del = 0;
8060   u32 *random_vector = 0;
8061   uword *random_hash;
8062   u32 random_seed = 0xdeaddabe;
8063   u32 classify_table_index = ~0;
8064   u8 is_classify = 0;
8065   u8 resolve_host = 0, resolve_attached = 0;
8066   mpls_label_t *next_hop_out_label_stack = NULL;
8067   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8068   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8069
8070   /* Parse args required to build the message */
8071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8074         ;
8075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8076         ;
8077       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8078         {
8079           address_set = 1;
8080           is_ipv6 = 0;
8081         }
8082       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8083         {
8084           address_set = 1;
8085           is_ipv6 = 1;
8086         }
8087       else if (unformat (i, "/%d", &dst_address_length))
8088         {
8089           address_length_set = 1;
8090         }
8091
8092       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8093                                          &v4_next_hop_address))
8094         {
8095           next_hop_set = 1;
8096         }
8097       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8098                                          &v6_next_hop_address))
8099         {
8100           next_hop_set = 1;
8101         }
8102       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8103         ;
8104       else if (unformat (i, "weight %d", &next_hop_weight))
8105         ;
8106       else if (unformat (i, "drop"))
8107         {
8108           is_drop = 1;
8109         }
8110       else if (unformat (i, "null-send-unreach"))
8111         {
8112           is_unreach = 1;
8113         }
8114       else if (unformat (i, "null-send-prohibit"))
8115         {
8116           is_prohibit = 1;
8117         }
8118       else if (unformat (i, "local"))
8119         {
8120           is_local = 1;
8121         }
8122       else if (unformat (i, "classify %d", &classify_table_index))
8123         {
8124           is_classify = 1;
8125         }
8126       else if (unformat (i, "del"))
8127         is_add = 0;
8128       else if (unformat (i, "add"))
8129         is_add = 1;
8130       else if (unformat (i, "resolve-via-host"))
8131         resolve_host = 1;
8132       else if (unformat (i, "resolve-via-attached"))
8133         resolve_attached = 1;
8134       else if (unformat (i, "multipath"))
8135         is_multipath = 1;
8136       else if (unformat (i, "vrf %d", &vrf_id))
8137         ;
8138       else if (unformat (i, "count %d", &count))
8139         ;
8140       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8141         ;
8142       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8143         ;
8144       else if (unformat (i, "out-label %d", &next_hop_out_label))
8145         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8146       else if (unformat (i, "via-label %d", &next_hop_via_label))
8147         ;
8148       else if (unformat (i, "random"))
8149         random_add_del = 1;
8150       else if (unformat (i, "seed %d", &random_seed))
8151         ;
8152       else
8153         {
8154           clib_warning ("parse error '%U'", format_unformat_error, i);
8155           return -99;
8156         }
8157     }
8158
8159   if (!next_hop_set && !is_drop && !is_local &&
8160       !is_classify && !is_unreach && !is_prohibit &&
8161       MPLS_LABEL_INVALID == next_hop_via_label)
8162     {
8163       errmsg
8164         ("next hop / local / drop / unreach / prohibit / classify not set");
8165       return -99;
8166     }
8167
8168   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8169     {
8170       errmsg ("next hop and next-hop via label set");
8171       return -99;
8172     }
8173   if (address_set == 0)
8174     {
8175       errmsg ("missing addresses");
8176       return -99;
8177     }
8178
8179   if (address_length_set == 0)
8180     {
8181       errmsg ("missing address length");
8182       return -99;
8183     }
8184
8185   /* Generate a pile of unique, random routes */
8186   if (random_add_del)
8187     {
8188       u32 this_random_address;
8189       random_hash = hash_create (count, sizeof (uword));
8190
8191       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8192       for (j = 0; j <= count; j++)
8193         {
8194           do
8195             {
8196               this_random_address = random_u32 (&random_seed);
8197               this_random_address =
8198                 clib_host_to_net_u32 (this_random_address);
8199             }
8200           while (hash_get (random_hash, this_random_address));
8201           vec_add1 (random_vector, this_random_address);
8202           hash_set (random_hash, this_random_address, 1);
8203         }
8204       hash_free (random_hash);
8205       v4_dst_address.as_u32 = random_vector[0];
8206     }
8207
8208   if (count > 1)
8209     {
8210       /* Turn on async mode */
8211       vam->async_mode = 1;
8212       vam->async_errors = 0;
8213       before = vat_time_now (vam);
8214     }
8215
8216   for (j = 0; j < count; j++)
8217     {
8218       /* Construct the API message */
8219       M2 (IP_ADD_DEL_ROUTE, mp,
8220           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8221
8222       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8223       mp->table_id = ntohl (vrf_id);
8224
8225       mp->is_add = is_add;
8226       mp->is_drop = is_drop;
8227       mp->is_unreach = is_unreach;
8228       mp->is_prohibit = is_prohibit;
8229       mp->is_ipv6 = is_ipv6;
8230       mp->is_local = is_local;
8231       mp->is_classify = is_classify;
8232       mp->is_multipath = is_multipath;
8233       mp->is_resolve_host = resolve_host;
8234       mp->is_resolve_attached = resolve_attached;
8235       mp->next_hop_weight = next_hop_weight;
8236       mp->dst_address_length = dst_address_length;
8237       mp->next_hop_table_id = ntohl (next_hop_table_id);
8238       mp->classify_table_index = ntohl (classify_table_index);
8239       mp->next_hop_via_label = ntohl (next_hop_via_label);
8240       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8241       if (0 != mp->next_hop_n_out_labels)
8242         {
8243           memcpy (mp->next_hop_out_label_stack,
8244                   next_hop_out_label_stack,
8245                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8246           vec_free (next_hop_out_label_stack);
8247         }
8248
8249       if (is_ipv6)
8250         {
8251           clib_memcpy (mp->dst_address, &v6_dst_address,
8252                        sizeof (v6_dst_address));
8253           if (next_hop_set)
8254             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8255                          sizeof (v6_next_hop_address));
8256           increment_v6_address (&v6_dst_address);
8257         }
8258       else
8259         {
8260           clib_memcpy (mp->dst_address, &v4_dst_address,
8261                        sizeof (v4_dst_address));
8262           if (next_hop_set)
8263             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8264                          sizeof (v4_next_hop_address));
8265           if (random_add_del)
8266             v4_dst_address.as_u32 = random_vector[j + 1];
8267           else
8268             increment_v4_address (&v4_dst_address);
8269         }
8270       /* send it... */
8271       S (mp);
8272       /* If we receive SIGTERM, stop now... */
8273       if (vam->do_exit)
8274         break;
8275     }
8276
8277   /* When testing multiple add/del ops, use a control-ping to sync */
8278   if (count > 1)
8279     {
8280       vl_api_control_ping_t *mp_ping;
8281       f64 after;
8282       f64 timeout;
8283
8284       /* Shut off async mode */
8285       vam->async_mode = 0;
8286
8287       MPING (CONTROL_PING, mp_ping);
8288       S (mp_ping);
8289
8290       timeout = vat_time_now (vam) + 1.0;
8291       while (vat_time_now (vam) < timeout)
8292         if (vam->result_ready == 1)
8293           goto out;
8294       vam->retval = -99;
8295
8296     out:
8297       if (vam->retval == -99)
8298         errmsg ("timeout");
8299
8300       if (vam->async_errors > 0)
8301         {
8302           errmsg ("%d asynchronous errors", vam->async_errors);
8303           vam->retval = -98;
8304         }
8305       vam->async_errors = 0;
8306       after = vat_time_now (vam);
8307
8308       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8309       if (j > 0)
8310         count = j;
8311
8312       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8313              count, after - before, count / (after - before));
8314     }
8315   else
8316     {
8317       int ret;
8318
8319       /* Wait for a reply... */
8320       W (ret);
8321       return ret;
8322     }
8323
8324   /* Return the good/bad news */
8325   return (vam->retval);
8326 }
8327
8328 static int
8329 api_ip_mroute_add_del (vat_main_t * vam)
8330 {
8331   unformat_input_t *i = vam->input;
8332   vl_api_ip_mroute_add_del_t *mp;
8333   u32 sw_if_index = ~0, vrf_id = 0;
8334   u8 is_ipv6 = 0;
8335   u8 is_local = 0;
8336   u8 is_add = 1;
8337   u8 address_set = 0;
8338   u32 grp_address_length = 0;
8339   ip4_address_t v4_grp_address, v4_src_address;
8340   ip6_address_t v6_grp_address, v6_src_address;
8341   mfib_itf_flags_t iflags = 0;
8342   mfib_entry_flags_t eflags = 0;
8343   int ret;
8344
8345   /* Parse args required to build the message */
8346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347     {
8348       if (unformat (i, "sw_if_index %d", &sw_if_index))
8349         ;
8350       else if (unformat (i, "%U %U",
8351                          unformat_ip4_address, &v4_src_address,
8352                          unformat_ip4_address, &v4_grp_address))
8353         {
8354           grp_address_length = 64;
8355           address_set = 1;
8356           is_ipv6 = 0;
8357         }
8358       else if (unformat (i, "%U %U",
8359                          unformat_ip6_address, &v6_src_address,
8360                          unformat_ip6_address, &v6_grp_address))
8361         {
8362           grp_address_length = 256;
8363           address_set = 1;
8364           is_ipv6 = 1;
8365         }
8366       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8367         {
8368           memset (&v4_src_address, 0, sizeof (v4_src_address));
8369           grp_address_length = 32;
8370           address_set = 1;
8371           is_ipv6 = 0;
8372         }
8373       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8374         {
8375           memset (&v6_src_address, 0, sizeof (v6_src_address));
8376           grp_address_length = 128;
8377           address_set = 1;
8378           is_ipv6 = 1;
8379         }
8380       else if (unformat (i, "/%d", &grp_address_length))
8381         ;
8382       else if (unformat (i, "local"))
8383         {
8384           is_local = 1;
8385         }
8386       else if (unformat (i, "del"))
8387         is_add = 0;
8388       else if (unformat (i, "add"))
8389         is_add = 1;
8390       else if (unformat (i, "vrf %d", &vrf_id))
8391         ;
8392       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8393         ;
8394       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8395         ;
8396       else
8397         {
8398           clib_warning ("parse error '%U'", format_unformat_error, i);
8399           return -99;
8400         }
8401     }
8402
8403   if (address_set == 0)
8404     {
8405       errmsg ("missing addresses\n");
8406       return -99;
8407     }
8408
8409   /* Construct the API message */
8410   M (IP_MROUTE_ADD_DEL, mp);
8411
8412   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8413   mp->table_id = ntohl (vrf_id);
8414
8415   mp->is_add = is_add;
8416   mp->is_ipv6 = is_ipv6;
8417   mp->is_local = is_local;
8418   mp->itf_flags = ntohl (iflags);
8419   mp->entry_flags = ntohl (eflags);
8420   mp->grp_address_length = grp_address_length;
8421   mp->grp_address_length = ntohs (mp->grp_address_length);
8422
8423   if (is_ipv6)
8424     {
8425       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8426       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8427     }
8428   else
8429     {
8430       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8431       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8432
8433     }
8434
8435   /* send it... */
8436   S (mp);
8437   /* Wait for a reply... */
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static int
8443 api_mpls_table_add_del (vat_main_t * vam)
8444 {
8445   unformat_input_t *i = vam->input;
8446   vl_api_mpls_table_add_del_t *mp;
8447   u32 table_id = ~0;
8448   u8 is_add = 1;
8449   int ret = 0;
8450
8451   /* Parse args required to build the message */
8452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8453     {
8454       if (unformat (i, "table %d", &table_id))
8455         ;
8456       else if (unformat (i, "del"))
8457         is_add = 0;
8458       else if (unformat (i, "add"))
8459         is_add = 1;
8460       else
8461         {
8462           clib_warning ("parse error '%U'", format_unformat_error, i);
8463           return -99;
8464         }
8465     }
8466
8467   if (~0 == table_id)
8468     {
8469       errmsg ("missing table-ID");
8470       return -99;
8471     }
8472
8473   /* Construct the API message */
8474   M (MPLS_TABLE_ADD_DEL, mp);
8475
8476   mp->mt_table_id = ntohl (table_id);
8477   mp->mt_is_add = is_add;
8478
8479   /* send it... */
8480   S (mp);
8481
8482   /* Wait for a reply... */
8483   W (ret);
8484
8485   return ret;
8486 }
8487
8488 static int
8489 api_mpls_route_add_del (vat_main_t * vam)
8490 {
8491   unformat_input_t *i = vam->input;
8492   vl_api_mpls_route_add_del_t *mp;
8493   u32 sw_if_index = ~0, table_id = 0;
8494   u8 is_add = 1;
8495   u32 next_hop_weight = 1;
8496   u8 is_multipath = 0;
8497   u32 next_hop_table_id = 0;
8498   u8 next_hop_set = 0;
8499   ip4_address_t v4_next_hop_address = {
8500     .as_u32 = 0,
8501   };
8502   ip6_address_t v6_next_hop_address = { {0} };
8503   int count = 1;
8504   int j;
8505   f64 before = 0;
8506   u32 classify_table_index = ~0;
8507   u8 is_classify = 0;
8508   u8 resolve_host = 0, resolve_attached = 0;
8509   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8510   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8511   mpls_label_t *next_hop_out_label_stack = NULL;
8512   mpls_label_t local_label = MPLS_LABEL_INVALID;
8513   u8 is_eos = 0;
8514   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8515
8516   /* Parse args required to build the message */
8517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8518     {
8519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8520         ;
8521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8522         ;
8523       else if (unformat (i, "%d", &local_label))
8524         ;
8525       else if (unformat (i, "eos"))
8526         is_eos = 1;
8527       else if (unformat (i, "non-eos"))
8528         is_eos = 0;
8529       else if (unformat (i, "via %U", unformat_ip4_address,
8530                          &v4_next_hop_address))
8531         {
8532           next_hop_set = 1;
8533           next_hop_proto = DPO_PROTO_IP4;
8534         }
8535       else if (unformat (i, "via %U", unformat_ip6_address,
8536                          &v6_next_hop_address))
8537         {
8538           next_hop_set = 1;
8539           next_hop_proto = DPO_PROTO_IP6;
8540         }
8541       else if (unformat (i, "weight %d", &next_hop_weight))
8542         ;
8543       else if (unformat (i, "classify %d", &classify_table_index))
8544         {
8545           is_classify = 1;
8546         }
8547       else if (unformat (i, "del"))
8548         is_add = 0;
8549       else if (unformat (i, "add"))
8550         is_add = 1;
8551       else if (unformat (i, "resolve-via-host"))
8552         resolve_host = 1;
8553       else if (unformat (i, "resolve-via-attached"))
8554         resolve_attached = 1;
8555       else if (unformat (i, "multipath"))
8556         is_multipath = 1;
8557       else if (unformat (i, "count %d", &count))
8558         ;
8559       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8560         {
8561           next_hop_set = 1;
8562           next_hop_proto = DPO_PROTO_IP4;
8563         }
8564       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8565         {
8566           next_hop_set = 1;
8567           next_hop_proto = DPO_PROTO_IP6;
8568         }
8569       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8570         ;
8571       else if (unformat (i, "via-label %d", &next_hop_via_label))
8572         ;
8573       else if (unformat (i, "out-label %d", &next_hop_out_label))
8574         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8575       else
8576         {
8577           clib_warning ("parse error '%U'", format_unformat_error, i);
8578           return -99;
8579         }
8580     }
8581
8582   if (!next_hop_set && !is_classify)
8583     {
8584       errmsg ("next hop / classify not set");
8585       return -99;
8586     }
8587
8588   if (MPLS_LABEL_INVALID == local_label)
8589     {
8590       errmsg ("missing label");
8591       return -99;
8592     }
8593
8594   if (count > 1)
8595     {
8596       /* Turn on async mode */
8597       vam->async_mode = 1;
8598       vam->async_errors = 0;
8599       before = vat_time_now (vam);
8600     }
8601
8602   for (j = 0; j < count; j++)
8603     {
8604       /* Construct the API message */
8605       M2 (MPLS_ROUTE_ADD_DEL, mp,
8606           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8607
8608       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8609       mp->mr_table_id = ntohl (table_id);
8610
8611       mp->mr_is_add = is_add;
8612       mp->mr_next_hop_proto = next_hop_proto;
8613       mp->mr_is_classify = is_classify;
8614       mp->mr_is_multipath = is_multipath;
8615       mp->mr_is_resolve_host = resolve_host;
8616       mp->mr_is_resolve_attached = resolve_attached;
8617       mp->mr_next_hop_weight = next_hop_weight;
8618       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8619       mp->mr_classify_table_index = ntohl (classify_table_index);
8620       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8621       mp->mr_label = ntohl (local_label);
8622       mp->mr_eos = is_eos;
8623
8624       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8625       if (0 != mp->mr_next_hop_n_out_labels)
8626         {
8627           memcpy (mp->mr_next_hop_out_label_stack,
8628                   next_hop_out_label_stack,
8629                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8630           vec_free (next_hop_out_label_stack);
8631         }
8632
8633       if (next_hop_set)
8634         {
8635           if (DPO_PROTO_IP4 == next_hop_proto)
8636             {
8637               clib_memcpy (mp->mr_next_hop,
8638                            &v4_next_hop_address,
8639                            sizeof (v4_next_hop_address));
8640             }
8641           else if (DPO_PROTO_IP6 == next_hop_proto)
8642
8643             {
8644               clib_memcpy (mp->mr_next_hop,
8645                            &v6_next_hop_address,
8646                            sizeof (v6_next_hop_address));
8647             }
8648         }
8649       local_label++;
8650
8651       /* send it... */
8652       S (mp);
8653       /* If we receive SIGTERM, stop now... */
8654       if (vam->do_exit)
8655         break;
8656     }
8657
8658   /* When testing multiple add/del ops, use a control-ping to sync */
8659   if (count > 1)
8660     {
8661       vl_api_control_ping_t *mp_ping;
8662       f64 after;
8663       f64 timeout;
8664
8665       /* Shut off async mode */
8666       vam->async_mode = 0;
8667
8668       MPING (CONTROL_PING, mp_ping);
8669       S (mp_ping);
8670
8671       timeout = vat_time_now (vam) + 1.0;
8672       while (vat_time_now (vam) < timeout)
8673         if (vam->result_ready == 1)
8674           goto out;
8675       vam->retval = -99;
8676
8677     out:
8678       if (vam->retval == -99)
8679         errmsg ("timeout");
8680
8681       if (vam->async_errors > 0)
8682         {
8683           errmsg ("%d asynchronous errors", vam->async_errors);
8684           vam->retval = -98;
8685         }
8686       vam->async_errors = 0;
8687       after = vat_time_now (vam);
8688
8689       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8690       if (j > 0)
8691         count = j;
8692
8693       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8694              count, after - before, count / (after - before));
8695     }
8696   else
8697     {
8698       int ret;
8699
8700       /* Wait for a reply... */
8701       W (ret);
8702       return ret;
8703     }
8704
8705   /* Return the good/bad news */
8706   return (vam->retval);
8707 }
8708
8709 static int
8710 api_mpls_ip_bind_unbind (vat_main_t * vam)
8711 {
8712   unformat_input_t *i = vam->input;
8713   vl_api_mpls_ip_bind_unbind_t *mp;
8714   u32 ip_table_id = 0;
8715   u8 is_bind = 1;
8716   u8 is_ip4 = 1;
8717   ip4_address_t v4_address;
8718   ip6_address_t v6_address;
8719   u32 address_length;
8720   u8 address_set = 0;
8721   mpls_label_t local_label = MPLS_LABEL_INVALID;
8722   int ret;
8723
8724   /* Parse args required to build the message */
8725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8726     {
8727       if (unformat (i, "%U/%d", unformat_ip4_address,
8728                     &v4_address, &address_length))
8729         {
8730           is_ip4 = 1;
8731           address_set = 1;
8732         }
8733       else if (unformat (i, "%U/%d", unformat_ip6_address,
8734                          &v6_address, &address_length))
8735         {
8736           is_ip4 = 0;
8737           address_set = 1;
8738         }
8739       else if (unformat (i, "%d", &local_label))
8740         ;
8741       else if (unformat (i, "table-id %d", &ip_table_id))
8742         ;
8743       else if (unformat (i, "unbind"))
8744         is_bind = 0;
8745       else if (unformat (i, "bind"))
8746         is_bind = 1;
8747       else
8748         {
8749           clib_warning ("parse error '%U'", format_unformat_error, i);
8750           return -99;
8751         }
8752     }
8753
8754   if (!address_set)
8755     {
8756       errmsg ("IP addres not set");
8757       return -99;
8758     }
8759
8760   if (MPLS_LABEL_INVALID == local_label)
8761     {
8762       errmsg ("missing label");
8763       return -99;
8764     }
8765
8766   /* Construct the API message */
8767   M (MPLS_IP_BIND_UNBIND, mp);
8768
8769   mp->mb_is_bind = is_bind;
8770   mp->mb_is_ip4 = is_ip4;
8771   mp->mb_ip_table_id = ntohl (ip_table_id);
8772   mp->mb_mpls_table_id = 0;
8773   mp->mb_label = ntohl (local_label);
8774   mp->mb_address_length = address_length;
8775
8776   if (is_ip4)
8777     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8778   else
8779     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8780
8781   /* send it... */
8782   S (mp);
8783
8784   /* Wait for a reply... */
8785   W (ret);
8786   return ret;
8787 }
8788
8789 static int
8790 api_bier_table_add_del (vat_main_t * vam)
8791 {
8792   unformat_input_t *i = vam->input;
8793   vl_api_bier_table_add_del_t *mp;
8794   u8 is_add = 1;
8795   u32 set = 0, sub_domain = 0, hdr_len = 3;
8796   mpls_label_t local_label = MPLS_LABEL_INVALID;
8797   int ret;
8798
8799   /* Parse args required to build the message */
8800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8801     {
8802       if (unformat (i, "sub-domain %d", &sub_domain))
8803         ;
8804       else if (unformat (i, "set %d", &set))
8805         ;
8806       else if (unformat (i, "label %d", &local_label))
8807         ;
8808       else if (unformat (i, "hdr-len %d", &hdr_len))
8809         ;
8810       else if (unformat (i, "add"))
8811         is_add = 1;
8812       else if (unformat (i, "del"))
8813         is_add = 0;
8814       else
8815         {
8816           clib_warning ("parse error '%U'", format_unformat_error, i);
8817           return -99;
8818         }
8819     }
8820
8821   if (MPLS_LABEL_INVALID == local_label)
8822     {
8823       errmsg ("missing label\n");
8824       return -99;
8825     }
8826
8827   /* Construct the API message */
8828   M (BIER_TABLE_ADD_DEL, mp);
8829
8830   mp->bt_is_add = is_add;
8831   mp->bt_label = ntohl (local_label);
8832   mp->bt_tbl_id.bt_set = set;
8833   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8834   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8835
8836   /* send it... */
8837   S (mp);
8838
8839   /* Wait for a reply... */
8840   W (ret);
8841
8842   return (ret);
8843 }
8844
8845 static int
8846 api_bier_route_add_del (vat_main_t * vam)
8847 {
8848   unformat_input_t *i = vam->input;
8849   vl_api_bier_route_add_del_t *mp;
8850   u8 is_add = 1;
8851   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8852   ip4_address_t v4_next_hop_address;
8853   ip6_address_t v6_next_hop_address;
8854   u8 next_hop_set = 0;
8855   u8 next_hop_proto_is_ip4 = 1;
8856   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8857   int ret;
8858
8859   /* Parse args required to build the message */
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8863         {
8864           next_hop_proto_is_ip4 = 1;
8865           next_hop_set = 1;
8866         }
8867       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8868         {
8869           next_hop_proto_is_ip4 = 0;
8870           next_hop_set = 1;
8871         }
8872       if (unformat (i, "sub-domain %d", &sub_domain))
8873         ;
8874       else if (unformat (i, "set %d", &set))
8875         ;
8876       else if (unformat (i, "hdr-len %d", &hdr_len))
8877         ;
8878       else if (unformat (i, "bp %d", &bp))
8879         ;
8880       else if (unformat (i, "add"))
8881         is_add = 1;
8882       else if (unformat (i, "del"))
8883         is_add = 0;
8884       else if (unformat (i, "out-label %d", &next_hop_out_label))
8885         ;
8886       else
8887         {
8888           clib_warning ("parse error '%U'", format_unformat_error, i);
8889           return -99;
8890         }
8891     }
8892
8893   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8894     {
8895       errmsg ("next hop / label set\n");
8896       return -99;
8897     }
8898   if (0 == bp)
8899     {
8900       errmsg ("bit=position not set\n");
8901       return -99;
8902     }
8903
8904   /* Construct the API message */
8905   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8906
8907   mp->br_is_add = is_add;
8908   mp->br_tbl_id.bt_set = set;
8909   mp->br_tbl_id.bt_sub_domain = sub_domain;
8910   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8911   mp->br_bp = ntohs (bp);
8912   mp->br_n_paths = 1;
8913   mp->br_paths[0].n_labels = 1;
8914   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8915   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8916
8917   if (next_hop_proto_is_ip4)
8918     {
8919       clib_memcpy (mp->br_paths[0].next_hop,
8920                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8921     }
8922   else
8923     {
8924       clib_memcpy (mp->br_paths[0].next_hop,
8925                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8926     }
8927
8928   /* send it... */
8929   S (mp);
8930
8931   /* Wait for a reply... */
8932   W (ret);
8933
8934   return (ret);
8935 }
8936
8937 static int
8938 api_proxy_arp_add_del (vat_main_t * vam)
8939 {
8940   unformat_input_t *i = vam->input;
8941   vl_api_proxy_arp_add_del_t *mp;
8942   u32 vrf_id = 0;
8943   u8 is_add = 1;
8944   ip4_address_t lo, hi;
8945   u8 range_set = 0;
8946   int ret;
8947
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "vrf %d", &vrf_id))
8951         ;
8952       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8953                          unformat_ip4_address, &hi))
8954         range_set = 1;
8955       else if (unformat (i, "del"))
8956         is_add = 0;
8957       else
8958         {
8959           clib_warning ("parse error '%U'", format_unformat_error, i);
8960           return -99;
8961         }
8962     }
8963
8964   if (range_set == 0)
8965     {
8966       errmsg ("address range not set");
8967       return -99;
8968     }
8969
8970   M (PROXY_ARP_ADD_DEL, mp);
8971
8972   mp->vrf_id = ntohl (vrf_id);
8973   mp->is_add = is_add;
8974   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8975   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8976
8977   S (mp);
8978   W (ret);
8979   return ret;
8980 }
8981
8982 static int
8983 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8984 {
8985   unformat_input_t *i = vam->input;
8986   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8987   u32 sw_if_index;
8988   u8 enable = 1;
8989   u8 sw_if_index_set = 0;
8990   int ret;
8991
8992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8995         sw_if_index_set = 1;
8996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8997         sw_if_index_set = 1;
8998       else if (unformat (i, "enable"))
8999         enable = 1;
9000       else if (unformat (i, "disable"))
9001         enable = 0;
9002       else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (sw_if_index_set == 0)
9010     {
9011       errmsg ("missing interface name or sw_if_index");
9012       return -99;
9013     }
9014
9015   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9016
9017   mp->sw_if_index = ntohl (sw_if_index);
9018   mp->enable_disable = enable;
9019
9020   S (mp);
9021   W (ret);
9022   return ret;
9023 }
9024
9025 static int
9026 api_mpls_tunnel_add_del (vat_main_t * vam)
9027 {
9028   unformat_input_t *i = vam->input;
9029   vl_api_mpls_tunnel_add_del_t *mp;
9030
9031   u8 is_add = 1;
9032   u8 l2_only = 0;
9033   u32 sw_if_index = ~0;
9034   u32 next_hop_sw_if_index = ~0;
9035   u32 next_hop_proto_is_ip4 = 1;
9036
9037   u32 next_hop_table_id = 0;
9038   ip4_address_t v4_next_hop_address = {
9039     .as_u32 = 0,
9040   };
9041   ip6_address_t v6_next_hop_address = { {0} };
9042   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9043   int ret;
9044
9045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (i, "add"))
9048         is_add = 1;
9049       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9050         is_add = 0;
9051       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9052         ;
9053       else if (unformat (i, "via %U",
9054                          unformat_ip4_address, &v4_next_hop_address))
9055         {
9056           next_hop_proto_is_ip4 = 1;
9057         }
9058       else if (unformat (i, "via %U",
9059                          unformat_ip6_address, &v6_next_hop_address))
9060         {
9061           next_hop_proto_is_ip4 = 0;
9062         }
9063       else if (unformat (i, "l2-only"))
9064         l2_only = 1;
9065       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9066         ;
9067       else if (unformat (i, "out-label %d", &next_hop_out_label))
9068         vec_add1 (labels, ntohl (next_hop_out_label));
9069       else
9070         {
9071           clib_warning ("parse error '%U'", format_unformat_error, i);
9072           return -99;
9073         }
9074     }
9075
9076   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9077
9078   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9079   mp->mt_sw_if_index = ntohl (sw_if_index);
9080   mp->mt_is_add = is_add;
9081   mp->mt_l2_only = l2_only;
9082   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9083   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9084
9085   mp->mt_next_hop_n_out_labels = vec_len (labels);
9086
9087   if (0 != mp->mt_next_hop_n_out_labels)
9088     {
9089       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9090                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9091       vec_free (labels);
9092     }
9093
9094   if (next_hop_proto_is_ip4)
9095     {
9096       clib_memcpy (mp->mt_next_hop,
9097                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9098     }
9099   else
9100     {
9101       clib_memcpy (mp->mt_next_hop,
9102                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9103     }
9104
9105   S (mp);
9106   W (ret);
9107   return ret;
9108 }
9109
9110 static int
9111 api_sw_interface_set_unnumbered (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_sw_interface_set_unnumbered_t *mp;
9115   u32 sw_if_index;
9116   u32 unnum_sw_index = ~0;
9117   u8 is_add = 1;
9118   u8 sw_if_index_set = 0;
9119   int ret;
9120
9121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9122     {
9123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9124         sw_if_index_set = 1;
9125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9126         sw_if_index_set = 1;
9127       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9128         ;
9129       else if (unformat (i, "del"))
9130         is_add = 0;
9131       else
9132         {
9133           clib_warning ("parse error '%U'", format_unformat_error, i);
9134           return -99;
9135         }
9136     }
9137
9138   if (sw_if_index_set == 0)
9139     {
9140       errmsg ("missing interface name or sw_if_index");
9141       return -99;
9142     }
9143
9144   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9145
9146   mp->sw_if_index = ntohl (sw_if_index);
9147   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9148   mp->is_add = is_add;
9149
9150   S (mp);
9151   W (ret);
9152   return ret;
9153 }
9154
9155 static int
9156 api_ip_neighbor_add_del (vat_main_t * vam)
9157 {
9158   unformat_input_t *i = vam->input;
9159   vl_api_ip_neighbor_add_del_t *mp;
9160   u32 sw_if_index;
9161   u8 sw_if_index_set = 0;
9162   u8 is_add = 1;
9163   u8 is_static = 0;
9164   u8 is_no_fib_entry = 0;
9165   u8 mac_address[6];
9166   u8 mac_set = 0;
9167   u8 v4_address_set = 0;
9168   u8 v6_address_set = 0;
9169   ip4_address_t v4address;
9170   ip6_address_t v6address;
9171   int ret;
9172
9173   memset (mac_address, 0, sizeof (mac_address));
9174
9175   /* Parse args required to build the message */
9176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9177     {
9178       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9179         {
9180           mac_set = 1;
9181         }
9182       else if (unformat (i, "del"))
9183         is_add = 0;
9184       else
9185         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9186         sw_if_index_set = 1;
9187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9188         sw_if_index_set = 1;
9189       else if (unformat (i, "is_static"))
9190         is_static = 1;
9191       else if (unformat (i, "no-fib-entry"))
9192         is_no_fib_entry = 1;
9193       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9194         v4_address_set = 1;
9195       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9196         v6_address_set = 1;
9197       else
9198         {
9199           clib_warning ("parse error '%U'", format_unformat_error, i);
9200           return -99;
9201         }
9202     }
9203
9204   if (sw_if_index_set == 0)
9205     {
9206       errmsg ("missing interface name or sw_if_index");
9207       return -99;
9208     }
9209   if (v4_address_set && v6_address_set)
9210     {
9211       errmsg ("both v4 and v6 addresses set");
9212       return -99;
9213     }
9214   if (!v4_address_set && !v6_address_set)
9215     {
9216       errmsg ("no address set");
9217       return -99;
9218     }
9219
9220   /* Construct the API message */
9221   M (IP_NEIGHBOR_ADD_DEL, mp);
9222
9223   mp->sw_if_index = ntohl (sw_if_index);
9224   mp->is_add = is_add;
9225   mp->is_static = is_static;
9226   mp->is_no_adj_fib = is_no_fib_entry;
9227   if (mac_set)
9228     clib_memcpy (mp->mac_address, mac_address, 6);
9229   if (v6_address_set)
9230     {
9231       mp->is_ipv6 = 1;
9232       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9233     }
9234   else
9235     {
9236       /* mp->is_ipv6 = 0; via memset in M macro above */
9237       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9238     }
9239
9240   /* send it... */
9241   S (mp);
9242
9243   /* Wait for a reply, return good/bad news  */
9244   W (ret);
9245   return ret;
9246 }
9247
9248 static int
9249 api_create_vlan_subif (vat_main_t * vam)
9250 {
9251   unformat_input_t *i = vam->input;
9252   vl_api_create_vlan_subif_t *mp;
9253   u32 sw_if_index;
9254   u8 sw_if_index_set = 0;
9255   u32 vlan_id;
9256   u8 vlan_id_set = 0;
9257   int ret;
9258
9259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9260     {
9261       if (unformat (i, "sw_if_index %d", &sw_if_index))
9262         sw_if_index_set = 1;
9263       else
9264         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9265         sw_if_index_set = 1;
9266       else if (unformat (i, "vlan %d", &vlan_id))
9267         vlan_id_set = 1;
9268       else
9269         {
9270           clib_warning ("parse error '%U'", format_unformat_error, i);
9271           return -99;
9272         }
9273     }
9274
9275   if (sw_if_index_set == 0)
9276     {
9277       errmsg ("missing interface name or sw_if_index");
9278       return -99;
9279     }
9280
9281   if (vlan_id_set == 0)
9282     {
9283       errmsg ("missing vlan_id");
9284       return -99;
9285     }
9286   M (CREATE_VLAN_SUBIF, mp);
9287
9288   mp->sw_if_index = ntohl (sw_if_index);
9289   mp->vlan_id = ntohl (vlan_id);
9290
9291   S (mp);
9292   W (ret);
9293   return ret;
9294 }
9295
9296 #define foreach_create_subif_bit                \
9297 _(no_tags)                                      \
9298 _(one_tag)                                      \
9299 _(two_tags)                                     \
9300 _(dot1ad)                                       \
9301 _(exact_match)                                  \
9302 _(default_sub)                                  \
9303 _(outer_vlan_id_any)                            \
9304 _(inner_vlan_id_any)
9305
9306 static int
9307 api_create_subif (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_create_subif_t *mp;
9311   u32 sw_if_index;
9312   u8 sw_if_index_set = 0;
9313   u32 sub_id;
9314   u8 sub_id_set = 0;
9315   u32 no_tags = 0;
9316   u32 one_tag = 0;
9317   u32 two_tags = 0;
9318   u32 dot1ad = 0;
9319   u32 exact_match = 0;
9320   u32 default_sub = 0;
9321   u32 outer_vlan_id_any = 0;
9322   u32 inner_vlan_id_any = 0;
9323   u32 tmp;
9324   u16 outer_vlan_id = 0;
9325   u16 inner_vlan_id = 0;
9326   int ret;
9327
9328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9329     {
9330       if (unformat (i, "sw_if_index %d", &sw_if_index))
9331         sw_if_index_set = 1;
9332       else
9333         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9334         sw_if_index_set = 1;
9335       else if (unformat (i, "sub_id %d", &sub_id))
9336         sub_id_set = 1;
9337       else if (unformat (i, "outer_vlan_id %d", &tmp))
9338         outer_vlan_id = tmp;
9339       else if (unformat (i, "inner_vlan_id %d", &tmp))
9340         inner_vlan_id = tmp;
9341
9342 #define _(a) else if (unformat (i, #a)) a = 1 ;
9343       foreach_create_subif_bit
9344 #undef _
9345         else
9346         {
9347           clib_warning ("parse error '%U'", format_unformat_error, i);
9348           return -99;
9349         }
9350     }
9351
9352   if (sw_if_index_set == 0)
9353     {
9354       errmsg ("missing interface name or sw_if_index");
9355       return -99;
9356     }
9357
9358   if (sub_id_set == 0)
9359     {
9360       errmsg ("missing sub_id");
9361       return -99;
9362     }
9363   M (CREATE_SUBIF, mp);
9364
9365   mp->sw_if_index = ntohl (sw_if_index);
9366   mp->sub_id = ntohl (sub_id);
9367
9368 #define _(a) mp->a = a;
9369   foreach_create_subif_bit;
9370 #undef _
9371
9372   mp->outer_vlan_id = ntohs (outer_vlan_id);
9373   mp->inner_vlan_id = ntohs (inner_vlan_id);
9374
9375   S (mp);
9376   W (ret);
9377   return ret;
9378 }
9379
9380 static int
9381 api_oam_add_del (vat_main_t * vam)
9382 {
9383   unformat_input_t *i = vam->input;
9384   vl_api_oam_add_del_t *mp;
9385   u32 vrf_id = 0;
9386   u8 is_add = 1;
9387   ip4_address_t src, dst;
9388   u8 src_set = 0;
9389   u8 dst_set = 0;
9390   int ret;
9391
9392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (unformat (i, "vrf %d", &vrf_id))
9395         ;
9396       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9397         src_set = 1;
9398       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9399         dst_set = 1;
9400       else if (unformat (i, "del"))
9401         is_add = 0;
9402       else
9403         {
9404           clib_warning ("parse error '%U'", format_unformat_error, i);
9405           return -99;
9406         }
9407     }
9408
9409   if (src_set == 0)
9410     {
9411       errmsg ("missing src addr");
9412       return -99;
9413     }
9414
9415   if (dst_set == 0)
9416     {
9417       errmsg ("missing dst addr");
9418       return -99;
9419     }
9420
9421   M (OAM_ADD_DEL, mp);
9422
9423   mp->vrf_id = ntohl (vrf_id);
9424   mp->is_add = is_add;
9425   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9426   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9427
9428   S (mp);
9429   W (ret);
9430   return ret;
9431 }
9432
9433 static int
9434 api_reset_fib (vat_main_t * vam)
9435 {
9436   unformat_input_t *i = vam->input;
9437   vl_api_reset_fib_t *mp;
9438   u32 vrf_id = 0;
9439   u8 is_ipv6 = 0;
9440   u8 vrf_id_set = 0;
9441
9442   int ret;
9443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9444     {
9445       if (unformat (i, "vrf %d", &vrf_id))
9446         vrf_id_set = 1;
9447       else if (unformat (i, "ipv6"))
9448         is_ipv6 = 1;
9449       else
9450         {
9451           clib_warning ("parse error '%U'", format_unformat_error, i);
9452           return -99;
9453         }
9454     }
9455
9456   if (vrf_id_set == 0)
9457     {
9458       errmsg ("missing vrf id");
9459       return -99;
9460     }
9461
9462   M (RESET_FIB, mp);
9463
9464   mp->vrf_id = ntohl (vrf_id);
9465   mp->is_ipv6 = is_ipv6;
9466
9467   S (mp);
9468   W (ret);
9469   return ret;
9470 }
9471
9472 static int
9473 api_dhcp_proxy_config (vat_main_t * vam)
9474 {
9475   unformat_input_t *i = vam->input;
9476   vl_api_dhcp_proxy_config_t *mp;
9477   u32 rx_vrf_id = 0;
9478   u32 server_vrf_id = 0;
9479   u8 is_add = 1;
9480   u8 v4_address_set = 0;
9481   u8 v6_address_set = 0;
9482   ip4_address_t v4address;
9483   ip6_address_t v6address;
9484   u8 v4_src_address_set = 0;
9485   u8 v6_src_address_set = 0;
9486   ip4_address_t v4srcaddress;
9487   ip6_address_t v6srcaddress;
9488   int ret;
9489
9490   /* Parse args required to build the message */
9491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (i, "del"))
9494         is_add = 0;
9495       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9496         ;
9497       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9498         ;
9499       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9500         v4_address_set = 1;
9501       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9502         v6_address_set = 1;
9503       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9504         v4_src_address_set = 1;
9505       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9506         v6_src_address_set = 1;
9507       else
9508         break;
9509     }
9510
9511   if (v4_address_set && v6_address_set)
9512     {
9513       errmsg ("both v4 and v6 server addresses set");
9514       return -99;
9515     }
9516   if (!v4_address_set && !v6_address_set)
9517     {
9518       errmsg ("no server addresses set");
9519       return -99;
9520     }
9521
9522   if (v4_src_address_set && v6_src_address_set)
9523     {
9524       errmsg ("both v4 and v6  src addresses set");
9525       return -99;
9526     }
9527   if (!v4_src_address_set && !v6_src_address_set)
9528     {
9529       errmsg ("no src addresses set");
9530       return -99;
9531     }
9532
9533   if (!(v4_src_address_set && v4_address_set) &&
9534       !(v6_src_address_set && v6_address_set))
9535     {
9536       errmsg ("no matching server and src addresses set");
9537       return -99;
9538     }
9539
9540   /* Construct the API message */
9541   M (DHCP_PROXY_CONFIG, mp);
9542
9543   mp->is_add = is_add;
9544   mp->rx_vrf_id = ntohl (rx_vrf_id);
9545   mp->server_vrf_id = ntohl (server_vrf_id);
9546   if (v6_address_set)
9547     {
9548       mp->is_ipv6 = 1;
9549       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9550       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9551     }
9552   else
9553     {
9554       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9555       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9556     }
9557
9558   /* send it... */
9559   S (mp);
9560
9561   /* Wait for a reply, return good/bad news  */
9562   W (ret);
9563   return ret;
9564 }
9565
9566 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9567 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9568
9569 static void
9570 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9571 {
9572   vat_main_t *vam = &vat_main;
9573   u32 i, count = mp->count;
9574   vl_api_dhcp_server_t *s;
9575
9576   if (mp->is_ipv6)
9577     print (vam->ofp,
9578            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9579            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9580            ntohl (mp->rx_vrf_id),
9581            format_ip6_address, mp->dhcp_src_address,
9582            mp->vss_type, mp->vss_vpn_ascii_id,
9583            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9584   else
9585     print (vam->ofp,
9586            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9587            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9588            ntohl (mp->rx_vrf_id),
9589            format_ip4_address, mp->dhcp_src_address,
9590            mp->vss_type, mp->vss_vpn_ascii_id,
9591            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9592
9593   for (i = 0; i < count; i++)
9594     {
9595       s = &mp->servers[i];
9596
9597       if (mp->is_ipv6)
9598         print (vam->ofp,
9599                " Server Table-ID %d, Server Address %U",
9600                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9601       else
9602         print (vam->ofp,
9603                " Server Table-ID %d, Server Address %U",
9604                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9605     }
9606 }
9607
9608 static void vl_api_dhcp_proxy_details_t_handler_json
9609   (vl_api_dhcp_proxy_details_t * mp)
9610 {
9611   vat_main_t *vam = &vat_main;
9612   vat_json_node_t *node = NULL;
9613   u32 i, count = mp->count;
9614   struct in_addr ip4;
9615   struct in6_addr ip6;
9616   vl_api_dhcp_server_t *s;
9617
9618   if (VAT_JSON_ARRAY != vam->json_tree.type)
9619     {
9620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9621       vat_json_init_array (&vam->json_tree);
9622     }
9623   node = vat_json_array_add (&vam->json_tree);
9624
9625   vat_json_init_object (node);
9626   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9627   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9628                              sizeof (mp->vss_type));
9629   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9630                                    mp->vss_vpn_ascii_id);
9631   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9632   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9633
9634   if (mp->is_ipv6)
9635     {
9636       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9637       vat_json_object_add_ip6 (node, "src_address", ip6);
9638     }
9639   else
9640     {
9641       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9642       vat_json_object_add_ip4 (node, "src_address", ip4);
9643     }
9644
9645   for (i = 0; i < count; i++)
9646     {
9647       s = &mp->servers[i];
9648
9649       vat_json_object_add_uint (node, "server-table-id",
9650                                 ntohl (s->server_vrf_id));
9651
9652       if (mp->is_ipv6)
9653         {
9654           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9655           vat_json_object_add_ip4 (node, "src_address", ip4);
9656         }
9657       else
9658         {
9659           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9660           vat_json_object_add_ip6 (node, "server_address", ip6);
9661         }
9662     }
9663 }
9664
9665 static int
9666 api_dhcp_proxy_dump (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_control_ping_t *mp_ping;
9670   vl_api_dhcp_proxy_dump_t *mp;
9671   u8 is_ipv6 = 0;
9672   int ret;
9673
9674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9675     {
9676       if (unformat (i, "ipv6"))
9677         is_ipv6 = 1;
9678       else
9679         {
9680           clib_warning ("parse error '%U'", format_unformat_error, i);
9681           return -99;
9682         }
9683     }
9684
9685   M (DHCP_PROXY_DUMP, mp);
9686
9687   mp->is_ip6 = is_ipv6;
9688   S (mp);
9689
9690   /* Use a control ping for synchronization */
9691   MPING (CONTROL_PING, mp_ping);
9692   S (mp_ping);
9693
9694   W (ret);
9695   return ret;
9696 }
9697
9698 static int
9699 api_dhcp_proxy_set_vss (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_dhcp_proxy_set_vss_t *mp;
9703   u8 is_ipv6 = 0;
9704   u8 is_add = 1;
9705   u32 tbl_id = ~0;
9706   u8 vss_type = VSS_TYPE_DEFAULT;
9707   u8 *vpn_ascii_id = 0;
9708   u32 oui = 0;
9709   u32 fib_id = 0;
9710   int ret;
9711
9712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9713     {
9714       if (unformat (i, "tbl_id %d", &tbl_id))
9715         ;
9716       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9717         vss_type = VSS_TYPE_ASCII;
9718       else if (unformat (i, "fib_id %d", &fib_id))
9719         vss_type = VSS_TYPE_VPN_ID;
9720       else if (unformat (i, "oui %d", &oui))
9721         vss_type = VSS_TYPE_VPN_ID;
9722       else if (unformat (i, "ipv6"))
9723         is_ipv6 = 1;
9724       else if (unformat (i, "del"))
9725         is_add = 0;
9726       else
9727         break;
9728     }
9729
9730   if (tbl_id == ~0)
9731     {
9732       errmsg ("missing tbl_id ");
9733       vec_free (vpn_ascii_id);
9734       return -99;
9735     }
9736
9737   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9738     {
9739       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9740       vec_free (vpn_ascii_id);
9741       return -99;
9742     }
9743
9744   M (DHCP_PROXY_SET_VSS, mp);
9745   mp->tbl_id = ntohl (tbl_id);
9746   mp->vss_type = vss_type;
9747   if (vpn_ascii_id)
9748     {
9749       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9750       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9751     }
9752   mp->vpn_index = ntohl (fib_id);
9753   mp->oui = ntohl (oui);
9754   mp->is_ipv6 = is_ipv6;
9755   mp->is_add = is_add;
9756
9757   S (mp);
9758   W (ret);
9759
9760   vec_free (vpn_ascii_id);
9761   return ret;
9762 }
9763
9764 static int
9765 api_dhcp_client_config (vat_main_t * vam)
9766 {
9767   unformat_input_t *i = vam->input;
9768   vl_api_dhcp_client_config_t *mp;
9769   u32 sw_if_index;
9770   u8 sw_if_index_set = 0;
9771   u8 is_add = 1;
9772   u8 *hostname = 0;
9773   u8 disable_event = 0;
9774   int ret;
9775
9776   /* Parse args required to build the message */
9777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (i, "del"))
9780         is_add = 0;
9781       else
9782         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9783         sw_if_index_set = 1;
9784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9785         sw_if_index_set = 1;
9786       else if (unformat (i, "hostname %s", &hostname))
9787         ;
9788       else if (unformat (i, "disable_event"))
9789         disable_event = 1;
9790       else
9791         break;
9792     }
9793
9794   if (sw_if_index_set == 0)
9795     {
9796       errmsg ("missing interface name or sw_if_index");
9797       return -99;
9798     }
9799
9800   if (vec_len (hostname) > 63)
9801     {
9802       errmsg ("hostname too long");
9803     }
9804   vec_add1 (hostname, 0);
9805
9806   /* Construct the API message */
9807   M (DHCP_CLIENT_CONFIG, mp);
9808
9809   mp->sw_if_index = htonl (sw_if_index);
9810   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9811   vec_free (hostname);
9812   mp->is_add = is_add;
9813   mp->want_dhcp_event = disable_event ? 0 : 1;
9814   mp->pid = htonl (getpid ());
9815
9816   /* send it... */
9817   S (mp);
9818
9819   /* Wait for a reply, return good/bad news  */
9820   W (ret);
9821   return ret;
9822 }
9823
9824 static int
9825 api_set_ip_flow_hash (vat_main_t * vam)
9826 {
9827   unformat_input_t *i = vam->input;
9828   vl_api_set_ip_flow_hash_t *mp;
9829   u32 vrf_id = 0;
9830   u8 is_ipv6 = 0;
9831   u8 vrf_id_set = 0;
9832   u8 src = 0;
9833   u8 dst = 0;
9834   u8 sport = 0;
9835   u8 dport = 0;
9836   u8 proto = 0;
9837   u8 reverse = 0;
9838   int ret;
9839
9840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9841     {
9842       if (unformat (i, "vrf %d", &vrf_id))
9843         vrf_id_set = 1;
9844       else if (unformat (i, "ipv6"))
9845         is_ipv6 = 1;
9846       else if (unformat (i, "src"))
9847         src = 1;
9848       else if (unformat (i, "dst"))
9849         dst = 1;
9850       else if (unformat (i, "sport"))
9851         sport = 1;
9852       else if (unformat (i, "dport"))
9853         dport = 1;
9854       else if (unformat (i, "proto"))
9855         proto = 1;
9856       else if (unformat (i, "reverse"))
9857         reverse = 1;
9858
9859       else
9860         {
9861           clib_warning ("parse error '%U'", format_unformat_error, i);
9862           return -99;
9863         }
9864     }
9865
9866   if (vrf_id_set == 0)
9867     {
9868       errmsg ("missing vrf id");
9869       return -99;
9870     }
9871
9872   M (SET_IP_FLOW_HASH, mp);
9873   mp->src = src;
9874   mp->dst = dst;
9875   mp->sport = sport;
9876   mp->dport = dport;
9877   mp->proto = proto;
9878   mp->reverse = reverse;
9879   mp->vrf_id = ntohl (vrf_id);
9880   mp->is_ipv6 = is_ipv6;
9881
9882   S (mp);
9883   W (ret);
9884   return ret;
9885 }
9886
9887 static int
9888 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9889 {
9890   unformat_input_t *i = vam->input;
9891   vl_api_sw_interface_ip6_enable_disable_t *mp;
9892   u32 sw_if_index;
9893   u8 sw_if_index_set = 0;
9894   u8 enable = 0;
9895   int ret;
9896
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "enable"))
9904         enable = 1;
9905       else if (unformat (i, "disable"))
9906         enable = 0;
9907       else
9908         {
9909           clib_warning ("parse error '%U'", format_unformat_error, i);
9910           return -99;
9911         }
9912     }
9913
9914   if (sw_if_index_set == 0)
9915     {
9916       errmsg ("missing interface name or sw_if_index");
9917       return -99;
9918     }
9919
9920   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9921
9922   mp->sw_if_index = ntohl (sw_if_index);
9923   mp->enable = enable;
9924
9925   S (mp);
9926   W (ret);
9927   return ret;
9928 }
9929
9930 static int
9931 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9935   u32 sw_if_index;
9936   u8 sw_if_index_set = 0;
9937   u8 v6_address_set = 0;
9938   ip6_address_t v6address;
9939   int ret;
9940
9941   /* Parse args required to build the message */
9942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9945         sw_if_index_set = 1;
9946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9947         sw_if_index_set = 1;
9948       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9949         v6_address_set = 1;
9950       else
9951         break;
9952     }
9953
9954   if (sw_if_index_set == 0)
9955     {
9956       errmsg ("missing interface name or sw_if_index");
9957       return -99;
9958     }
9959   if (!v6_address_set)
9960     {
9961       errmsg ("no address set");
9962       return -99;
9963     }
9964
9965   /* Construct the API message */
9966   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9967
9968   mp->sw_if_index = ntohl (sw_if_index);
9969   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9970
9971   /* send it... */
9972   S (mp);
9973
9974   /* Wait for a reply, return good/bad news  */
9975   W (ret);
9976   return ret;
9977 }
9978
9979 static int
9980 api_ip6nd_proxy_add_del (vat_main_t * vam)
9981 {
9982   unformat_input_t *i = vam->input;
9983   vl_api_ip6nd_proxy_add_del_t *mp;
9984   u32 sw_if_index = ~0;
9985   u8 v6_address_set = 0;
9986   ip6_address_t v6address;
9987   u8 is_del = 0;
9988   int ret;
9989
9990   /* Parse args required to build the message */
9991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9992     {
9993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9994         ;
9995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9996         ;
9997       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9998         v6_address_set = 1;
9999       if (unformat (i, "del"))
10000         is_del = 1;
10001       else
10002         {
10003           clib_warning ("parse error '%U'", format_unformat_error, i);
10004           return -99;
10005         }
10006     }
10007
10008   if (sw_if_index == ~0)
10009     {
10010       errmsg ("missing interface name or sw_if_index");
10011       return -99;
10012     }
10013   if (!v6_address_set)
10014     {
10015       errmsg ("no address set");
10016       return -99;
10017     }
10018
10019   /* Construct the API message */
10020   M (IP6ND_PROXY_ADD_DEL, mp);
10021
10022   mp->is_del = is_del;
10023   mp->sw_if_index = ntohl (sw_if_index);
10024   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10025
10026   /* send it... */
10027   S (mp);
10028
10029   /* Wait for a reply, return good/bad news  */
10030   W (ret);
10031   return ret;
10032 }
10033
10034 static int
10035 api_ip6nd_proxy_dump (vat_main_t * vam)
10036 {
10037   vl_api_ip6nd_proxy_dump_t *mp;
10038   vl_api_control_ping_t *mp_ping;
10039   int ret;
10040
10041   M (IP6ND_PROXY_DUMP, mp);
10042
10043   S (mp);
10044
10045   /* Use a control ping for synchronization */
10046   MPING (CONTROL_PING, mp_ping);
10047   S (mp_ping);
10048
10049   W (ret);
10050   return ret;
10051 }
10052
10053 static void vl_api_ip6nd_proxy_details_t_handler
10054   (vl_api_ip6nd_proxy_details_t * mp)
10055 {
10056   vat_main_t *vam = &vat_main;
10057
10058   print (vam->ofp, "host %U sw_if_index %d",
10059          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10060 }
10061
10062 static void vl_api_ip6nd_proxy_details_t_handler_json
10063   (vl_api_ip6nd_proxy_details_t * mp)
10064 {
10065   vat_main_t *vam = &vat_main;
10066   struct in6_addr ip6;
10067   vat_json_node_t *node = NULL;
10068
10069   if (VAT_JSON_ARRAY != vam->json_tree.type)
10070     {
10071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10072       vat_json_init_array (&vam->json_tree);
10073     }
10074   node = vat_json_array_add (&vam->json_tree);
10075
10076   vat_json_init_object (node);
10077   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10078
10079   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10080   vat_json_object_add_ip6 (node, "host", ip6);
10081 }
10082
10083 static int
10084 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10085 {
10086   unformat_input_t *i = vam->input;
10087   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10088   u32 sw_if_index;
10089   u8 sw_if_index_set = 0;
10090   u32 address_length = 0;
10091   u8 v6_address_set = 0;
10092   ip6_address_t v6address;
10093   u8 use_default = 0;
10094   u8 no_advertise = 0;
10095   u8 off_link = 0;
10096   u8 no_autoconfig = 0;
10097   u8 no_onlink = 0;
10098   u8 is_no = 0;
10099   u32 val_lifetime = 0;
10100   u32 pref_lifetime = 0;
10101   int ret;
10102
10103   /* Parse args required to build the message */
10104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10105     {
10106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10107         sw_if_index_set = 1;
10108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10109         sw_if_index_set = 1;
10110       else if (unformat (i, "%U/%d",
10111                          unformat_ip6_address, &v6address, &address_length))
10112         v6_address_set = 1;
10113       else if (unformat (i, "val_life %d", &val_lifetime))
10114         ;
10115       else if (unformat (i, "pref_life %d", &pref_lifetime))
10116         ;
10117       else if (unformat (i, "def"))
10118         use_default = 1;
10119       else if (unformat (i, "noadv"))
10120         no_advertise = 1;
10121       else if (unformat (i, "offl"))
10122         off_link = 1;
10123       else if (unformat (i, "noauto"))
10124         no_autoconfig = 1;
10125       else if (unformat (i, "nolink"))
10126         no_onlink = 1;
10127       else if (unformat (i, "isno"))
10128         is_no = 1;
10129       else
10130         {
10131           clib_warning ("parse error '%U'", format_unformat_error, i);
10132           return -99;
10133         }
10134     }
10135
10136   if (sw_if_index_set == 0)
10137     {
10138       errmsg ("missing interface name or sw_if_index");
10139       return -99;
10140     }
10141   if (!v6_address_set)
10142     {
10143       errmsg ("no address set");
10144       return -99;
10145     }
10146
10147   /* Construct the API message */
10148   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10149
10150   mp->sw_if_index = ntohl (sw_if_index);
10151   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10152   mp->address_length = address_length;
10153   mp->use_default = use_default;
10154   mp->no_advertise = no_advertise;
10155   mp->off_link = off_link;
10156   mp->no_autoconfig = no_autoconfig;
10157   mp->no_onlink = no_onlink;
10158   mp->is_no = is_no;
10159   mp->val_lifetime = ntohl (val_lifetime);
10160   mp->pref_lifetime = ntohl (pref_lifetime);
10161
10162   /* send it... */
10163   S (mp);
10164
10165   /* Wait for a reply, return good/bad news  */
10166   W (ret);
10167   return ret;
10168 }
10169
10170 static int
10171 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10172 {
10173   unformat_input_t *i = vam->input;
10174   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10175   u32 sw_if_index;
10176   u8 sw_if_index_set = 0;
10177   u8 suppress = 0;
10178   u8 managed = 0;
10179   u8 other = 0;
10180   u8 ll_option = 0;
10181   u8 send_unicast = 0;
10182   u8 cease = 0;
10183   u8 is_no = 0;
10184   u8 default_router = 0;
10185   u32 max_interval = 0;
10186   u32 min_interval = 0;
10187   u32 lifetime = 0;
10188   u32 initial_count = 0;
10189   u32 initial_interval = 0;
10190   int ret;
10191
10192
10193   /* Parse args required to build the message */
10194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10197         sw_if_index_set = 1;
10198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10199         sw_if_index_set = 1;
10200       else if (unformat (i, "maxint %d", &max_interval))
10201         ;
10202       else if (unformat (i, "minint %d", &min_interval))
10203         ;
10204       else if (unformat (i, "life %d", &lifetime))
10205         ;
10206       else if (unformat (i, "count %d", &initial_count))
10207         ;
10208       else if (unformat (i, "interval %d", &initial_interval))
10209         ;
10210       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10211         suppress = 1;
10212       else if (unformat (i, "managed"))
10213         managed = 1;
10214       else if (unformat (i, "other"))
10215         other = 1;
10216       else if (unformat (i, "ll"))
10217         ll_option = 1;
10218       else if (unformat (i, "send"))
10219         send_unicast = 1;
10220       else if (unformat (i, "cease"))
10221         cease = 1;
10222       else if (unformat (i, "isno"))
10223         is_no = 1;
10224       else if (unformat (i, "def"))
10225         default_router = 1;
10226       else
10227         {
10228           clib_warning ("parse error '%U'", format_unformat_error, i);
10229           return -99;
10230         }
10231     }
10232
10233   if (sw_if_index_set == 0)
10234     {
10235       errmsg ("missing interface name or sw_if_index");
10236       return -99;
10237     }
10238
10239   /* Construct the API message */
10240   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10241
10242   mp->sw_if_index = ntohl (sw_if_index);
10243   mp->max_interval = ntohl (max_interval);
10244   mp->min_interval = ntohl (min_interval);
10245   mp->lifetime = ntohl (lifetime);
10246   mp->initial_count = ntohl (initial_count);
10247   mp->initial_interval = ntohl (initial_interval);
10248   mp->suppress = suppress;
10249   mp->managed = managed;
10250   mp->other = other;
10251   mp->ll_option = ll_option;
10252   mp->send_unicast = send_unicast;
10253   mp->cease = cease;
10254   mp->is_no = is_no;
10255   mp->default_router = default_router;
10256
10257   /* send it... */
10258   S (mp);
10259
10260   /* Wait for a reply, return good/bad news  */
10261   W (ret);
10262   return ret;
10263 }
10264
10265 static int
10266 api_set_arp_neighbor_limit (vat_main_t * vam)
10267 {
10268   unformat_input_t *i = vam->input;
10269   vl_api_set_arp_neighbor_limit_t *mp;
10270   u32 arp_nbr_limit;
10271   u8 limit_set = 0;
10272   u8 is_ipv6 = 0;
10273   int ret;
10274
10275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10276     {
10277       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10278         limit_set = 1;
10279       else if (unformat (i, "ipv6"))
10280         is_ipv6 = 1;
10281       else
10282         {
10283           clib_warning ("parse error '%U'", format_unformat_error, i);
10284           return -99;
10285         }
10286     }
10287
10288   if (limit_set == 0)
10289     {
10290       errmsg ("missing limit value");
10291       return -99;
10292     }
10293
10294   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10295
10296   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10297   mp->is_ipv6 = is_ipv6;
10298
10299   S (mp);
10300   W (ret);
10301   return ret;
10302 }
10303
10304 static int
10305 api_l2_patch_add_del (vat_main_t * vam)
10306 {
10307   unformat_input_t *i = vam->input;
10308   vl_api_l2_patch_add_del_t *mp;
10309   u32 rx_sw_if_index;
10310   u8 rx_sw_if_index_set = 0;
10311   u32 tx_sw_if_index;
10312   u8 tx_sw_if_index_set = 0;
10313   u8 is_add = 1;
10314   int ret;
10315
10316   /* Parse args required to build the message */
10317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10318     {
10319       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10320         rx_sw_if_index_set = 1;
10321       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10322         tx_sw_if_index_set = 1;
10323       else if (unformat (i, "rx"))
10324         {
10325           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10326             {
10327               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10328                             &rx_sw_if_index))
10329                 rx_sw_if_index_set = 1;
10330             }
10331           else
10332             break;
10333         }
10334       else if (unformat (i, "tx"))
10335         {
10336           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10337             {
10338               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10339                             &tx_sw_if_index))
10340                 tx_sw_if_index_set = 1;
10341             }
10342           else
10343             break;
10344         }
10345       else if (unformat (i, "del"))
10346         is_add = 0;
10347       else
10348         break;
10349     }
10350
10351   if (rx_sw_if_index_set == 0)
10352     {
10353       errmsg ("missing rx interface name or rx_sw_if_index");
10354       return -99;
10355     }
10356
10357   if (tx_sw_if_index_set == 0)
10358     {
10359       errmsg ("missing tx interface name or tx_sw_if_index");
10360       return -99;
10361     }
10362
10363   M (L2_PATCH_ADD_DEL, mp);
10364
10365   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10366   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10367   mp->is_add = is_add;
10368
10369   S (mp);
10370   W (ret);
10371   return ret;
10372 }
10373
10374 u8 is_del;
10375 u8 localsid_addr[16];
10376 u8 end_psp;
10377 u8 behavior;
10378 u32 sw_if_index;
10379 u32 vlan_index;
10380 u32 fib_table;
10381 u8 nh_addr[16];
10382
10383 static int
10384 api_sr_localsid_add_del (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_sr_localsid_add_del_t *mp;
10388
10389   u8 is_del;
10390   ip6_address_t localsid;
10391   u8 end_psp = 0;
10392   u8 behavior = ~0;
10393   u32 sw_if_index;
10394   u32 fib_table = ~(u32) 0;
10395   ip6_address_t next_hop;
10396
10397   bool nexthop_set = 0;
10398
10399   int ret;
10400
10401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10402     {
10403       if (unformat (i, "del"))
10404         is_del = 1;
10405       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10406       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10407         nexthop_set = 1;
10408       else if (unformat (i, "behavior %u", &behavior));
10409       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10410       else if (unformat (i, "fib-table %u", &fib_table));
10411       else if (unformat (i, "end.psp %u", &behavior));
10412       else
10413         break;
10414     }
10415
10416   M (SR_LOCALSID_ADD_DEL, mp);
10417
10418   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10419   if (nexthop_set)
10420     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10421   mp->behavior = behavior;
10422   mp->sw_if_index = ntohl (sw_if_index);
10423   mp->fib_table = ntohl (fib_table);
10424   mp->end_psp = end_psp;
10425   mp->is_del = is_del;
10426
10427   S (mp);
10428   W (ret);
10429   return ret;
10430 }
10431
10432 static int
10433 api_ioam_enable (vat_main_t * vam)
10434 {
10435   unformat_input_t *input = vam->input;
10436   vl_api_ioam_enable_t *mp;
10437   u32 id = 0;
10438   int has_trace_option = 0;
10439   int has_pot_option = 0;
10440   int has_seqno_option = 0;
10441   int has_analyse_option = 0;
10442   int ret;
10443
10444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (input, "trace"))
10447         has_trace_option = 1;
10448       else if (unformat (input, "pot"))
10449         has_pot_option = 1;
10450       else if (unformat (input, "seqno"))
10451         has_seqno_option = 1;
10452       else if (unformat (input, "analyse"))
10453         has_analyse_option = 1;
10454       else
10455         break;
10456     }
10457   M (IOAM_ENABLE, mp);
10458   mp->id = htons (id);
10459   mp->seqno = has_seqno_option;
10460   mp->analyse = has_analyse_option;
10461   mp->pot_enable = has_pot_option;
10462   mp->trace_enable = has_trace_option;
10463
10464   S (mp);
10465   W (ret);
10466   return ret;
10467 }
10468
10469
10470 static int
10471 api_ioam_disable (vat_main_t * vam)
10472 {
10473   vl_api_ioam_disable_t *mp;
10474   int ret;
10475
10476   M (IOAM_DISABLE, mp);
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482 #define foreach_tcp_proto_field                 \
10483 _(src_port)                                     \
10484 _(dst_port)
10485
10486 #define foreach_udp_proto_field                 \
10487 _(src_port)                                     \
10488 _(dst_port)
10489
10490 #define foreach_ip4_proto_field                 \
10491 _(src_address)                                  \
10492 _(dst_address)                                  \
10493 _(tos)                                          \
10494 _(length)                                       \
10495 _(fragment_id)                                  \
10496 _(ttl)                                          \
10497 _(protocol)                                     \
10498 _(checksum)
10499
10500 typedef struct
10501 {
10502   u16 src_port, dst_port;
10503 } tcpudp_header_t;
10504
10505 #if VPP_API_TEST_BUILTIN == 0
10506 uword
10507 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10508 {
10509   u8 **maskp = va_arg (*args, u8 **);
10510   u8 *mask = 0;
10511   u8 found_something = 0;
10512   tcp_header_t *tcp;
10513
10514 #define _(a) u8 a=0;
10515   foreach_tcp_proto_field;
10516 #undef _
10517
10518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10519     {
10520       if (0);
10521 #define _(a) else if (unformat (input, #a)) a=1;
10522       foreach_tcp_proto_field
10523 #undef _
10524         else
10525         break;
10526     }
10527
10528 #define _(a) found_something += a;
10529   foreach_tcp_proto_field;
10530 #undef _
10531
10532   if (found_something == 0)
10533     return 0;
10534
10535   vec_validate (mask, sizeof (*tcp) - 1);
10536
10537   tcp = (tcp_header_t *) mask;
10538
10539 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10540   foreach_tcp_proto_field;
10541 #undef _
10542
10543   *maskp = mask;
10544   return 1;
10545 }
10546
10547 uword
10548 unformat_udp_mask (unformat_input_t * input, va_list * args)
10549 {
10550   u8 **maskp = va_arg (*args, u8 **);
10551   u8 *mask = 0;
10552   u8 found_something = 0;
10553   udp_header_t *udp;
10554
10555 #define _(a) u8 a=0;
10556   foreach_udp_proto_field;
10557 #undef _
10558
10559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10560     {
10561       if (0);
10562 #define _(a) else if (unformat (input, #a)) a=1;
10563       foreach_udp_proto_field
10564 #undef _
10565         else
10566         break;
10567     }
10568
10569 #define _(a) found_something += a;
10570   foreach_udp_proto_field;
10571 #undef _
10572
10573   if (found_something == 0)
10574     return 0;
10575
10576   vec_validate (mask, sizeof (*udp) - 1);
10577
10578   udp = (udp_header_t *) mask;
10579
10580 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10581   foreach_udp_proto_field;
10582 #undef _
10583
10584   *maskp = mask;
10585   return 1;
10586 }
10587
10588 uword
10589 unformat_l4_mask (unformat_input_t * input, va_list * args)
10590 {
10591   u8 **maskp = va_arg (*args, u8 **);
10592   u16 src_port = 0, dst_port = 0;
10593   tcpudp_header_t *tcpudp;
10594
10595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10598         return 1;
10599       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10600         return 1;
10601       else if (unformat (input, "src_port"))
10602         src_port = 0xFFFF;
10603       else if (unformat (input, "dst_port"))
10604         dst_port = 0xFFFF;
10605       else
10606         return 0;
10607     }
10608
10609   if (!src_port && !dst_port)
10610     return 0;
10611
10612   u8 *mask = 0;
10613   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10614
10615   tcpudp = (tcpudp_header_t *) mask;
10616   tcpudp->src_port = src_port;
10617   tcpudp->dst_port = dst_port;
10618
10619   *maskp = mask;
10620
10621   return 1;
10622 }
10623
10624 uword
10625 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10626 {
10627   u8 **maskp = va_arg (*args, u8 **);
10628   u8 *mask = 0;
10629   u8 found_something = 0;
10630   ip4_header_t *ip;
10631
10632 #define _(a) u8 a=0;
10633   foreach_ip4_proto_field;
10634 #undef _
10635   u8 version = 0;
10636   u8 hdr_length = 0;
10637
10638
10639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10640     {
10641       if (unformat (input, "version"))
10642         version = 1;
10643       else if (unformat (input, "hdr_length"))
10644         hdr_length = 1;
10645       else if (unformat (input, "src"))
10646         src_address = 1;
10647       else if (unformat (input, "dst"))
10648         dst_address = 1;
10649       else if (unformat (input, "proto"))
10650         protocol = 1;
10651
10652 #define _(a) else if (unformat (input, #a)) a=1;
10653       foreach_ip4_proto_field
10654 #undef _
10655         else
10656         break;
10657     }
10658
10659 #define _(a) found_something += a;
10660   foreach_ip4_proto_field;
10661 #undef _
10662
10663   if (found_something == 0)
10664     return 0;
10665
10666   vec_validate (mask, sizeof (*ip) - 1);
10667
10668   ip = (ip4_header_t *) mask;
10669
10670 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10671   foreach_ip4_proto_field;
10672 #undef _
10673
10674   ip->ip_version_and_header_length = 0;
10675
10676   if (version)
10677     ip->ip_version_and_header_length |= 0xF0;
10678
10679   if (hdr_length)
10680     ip->ip_version_and_header_length |= 0x0F;
10681
10682   *maskp = mask;
10683   return 1;
10684 }
10685
10686 #define foreach_ip6_proto_field                 \
10687 _(src_address)                                  \
10688 _(dst_address)                                  \
10689 _(payload_length)                               \
10690 _(hop_limit)                                    \
10691 _(protocol)
10692
10693 uword
10694 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10695 {
10696   u8 **maskp = va_arg (*args, u8 **);
10697   u8 *mask = 0;
10698   u8 found_something = 0;
10699   ip6_header_t *ip;
10700   u32 ip_version_traffic_class_and_flow_label;
10701
10702 #define _(a) u8 a=0;
10703   foreach_ip6_proto_field;
10704 #undef _
10705   u8 version = 0;
10706   u8 traffic_class = 0;
10707   u8 flow_label = 0;
10708
10709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10710     {
10711       if (unformat (input, "version"))
10712         version = 1;
10713       else if (unformat (input, "traffic-class"))
10714         traffic_class = 1;
10715       else if (unformat (input, "flow-label"))
10716         flow_label = 1;
10717       else if (unformat (input, "src"))
10718         src_address = 1;
10719       else if (unformat (input, "dst"))
10720         dst_address = 1;
10721       else if (unformat (input, "proto"))
10722         protocol = 1;
10723
10724 #define _(a) else if (unformat (input, #a)) a=1;
10725       foreach_ip6_proto_field
10726 #undef _
10727         else
10728         break;
10729     }
10730
10731 #define _(a) found_something += a;
10732   foreach_ip6_proto_field;
10733 #undef _
10734
10735   if (found_something == 0)
10736     return 0;
10737
10738   vec_validate (mask, sizeof (*ip) - 1);
10739
10740   ip = (ip6_header_t *) mask;
10741
10742 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10743   foreach_ip6_proto_field;
10744 #undef _
10745
10746   ip_version_traffic_class_and_flow_label = 0;
10747
10748   if (version)
10749     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10750
10751   if (traffic_class)
10752     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10753
10754   if (flow_label)
10755     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10756
10757   ip->ip_version_traffic_class_and_flow_label =
10758     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10759
10760   *maskp = mask;
10761   return 1;
10762 }
10763
10764 uword
10765 unformat_l3_mask (unformat_input_t * input, va_list * args)
10766 {
10767   u8 **maskp = va_arg (*args, u8 **);
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10772         return 1;
10773       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10774         return 1;
10775       else
10776         break;
10777     }
10778   return 0;
10779 }
10780
10781 uword
10782 unformat_l2_mask (unformat_input_t * input, va_list * args)
10783 {
10784   u8 **maskp = va_arg (*args, u8 **);
10785   u8 *mask = 0;
10786   u8 src = 0;
10787   u8 dst = 0;
10788   u8 proto = 0;
10789   u8 tag1 = 0;
10790   u8 tag2 = 0;
10791   u8 ignore_tag1 = 0;
10792   u8 ignore_tag2 = 0;
10793   u8 cos1 = 0;
10794   u8 cos2 = 0;
10795   u8 dot1q = 0;
10796   u8 dot1ad = 0;
10797   int len = 14;
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "src"))
10802         src = 1;
10803       else if (unformat (input, "dst"))
10804         dst = 1;
10805       else if (unformat (input, "proto"))
10806         proto = 1;
10807       else if (unformat (input, "tag1"))
10808         tag1 = 1;
10809       else if (unformat (input, "tag2"))
10810         tag2 = 1;
10811       else if (unformat (input, "ignore-tag1"))
10812         ignore_tag1 = 1;
10813       else if (unformat (input, "ignore-tag2"))
10814         ignore_tag2 = 1;
10815       else if (unformat (input, "cos1"))
10816         cos1 = 1;
10817       else if (unformat (input, "cos2"))
10818         cos2 = 1;
10819       else if (unformat (input, "dot1q"))
10820         dot1q = 1;
10821       else if (unformat (input, "dot1ad"))
10822         dot1ad = 1;
10823       else
10824         break;
10825     }
10826   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10827        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10828     return 0;
10829
10830   if (tag1 || ignore_tag1 || cos1 || dot1q)
10831     len = 18;
10832   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10833     len = 22;
10834
10835   vec_validate (mask, len - 1);
10836
10837   if (dst)
10838     memset (mask, 0xff, 6);
10839
10840   if (src)
10841     memset (mask + 6, 0xff, 6);
10842
10843   if (tag2 || dot1ad)
10844     {
10845       /* inner vlan tag */
10846       if (tag2)
10847         {
10848           mask[19] = 0xff;
10849           mask[18] = 0x0f;
10850         }
10851       if (cos2)
10852         mask[18] |= 0xe0;
10853       if (proto)
10854         mask[21] = mask[20] = 0xff;
10855       if (tag1)
10856         {
10857           mask[15] = 0xff;
10858           mask[14] = 0x0f;
10859         }
10860       if (cos1)
10861         mask[14] |= 0xe0;
10862       *maskp = mask;
10863       return 1;
10864     }
10865   if (tag1 | dot1q)
10866     {
10867       if (tag1)
10868         {
10869           mask[15] = 0xff;
10870           mask[14] = 0x0f;
10871         }
10872       if (cos1)
10873         mask[14] |= 0xe0;
10874       if (proto)
10875         mask[16] = mask[17] = 0xff;
10876
10877       *maskp = mask;
10878       return 1;
10879     }
10880   if (cos2)
10881     mask[18] |= 0xe0;
10882   if (cos1)
10883     mask[14] |= 0xe0;
10884   if (proto)
10885     mask[12] = mask[13] = 0xff;
10886
10887   *maskp = mask;
10888   return 1;
10889 }
10890
10891 uword
10892 unformat_classify_mask (unformat_input_t * input, va_list * args)
10893 {
10894   u8 **maskp = va_arg (*args, u8 **);
10895   u32 *skipp = va_arg (*args, u32 *);
10896   u32 *matchp = va_arg (*args, u32 *);
10897   u32 match;
10898   u8 *mask = 0;
10899   u8 *l2 = 0;
10900   u8 *l3 = 0;
10901   u8 *l4 = 0;
10902   int i;
10903
10904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10907         ;
10908       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10909         ;
10910       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10911         ;
10912       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10913         ;
10914       else
10915         break;
10916     }
10917
10918   if (l4 && !l3)
10919     {
10920       vec_free (mask);
10921       vec_free (l2);
10922       vec_free (l4);
10923       return 0;
10924     }
10925
10926   if (mask || l2 || l3 || l4)
10927     {
10928       if (l2 || l3 || l4)
10929         {
10930           /* "With a free Ethernet header in every package" */
10931           if (l2 == 0)
10932             vec_validate (l2, 13);
10933           mask = l2;
10934           if (vec_len (l3))
10935             {
10936               vec_append (mask, l3);
10937               vec_free (l3);
10938             }
10939           if (vec_len (l4))
10940             {
10941               vec_append (mask, l4);
10942               vec_free (l4);
10943             }
10944         }
10945
10946       /* Scan forward looking for the first significant mask octet */
10947       for (i = 0; i < vec_len (mask); i++)
10948         if (mask[i])
10949           break;
10950
10951       /* compute (skip, match) params */
10952       *skipp = i / sizeof (u32x4);
10953       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10954
10955       /* Pad mask to an even multiple of the vector size */
10956       while (vec_len (mask) % sizeof (u32x4))
10957         vec_add1 (mask, 0);
10958
10959       match = vec_len (mask) / sizeof (u32x4);
10960
10961       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10962         {
10963           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10964           if (*tmp || *(tmp + 1))
10965             break;
10966           match--;
10967         }
10968       if (match == 0)
10969         clib_warning ("BUG: match 0");
10970
10971       _vec_len (mask) = match * sizeof (u32x4);
10972
10973       *matchp = match;
10974       *maskp = mask;
10975
10976       return 1;
10977     }
10978
10979   return 0;
10980 }
10981 #endif /* VPP_API_TEST_BUILTIN */
10982
10983 #define foreach_l2_next                         \
10984 _(drop, DROP)                                   \
10985 _(ethernet, ETHERNET_INPUT)                     \
10986 _(ip4, IP4_INPUT)                               \
10987 _(ip6, IP6_INPUT)
10988
10989 uword
10990 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10991 {
10992   u32 *miss_next_indexp = va_arg (*args, u32 *);
10993   u32 next_index = 0;
10994   u32 tmp;
10995
10996 #define _(n,N) \
10997   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10998   foreach_l2_next;
10999 #undef _
11000
11001   if (unformat (input, "%d", &tmp))
11002     {
11003       next_index = tmp;
11004       goto out;
11005     }
11006
11007   return 0;
11008
11009 out:
11010   *miss_next_indexp = next_index;
11011   return 1;
11012 }
11013
11014 #define foreach_ip_next                         \
11015 _(drop, DROP)                                   \
11016 _(local, LOCAL)                                 \
11017 _(rewrite, REWRITE)
11018
11019 uword
11020 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11021 {
11022   u32 *miss_next_indexp = va_arg (*args, u32 *);
11023   u32 next_index = 0;
11024   u32 tmp;
11025
11026 #define _(n,N) \
11027   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11028   foreach_ip_next;
11029 #undef _
11030
11031   if (unformat (input, "%d", &tmp))
11032     {
11033       next_index = tmp;
11034       goto out;
11035     }
11036
11037   return 0;
11038
11039 out:
11040   *miss_next_indexp = next_index;
11041   return 1;
11042 }
11043
11044 #define foreach_acl_next                        \
11045 _(deny, DENY)
11046
11047 uword
11048 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *miss_next_indexp = va_arg (*args, u32 *);
11051   u32 next_index = 0;
11052   u32 tmp;
11053
11054 #define _(n,N) \
11055   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11056   foreach_acl_next;
11057 #undef _
11058
11059   if (unformat (input, "permit"))
11060     {
11061       next_index = ~0;
11062       goto out;
11063     }
11064   else if (unformat (input, "%d", &tmp))
11065     {
11066       next_index = tmp;
11067       goto out;
11068     }
11069
11070   return 0;
11071
11072 out:
11073   *miss_next_indexp = next_index;
11074   return 1;
11075 }
11076
11077 uword
11078 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11079 {
11080   u32 *r = va_arg (*args, u32 *);
11081
11082   if (unformat (input, "conform-color"))
11083     *r = POLICE_CONFORM;
11084   else if (unformat (input, "exceed-color"))
11085     *r = POLICE_EXCEED;
11086   else
11087     return 0;
11088
11089   return 1;
11090 }
11091
11092 static int
11093 api_classify_add_del_table (vat_main_t * vam)
11094 {
11095   unformat_input_t *i = vam->input;
11096   vl_api_classify_add_del_table_t *mp;
11097
11098   u32 nbuckets = 2;
11099   u32 skip = ~0;
11100   u32 match = ~0;
11101   int is_add = 1;
11102   int del_chain = 0;
11103   u32 table_index = ~0;
11104   u32 next_table_index = ~0;
11105   u32 miss_next_index = ~0;
11106   u32 memory_size = 32 << 20;
11107   u8 *mask = 0;
11108   u32 current_data_flag = 0;
11109   int current_data_offset = 0;
11110   int ret;
11111
11112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11113     {
11114       if (unformat (i, "del"))
11115         is_add = 0;
11116       else if (unformat (i, "del-chain"))
11117         {
11118           is_add = 0;
11119           del_chain = 1;
11120         }
11121       else if (unformat (i, "buckets %d", &nbuckets))
11122         ;
11123       else if (unformat (i, "memory_size %d", &memory_size))
11124         ;
11125       else if (unformat (i, "skip %d", &skip))
11126         ;
11127       else if (unformat (i, "match %d", &match))
11128         ;
11129       else if (unformat (i, "table %d", &table_index))
11130         ;
11131       else if (unformat (i, "mask %U", unformat_classify_mask,
11132                          &mask, &skip, &match))
11133         ;
11134       else if (unformat (i, "next-table %d", &next_table_index))
11135         ;
11136       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11137                          &miss_next_index))
11138         ;
11139       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11140                          &miss_next_index))
11141         ;
11142       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11143                          &miss_next_index))
11144         ;
11145       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11146         ;
11147       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11148         ;
11149       else
11150         break;
11151     }
11152
11153   if (is_add && mask == 0)
11154     {
11155       errmsg ("Mask required");
11156       return -99;
11157     }
11158
11159   if (is_add && skip == ~0)
11160     {
11161       errmsg ("skip count required");
11162       return -99;
11163     }
11164
11165   if (is_add && match == ~0)
11166     {
11167       errmsg ("match count required");
11168       return -99;
11169     }
11170
11171   if (!is_add && table_index == ~0)
11172     {
11173       errmsg ("table index required for delete");
11174       return -99;
11175     }
11176
11177   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11178
11179   mp->is_add = is_add;
11180   mp->del_chain = del_chain;
11181   mp->table_index = ntohl (table_index);
11182   mp->nbuckets = ntohl (nbuckets);
11183   mp->memory_size = ntohl (memory_size);
11184   mp->skip_n_vectors = ntohl (skip);
11185   mp->match_n_vectors = ntohl (match);
11186   mp->next_table_index = ntohl (next_table_index);
11187   mp->miss_next_index = ntohl (miss_next_index);
11188   mp->current_data_flag = ntohl (current_data_flag);
11189   mp->current_data_offset = ntohl (current_data_offset);
11190   clib_memcpy (mp->mask, mask, vec_len (mask));
11191
11192   vec_free (mask);
11193
11194   S (mp);
11195   W (ret);
11196   return ret;
11197 }
11198
11199 #if VPP_API_TEST_BUILTIN == 0
11200 uword
11201 unformat_l4_match (unformat_input_t * input, va_list * args)
11202 {
11203   u8 **matchp = va_arg (*args, u8 **);
11204
11205   u8 *proto_header = 0;
11206   int src_port = 0;
11207   int dst_port = 0;
11208
11209   tcpudp_header_t h;
11210
11211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11212     {
11213       if (unformat (input, "src_port %d", &src_port))
11214         ;
11215       else if (unformat (input, "dst_port %d", &dst_port))
11216         ;
11217       else
11218         return 0;
11219     }
11220
11221   h.src_port = clib_host_to_net_u16 (src_port);
11222   h.dst_port = clib_host_to_net_u16 (dst_port);
11223   vec_validate (proto_header, sizeof (h) - 1);
11224   memcpy (proto_header, &h, sizeof (h));
11225
11226   *matchp = proto_header;
11227
11228   return 1;
11229 }
11230
11231 uword
11232 unformat_ip4_match (unformat_input_t * input, va_list * args)
11233 {
11234   u8 **matchp = va_arg (*args, u8 **);
11235   u8 *match = 0;
11236   ip4_header_t *ip;
11237   int version = 0;
11238   u32 version_val;
11239   int hdr_length = 0;
11240   u32 hdr_length_val;
11241   int src = 0, dst = 0;
11242   ip4_address_t src_val, dst_val;
11243   int proto = 0;
11244   u32 proto_val;
11245   int tos = 0;
11246   u32 tos_val;
11247   int length = 0;
11248   u32 length_val;
11249   int fragment_id = 0;
11250   u32 fragment_id_val;
11251   int ttl = 0;
11252   int ttl_val;
11253   int checksum = 0;
11254   u32 checksum_val;
11255
11256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11257     {
11258       if (unformat (input, "version %d", &version_val))
11259         version = 1;
11260       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11261         hdr_length = 1;
11262       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11263         src = 1;
11264       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11265         dst = 1;
11266       else if (unformat (input, "proto %d", &proto_val))
11267         proto = 1;
11268       else if (unformat (input, "tos %d", &tos_val))
11269         tos = 1;
11270       else if (unformat (input, "length %d", &length_val))
11271         length = 1;
11272       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11273         fragment_id = 1;
11274       else if (unformat (input, "ttl %d", &ttl_val))
11275         ttl = 1;
11276       else if (unformat (input, "checksum %d", &checksum_val))
11277         checksum = 1;
11278       else
11279         break;
11280     }
11281
11282   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11283       + ttl + checksum == 0)
11284     return 0;
11285
11286   /*
11287    * Aligned because we use the real comparison functions
11288    */
11289   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11290
11291   ip = (ip4_header_t *) match;
11292
11293   /* These are realistically matched in practice */
11294   if (src)
11295     ip->src_address.as_u32 = src_val.as_u32;
11296
11297   if (dst)
11298     ip->dst_address.as_u32 = dst_val.as_u32;
11299
11300   if (proto)
11301     ip->protocol = proto_val;
11302
11303
11304   /* These are not, but they're included for completeness */
11305   if (version)
11306     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11307
11308   if (hdr_length)
11309     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11310
11311   if (tos)
11312     ip->tos = tos_val;
11313
11314   if (length)
11315     ip->length = clib_host_to_net_u16 (length_val);
11316
11317   if (ttl)
11318     ip->ttl = ttl_val;
11319
11320   if (checksum)
11321     ip->checksum = clib_host_to_net_u16 (checksum_val);
11322
11323   *matchp = match;
11324   return 1;
11325 }
11326
11327 uword
11328 unformat_ip6_match (unformat_input_t * input, va_list * args)
11329 {
11330   u8 **matchp = va_arg (*args, u8 **);
11331   u8 *match = 0;
11332   ip6_header_t *ip;
11333   int version = 0;
11334   u32 version_val;
11335   u8 traffic_class = 0;
11336   u32 traffic_class_val = 0;
11337   u8 flow_label = 0;
11338   u8 flow_label_val;
11339   int src = 0, dst = 0;
11340   ip6_address_t src_val, dst_val;
11341   int proto = 0;
11342   u32 proto_val;
11343   int payload_length = 0;
11344   u32 payload_length_val;
11345   int hop_limit = 0;
11346   int hop_limit_val;
11347   u32 ip_version_traffic_class_and_flow_label;
11348
11349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (input, "version %d", &version_val))
11352         version = 1;
11353       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11354         traffic_class = 1;
11355       else if (unformat (input, "flow_label %d", &flow_label_val))
11356         flow_label = 1;
11357       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11358         src = 1;
11359       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11360         dst = 1;
11361       else if (unformat (input, "proto %d", &proto_val))
11362         proto = 1;
11363       else if (unformat (input, "payload_length %d", &payload_length_val))
11364         payload_length = 1;
11365       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11366         hop_limit = 1;
11367       else
11368         break;
11369     }
11370
11371   if (version + traffic_class + flow_label + src + dst + proto +
11372       payload_length + hop_limit == 0)
11373     return 0;
11374
11375   /*
11376    * Aligned because we use the real comparison functions
11377    */
11378   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11379
11380   ip = (ip6_header_t *) match;
11381
11382   if (src)
11383     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11384
11385   if (dst)
11386     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11387
11388   if (proto)
11389     ip->protocol = proto_val;
11390
11391   ip_version_traffic_class_and_flow_label = 0;
11392
11393   if (version)
11394     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11395
11396   if (traffic_class)
11397     ip_version_traffic_class_and_flow_label |=
11398       (traffic_class_val & 0xFF) << 20;
11399
11400   if (flow_label)
11401     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11402
11403   ip->ip_version_traffic_class_and_flow_label =
11404     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11405
11406   if (payload_length)
11407     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11408
11409   if (hop_limit)
11410     ip->hop_limit = hop_limit_val;
11411
11412   *matchp = match;
11413   return 1;
11414 }
11415
11416 uword
11417 unformat_l3_match (unformat_input_t * input, va_list * args)
11418 {
11419   u8 **matchp = va_arg (*args, u8 **);
11420
11421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11422     {
11423       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11424         return 1;
11425       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11426         return 1;
11427       else
11428         break;
11429     }
11430   return 0;
11431 }
11432
11433 uword
11434 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11435 {
11436   u8 *tagp = va_arg (*args, u8 *);
11437   u32 tag;
11438
11439   if (unformat (input, "%d", &tag))
11440     {
11441       tagp[0] = (tag >> 8) & 0x0F;
11442       tagp[1] = tag & 0xFF;
11443       return 1;
11444     }
11445
11446   return 0;
11447 }
11448
11449 uword
11450 unformat_l2_match (unformat_input_t * input, va_list * args)
11451 {
11452   u8 **matchp = va_arg (*args, u8 **);
11453   u8 *match = 0;
11454   u8 src = 0;
11455   u8 src_val[6];
11456   u8 dst = 0;
11457   u8 dst_val[6];
11458   u8 proto = 0;
11459   u16 proto_val;
11460   u8 tag1 = 0;
11461   u8 tag1_val[2];
11462   u8 tag2 = 0;
11463   u8 tag2_val[2];
11464   int len = 14;
11465   u8 ignore_tag1 = 0;
11466   u8 ignore_tag2 = 0;
11467   u8 cos1 = 0;
11468   u8 cos2 = 0;
11469   u32 cos1_val = 0;
11470   u32 cos2_val = 0;
11471
11472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11473     {
11474       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11475         src = 1;
11476       else
11477         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11478         dst = 1;
11479       else if (unformat (input, "proto %U",
11480                          unformat_ethernet_type_host_byte_order, &proto_val))
11481         proto = 1;
11482       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11483         tag1 = 1;
11484       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11485         tag2 = 1;
11486       else if (unformat (input, "ignore-tag1"))
11487         ignore_tag1 = 1;
11488       else if (unformat (input, "ignore-tag2"))
11489         ignore_tag2 = 1;
11490       else if (unformat (input, "cos1 %d", &cos1_val))
11491         cos1 = 1;
11492       else if (unformat (input, "cos2 %d", &cos2_val))
11493         cos2 = 1;
11494       else
11495         break;
11496     }
11497   if ((src + dst + proto + tag1 + tag2 +
11498        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11499     return 0;
11500
11501   if (tag1 || ignore_tag1 || cos1)
11502     len = 18;
11503   if (tag2 || ignore_tag2 || cos2)
11504     len = 22;
11505
11506   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11507
11508   if (dst)
11509     clib_memcpy (match, dst_val, 6);
11510
11511   if (src)
11512     clib_memcpy (match + 6, src_val, 6);
11513
11514   if (tag2)
11515     {
11516       /* inner vlan tag */
11517       match[19] = tag2_val[1];
11518       match[18] = tag2_val[0];
11519       if (cos2)
11520         match[18] |= (cos2_val & 0x7) << 5;
11521       if (proto)
11522         {
11523           match[21] = proto_val & 0xff;
11524           match[20] = proto_val >> 8;
11525         }
11526       if (tag1)
11527         {
11528           match[15] = tag1_val[1];
11529           match[14] = tag1_val[0];
11530         }
11531       if (cos1)
11532         match[14] |= (cos1_val & 0x7) << 5;
11533       *matchp = match;
11534       return 1;
11535     }
11536   if (tag1)
11537     {
11538       match[15] = tag1_val[1];
11539       match[14] = tag1_val[0];
11540       if (proto)
11541         {
11542           match[17] = proto_val & 0xff;
11543           match[16] = proto_val >> 8;
11544         }
11545       if (cos1)
11546         match[14] |= (cos1_val & 0x7) << 5;
11547
11548       *matchp = match;
11549       return 1;
11550     }
11551   if (cos2)
11552     match[18] |= (cos2_val & 0x7) << 5;
11553   if (cos1)
11554     match[14] |= (cos1_val & 0x7) << 5;
11555   if (proto)
11556     {
11557       match[13] = proto_val & 0xff;
11558       match[12] = proto_val >> 8;
11559     }
11560
11561   *matchp = match;
11562   return 1;
11563 }
11564 #endif
11565
11566 uword
11567 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11568 {
11569   u8 **matchp = va_arg (*args, u8 **);
11570   u32 skip_n_vectors = va_arg (*args, u32);
11571   u32 match_n_vectors = va_arg (*args, u32);
11572
11573   u8 *match = 0;
11574   u8 *l2 = 0;
11575   u8 *l3 = 0;
11576   u8 *l4 = 0;
11577
11578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (input, "hex %U", unformat_hex_string, &match))
11581         ;
11582       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11583         ;
11584       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11585         ;
11586       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11587         ;
11588       else
11589         break;
11590     }
11591
11592   if (l4 && !l3)
11593     {
11594       vec_free (match);
11595       vec_free (l2);
11596       vec_free (l4);
11597       return 0;
11598     }
11599
11600   if (match || l2 || l3 || l4)
11601     {
11602       if (l2 || l3 || l4)
11603         {
11604           /* "Win a free Ethernet header in every packet" */
11605           if (l2 == 0)
11606             vec_validate_aligned (l2, 13, sizeof (u32x4));
11607           match = l2;
11608           if (vec_len (l3))
11609             {
11610               vec_append_aligned (match, l3, sizeof (u32x4));
11611               vec_free (l3);
11612             }
11613           if (vec_len (l4))
11614             {
11615               vec_append_aligned (match, l4, sizeof (u32x4));
11616               vec_free (l4);
11617             }
11618         }
11619
11620       /* Make sure the vector is big enough even if key is all 0's */
11621       vec_validate_aligned
11622         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11623          sizeof (u32x4));
11624
11625       /* Set size, include skipped vectors */
11626       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11627
11628       *matchp = match;
11629
11630       return 1;
11631     }
11632
11633   return 0;
11634 }
11635
11636 static int
11637 api_classify_add_del_session (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   vl_api_classify_add_del_session_t *mp;
11641   int is_add = 1;
11642   u32 table_index = ~0;
11643   u32 hit_next_index = ~0;
11644   u32 opaque_index = ~0;
11645   u8 *match = 0;
11646   i32 advance = 0;
11647   u32 skip_n_vectors = 0;
11648   u32 match_n_vectors = 0;
11649   u32 action = 0;
11650   u32 metadata = 0;
11651   int ret;
11652
11653   /*
11654    * Warning: you have to supply skip_n and match_n
11655    * because the API client cant simply look at the classify
11656    * table object.
11657    */
11658
11659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11660     {
11661       if (unformat (i, "del"))
11662         is_add = 0;
11663       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11664                          &hit_next_index))
11665         ;
11666       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11667                          &hit_next_index))
11668         ;
11669       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11670                          &hit_next_index))
11671         ;
11672       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11673         ;
11674       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11675         ;
11676       else if (unformat (i, "opaque-index %d", &opaque_index))
11677         ;
11678       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11679         ;
11680       else if (unformat (i, "match_n %d", &match_n_vectors))
11681         ;
11682       else if (unformat (i, "match %U", api_unformat_classify_match,
11683                          &match, skip_n_vectors, match_n_vectors))
11684         ;
11685       else if (unformat (i, "advance %d", &advance))
11686         ;
11687       else if (unformat (i, "table-index %d", &table_index))
11688         ;
11689       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11690         action = 1;
11691       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11692         action = 2;
11693       else if (unformat (i, "action %d", &action))
11694         ;
11695       else if (unformat (i, "metadata %d", &metadata))
11696         ;
11697       else
11698         break;
11699     }
11700
11701   if (table_index == ~0)
11702     {
11703       errmsg ("Table index required");
11704       return -99;
11705     }
11706
11707   if (is_add && match == 0)
11708     {
11709       errmsg ("Match value required");
11710       return -99;
11711     }
11712
11713   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11714
11715   mp->is_add = is_add;
11716   mp->table_index = ntohl (table_index);
11717   mp->hit_next_index = ntohl (hit_next_index);
11718   mp->opaque_index = ntohl (opaque_index);
11719   mp->advance = ntohl (advance);
11720   mp->action = action;
11721   mp->metadata = ntohl (metadata);
11722   clib_memcpy (mp->match, match, vec_len (match));
11723   vec_free (match);
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_classify_set_interface_ip_table (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_classify_set_interface_ip_table_t *mp;
11735   u32 sw_if_index;
11736   int sw_if_index_set;
11737   u32 table_index = ~0;
11738   u8 is_ipv6 = 0;
11739   int ret;
11740
11741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11744         sw_if_index_set = 1;
11745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11746         sw_if_index_set = 1;
11747       else if (unformat (i, "table %d", &table_index))
11748         ;
11749       else
11750         {
11751           clib_warning ("parse error '%U'", format_unformat_error, i);
11752           return -99;
11753         }
11754     }
11755
11756   if (sw_if_index_set == 0)
11757     {
11758       errmsg ("missing interface name or sw_if_index");
11759       return -99;
11760     }
11761
11762
11763   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11764
11765   mp->sw_if_index = ntohl (sw_if_index);
11766   mp->table_index = ntohl (table_index);
11767   mp->is_ipv6 = is_ipv6;
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static int
11775 api_classify_set_interface_l2_tables (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_classify_set_interface_l2_tables_t *mp;
11779   u32 sw_if_index;
11780   int sw_if_index_set;
11781   u32 ip4_table_index = ~0;
11782   u32 ip6_table_index = ~0;
11783   u32 other_table_index = ~0;
11784   u32 is_input = 1;
11785   int ret;
11786
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11790         sw_if_index_set = 1;
11791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11792         sw_if_index_set = 1;
11793       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11794         ;
11795       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11796         ;
11797       else if (unformat (i, "other-table %d", &other_table_index))
11798         ;
11799       else if (unformat (i, "is-input %d", &is_input))
11800         ;
11801       else
11802         {
11803           clib_warning ("parse error '%U'", format_unformat_error, i);
11804           return -99;
11805         }
11806     }
11807
11808   if (sw_if_index_set == 0)
11809     {
11810       errmsg ("missing interface name or sw_if_index");
11811       return -99;
11812     }
11813
11814
11815   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11816
11817   mp->sw_if_index = ntohl (sw_if_index);
11818   mp->ip4_table_index = ntohl (ip4_table_index);
11819   mp->ip6_table_index = ntohl (ip6_table_index);
11820   mp->other_table_index = ntohl (other_table_index);
11821   mp->is_input = (u8) is_input;
11822
11823   S (mp);
11824   W (ret);
11825   return ret;
11826 }
11827
11828 static int
11829 api_set_ipfix_exporter (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_set_ipfix_exporter_t *mp;
11833   ip4_address_t collector_address;
11834   u8 collector_address_set = 0;
11835   u32 collector_port = ~0;
11836   ip4_address_t src_address;
11837   u8 src_address_set = 0;
11838   u32 vrf_id = ~0;
11839   u32 path_mtu = ~0;
11840   u32 template_interval = ~0;
11841   u8 udp_checksum = 0;
11842   int ret;
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "collector_address %U", unformat_ip4_address,
11847                     &collector_address))
11848         collector_address_set = 1;
11849       else if (unformat (i, "collector_port %d", &collector_port))
11850         ;
11851       else if (unformat (i, "src_address %U", unformat_ip4_address,
11852                          &src_address))
11853         src_address_set = 1;
11854       else if (unformat (i, "vrf_id %d", &vrf_id))
11855         ;
11856       else if (unformat (i, "path_mtu %d", &path_mtu))
11857         ;
11858       else if (unformat (i, "template_interval %d", &template_interval))
11859         ;
11860       else if (unformat (i, "udp_checksum"))
11861         udp_checksum = 1;
11862       else
11863         break;
11864     }
11865
11866   if (collector_address_set == 0)
11867     {
11868       errmsg ("collector_address required");
11869       return -99;
11870     }
11871
11872   if (src_address_set == 0)
11873     {
11874       errmsg ("src_address required");
11875       return -99;
11876     }
11877
11878   M (SET_IPFIX_EXPORTER, mp);
11879
11880   memcpy (mp->collector_address, collector_address.data,
11881           sizeof (collector_address.data));
11882   mp->collector_port = htons ((u16) collector_port);
11883   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11884   mp->vrf_id = htonl (vrf_id);
11885   mp->path_mtu = htonl (path_mtu);
11886   mp->template_interval = htonl (template_interval);
11887   mp->udp_checksum = udp_checksum;
11888
11889   S (mp);
11890   W (ret);
11891   return ret;
11892 }
11893
11894 static int
11895 api_set_ipfix_classify_stream (vat_main_t * vam)
11896 {
11897   unformat_input_t *i = vam->input;
11898   vl_api_set_ipfix_classify_stream_t *mp;
11899   u32 domain_id = 0;
11900   u32 src_port = UDP_DST_PORT_ipfix;
11901   int ret;
11902
11903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11904     {
11905       if (unformat (i, "domain %d", &domain_id))
11906         ;
11907       else if (unformat (i, "src_port %d", &src_port))
11908         ;
11909       else
11910         {
11911           errmsg ("unknown input `%U'", format_unformat_error, i);
11912           return -99;
11913         }
11914     }
11915
11916   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11917
11918   mp->domain_id = htonl (domain_id);
11919   mp->src_port = htons ((u16) src_port);
11920
11921   S (mp);
11922   W (ret);
11923   return ret;
11924 }
11925
11926 static int
11927 api_ipfix_classify_table_add_del (vat_main_t * vam)
11928 {
11929   unformat_input_t *i = vam->input;
11930   vl_api_ipfix_classify_table_add_del_t *mp;
11931   int is_add = -1;
11932   u32 classify_table_index = ~0;
11933   u8 ip_version = 0;
11934   u8 transport_protocol = 255;
11935   int ret;
11936
11937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11938     {
11939       if (unformat (i, "add"))
11940         is_add = 1;
11941       else if (unformat (i, "del"))
11942         is_add = 0;
11943       else if (unformat (i, "table %d", &classify_table_index))
11944         ;
11945       else if (unformat (i, "ip4"))
11946         ip_version = 4;
11947       else if (unformat (i, "ip6"))
11948         ip_version = 6;
11949       else if (unformat (i, "tcp"))
11950         transport_protocol = 6;
11951       else if (unformat (i, "udp"))
11952         transport_protocol = 17;
11953       else
11954         {
11955           errmsg ("unknown input `%U'", format_unformat_error, i);
11956           return -99;
11957         }
11958     }
11959
11960   if (is_add == -1)
11961     {
11962       errmsg ("expecting: add|del");
11963       return -99;
11964     }
11965   if (classify_table_index == ~0)
11966     {
11967       errmsg ("classifier table not specified");
11968       return -99;
11969     }
11970   if (ip_version == 0)
11971     {
11972       errmsg ("IP version not specified");
11973       return -99;
11974     }
11975
11976   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11977
11978   mp->is_add = is_add;
11979   mp->table_id = htonl (classify_table_index);
11980   mp->ip_version = ip_version;
11981   mp->transport_protocol = transport_protocol;
11982
11983   S (mp);
11984   W (ret);
11985   return ret;
11986 }
11987
11988 static int
11989 api_get_node_index (vat_main_t * vam)
11990 {
11991   unformat_input_t *i = vam->input;
11992   vl_api_get_node_index_t *mp;
11993   u8 *name = 0;
11994   int ret;
11995
11996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (i, "node %s", &name))
11999         ;
12000       else
12001         break;
12002     }
12003   if (name == 0)
12004     {
12005       errmsg ("node name required");
12006       return -99;
12007     }
12008   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12009     {
12010       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12011       return -99;
12012     }
12013
12014   M (GET_NODE_INDEX, mp);
12015   clib_memcpy (mp->node_name, name, vec_len (name));
12016   vec_free (name);
12017
12018   S (mp);
12019   W (ret);
12020   return ret;
12021 }
12022
12023 static int
12024 api_get_next_index (vat_main_t * vam)
12025 {
12026   unformat_input_t *i = vam->input;
12027   vl_api_get_next_index_t *mp;
12028   u8 *node_name = 0, *next_node_name = 0;
12029   int ret;
12030
12031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (i, "node-name %s", &node_name))
12034         ;
12035       else if (unformat (i, "next-node-name %s", &next_node_name))
12036         break;
12037     }
12038
12039   if (node_name == 0)
12040     {
12041       errmsg ("node name required");
12042       return -99;
12043     }
12044   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12045     {
12046       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12047       return -99;
12048     }
12049
12050   if (next_node_name == 0)
12051     {
12052       errmsg ("next node name required");
12053       return -99;
12054     }
12055   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12056     {
12057       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12058       return -99;
12059     }
12060
12061   M (GET_NEXT_INDEX, mp);
12062   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12063   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12064   vec_free (node_name);
12065   vec_free (next_node_name);
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 static int
12073 api_add_node_next (vat_main_t * vam)
12074 {
12075   unformat_input_t *i = vam->input;
12076   vl_api_add_node_next_t *mp;
12077   u8 *name = 0;
12078   u8 *next = 0;
12079   int ret;
12080
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "node %s", &name))
12084         ;
12085       else if (unformat (i, "next %s", &next))
12086         ;
12087       else
12088         break;
12089     }
12090   if (name == 0)
12091     {
12092       errmsg ("node name required");
12093       return -99;
12094     }
12095   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12096     {
12097       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12098       return -99;
12099     }
12100   if (next == 0)
12101     {
12102       errmsg ("next node required");
12103       return -99;
12104     }
12105   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12106     {
12107       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12108       return -99;
12109     }
12110
12111   M (ADD_NODE_NEXT, mp);
12112   clib_memcpy (mp->node_name, name, vec_len (name));
12113   clib_memcpy (mp->next_name, next, vec_len (next));
12114   vec_free (name);
12115   vec_free (next);
12116
12117   S (mp);
12118   W (ret);
12119   return ret;
12120 }
12121
12122 static int
12123 api_l2tpv3_create_tunnel (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   ip6_address_t client_address, our_address;
12127   int client_address_set = 0;
12128   int our_address_set = 0;
12129   u32 local_session_id = 0;
12130   u32 remote_session_id = 0;
12131   u64 local_cookie = 0;
12132   u64 remote_cookie = 0;
12133   u8 l2_sublayer_present = 0;
12134   vl_api_l2tpv3_create_tunnel_t *mp;
12135   int ret;
12136
12137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (i, "client_address %U", unformat_ip6_address,
12140                     &client_address))
12141         client_address_set = 1;
12142       else if (unformat (i, "our_address %U", unformat_ip6_address,
12143                          &our_address))
12144         our_address_set = 1;
12145       else if (unformat (i, "local_session_id %d", &local_session_id))
12146         ;
12147       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12148         ;
12149       else if (unformat (i, "local_cookie %lld", &local_cookie))
12150         ;
12151       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12152         ;
12153       else if (unformat (i, "l2-sublayer-present"))
12154         l2_sublayer_present = 1;
12155       else
12156         break;
12157     }
12158
12159   if (client_address_set == 0)
12160     {
12161       errmsg ("client_address required");
12162       return -99;
12163     }
12164
12165   if (our_address_set == 0)
12166     {
12167       errmsg ("our_address required");
12168       return -99;
12169     }
12170
12171   M (L2TPV3_CREATE_TUNNEL, mp);
12172
12173   clib_memcpy (mp->client_address, client_address.as_u8,
12174                sizeof (mp->client_address));
12175
12176   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12177
12178   mp->local_session_id = ntohl (local_session_id);
12179   mp->remote_session_id = ntohl (remote_session_id);
12180   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12181   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12182   mp->l2_sublayer_present = l2_sublayer_present;
12183   mp->is_ipv6 = 1;
12184
12185   S (mp);
12186   W (ret);
12187   return ret;
12188 }
12189
12190 static int
12191 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12192 {
12193   unformat_input_t *i = vam->input;
12194   u32 sw_if_index;
12195   u8 sw_if_index_set = 0;
12196   u64 new_local_cookie = 0;
12197   u64 new_remote_cookie = 0;
12198   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12199   int ret;
12200
12201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12202     {
12203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12204         sw_if_index_set = 1;
12205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12206         sw_if_index_set = 1;
12207       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12208         ;
12209       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12210         ;
12211       else
12212         break;
12213     }
12214
12215   if (sw_if_index_set == 0)
12216     {
12217       errmsg ("missing interface name or sw_if_index");
12218       return -99;
12219     }
12220
12221   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12222
12223   mp->sw_if_index = ntohl (sw_if_index);
12224   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12225   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12226
12227   S (mp);
12228   W (ret);
12229   return ret;
12230 }
12231
12232 static int
12233 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12234 {
12235   unformat_input_t *i = vam->input;
12236   vl_api_l2tpv3_interface_enable_disable_t *mp;
12237   u32 sw_if_index;
12238   u8 sw_if_index_set = 0;
12239   u8 enable_disable = 1;
12240   int ret;
12241
12242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12243     {
12244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12245         sw_if_index_set = 1;
12246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12247         sw_if_index_set = 1;
12248       else if (unformat (i, "enable"))
12249         enable_disable = 1;
12250       else if (unformat (i, "disable"))
12251         enable_disable = 0;
12252       else
12253         break;
12254     }
12255
12256   if (sw_if_index_set == 0)
12257     {
12258       errmsg ("missing interface name or sw_if_index");
12259       return -99;
12260     }
12261
12262   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12263
12264   mp->sw_if_index = ntohl (sw_if_index);
12265   mp->enable_disable = enable_disable;
12266
12267   S (mp);
12268   W (ret);
12269   return ret;
12270 }
12271
12272 static int
12273 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12274 {
12275   unformat_input_t *i = vam->input;
12276   vl_api_l2tpv3_set_lookup_key_t *mp;
12277   u8 key = ~0;
12278   int ret;
12279
12280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12281     {
12282       if (unformat (i, "lookup_v6_src"))
12283         key = L2T_LOOKUP_SRC_ADDRESS;
12284       else if (unformat (i, "lookup_v6_dst"))
12285         key = L2T_LOOKUP_DST_ADDRESS;
12286       else if (unformat (i, "lookup_session_id"))
12287         key = L2T_LOOKUP_SESSION_ID;
12288       else
12289         break;
12290     }
12291
12292   if (key == (u8) ~ 0)
12293     {
12294       errmsg ("l2tp session lookup key unset");
12295       return -99;
12296     }
12297
12298   M (L2TPV3_SET_LOOKUP_KEY, mp);
12299
12300   mp->key = key;
12301
12302   S (mp);
12303   W (ret);
12304   return ret;
12305 }
12306
12307 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12308   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12309 {
12310   vat_main_t *vam = &vat_main;
12311
12312   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12313          format_ip6_address, mp->our_address,
12314          format_ip6_address, mp->client_address,
12315          clib_net_to_host_u32 (mp->sw_if_index));
12316
12317   print (vam->ofp,
12318          "   local cookies %016llx %016llx remote cookie %016llx",
12319          clib_net_to_host_u64 (mp->local_cookie[0]),
12320          clib_net_to_host_u64 (mp->local_cookie[1]),
12321          clib_net_to_host_u64 (mp->remote_cookie));
12322
12323   print (vam->ofp, "   local session-id %d remote session-id %d",
12324          clib_net_to_host_u32 (mp->local_session_id),
12325          clib_net_to_host_u32 (mp->remote_session_id));
12326
12327   print (vam->ofp, "   l2 specific sublayer %s\n",
12328          mp->l2_sublayer_present ? "preset" : "absent");
12329
12330 }
12331
12332 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12333   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12334 {
12335   vat_main_t *vam = &vat_main;
12336   vat_json_node_t *node = NULL;
12337   struct in6_addr addr;
12338
12339   if (VAT_JSON_ARRAY != vam->json_tree.type)
12340     {
12341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12342       vat_json_init_array (&vam->json_tree);
12343     }
12344   node = vat_json_array_add (&vam->json_tree);
12345
12346   vat_json_init_object (node);
12347
12348   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12349   vat_json_object_add_ip6 (node, "our_address", addr);
12350   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12351   vat_json_object_add_ip6 (node, "client_address", addr);
12352
12353   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12354   vat_json_init_array (lc);
12355   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12356   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12357   vat_json_object_add_uint (node, "remote_cookie",
12358                             clib_net_to_host_u64 (mp->remote_cookie));
12359
12360   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12361   vat_json_object_add_uint (node, "local_session_id",
12362                             clib_net_to_host_u32 (mp->local_session_id));
12363   vat_json_object_add_uint (node, "remote_session_id",
12364                             clib_net_to_host_u32 (mp->remote_session_id));
12365   vat_json_object_add_string_copy (node, "l2_sublayer",
12366                                    mp->l2_sublayer_present ? (u8 *) "present"
12367                                    : (u8 *) "absent");
12368 }
12369
12370 static int
12371 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12372 {
12373   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12374   vl_api_control_ping_t *mp_ping;
12375   int ret;
12376
12377   /* Get list of l2tpv3-tunnel interfaces */
12378   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12379   S (mp);
12380
12381   /* Use a control ping for synchronization */
12382   MPING (CONTROL_PING, mp_ping);
12383   S (mp_ping);
12384
12385   W (ret);
12386   return ret;
12387 }
12388
12389
12390 static void vl_api_sw_interface_tap_details_t_handler
12391   (vl_api_sw_interface_tap_details_t * mp)
12392 {
12393   vat_main_t *vam = &vat_main;
12394
12395   print (vam->ofp, "%-16s %d",
12396          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12397 }
12398
12399 static void vl_api_sw_interface_tap_details_t_handler_json
12400   (vl_api_sw_interface_tap_details_t * mp)
12401 {
12402   vat_main_t *vam = &vat_main;
12403   vat_json_node_t *node = NULL;
12404
12405   if (VAT_JSON_ARRAY != vam->json_tree.type)
12406     {
12407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12408       vat_json_init_array (&vam->json_tree);
12409     }
12410   node = vat_json_array_add (&vam->json_tree);
12411
12412   vat_json_init_object (node);
12413   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12414   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12415 }
12416
12417 static int
12418 api_sw_interface_tap_dump (vat_main_t * vam)
12419 {
12420   vl_api_sw_interface_tap_dump_t *mp;
12421   vl_api_control_ping_t *mp_ping;
12422   int ret;
12423
12424   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12425   /* Get list of tap interfaces */
12426   M (SW_INTERFACE_TAP_DUMP, mp);
12427   S (mp);
12428
12429   /* Use a control ping for synchronization */
12430   MPING (CONTROL_PING, mp_ping);
12431   S (mp_ping);
12432
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static void vl_api_sw_interface_tap_v2_details_t_handler
12438   (vl_api_sw_interface_tap_v2_details_t * mp)
12439 {
12440   vat_main_t *vam = &vat_main;
12441
12442   print (vam->ofp, "%-16s %d",
12443          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12444 }
12445
12446 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12447   (vl_api_sw_interface_tap_v2_details_t * mp)
12448 {
12449   vat_main_t *vam = &vat_main;
12450   vat_json_node_t *node = NULL;
12451
12452   if (VAT_JSON_ARRAY != vam->json_tree.type)
12453     {
12454       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12455       vat_json_init_array (&vam->json_tree);
12456     }
12457   node = vat_json_array_add (&vam->json_tree);
12458
12459   vat_json_init_object (node);
12460   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12461   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12462 }
12463
12464 static int
12465 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12466 {
12467   vl_api_sw_interface_tap_v2_dump_t *mp;
12468   vl_api_control_ping_t *mp_ping;
12469   int ret;
12470
12471   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12472   /* Get list of tap interfaces */
12473   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12474   S (mp);
12475
12476   /* Use a control ping for synchronization */
12477   MPING (CONTROL_PING, mp_ping);
12478   S (mp_ping);
12479
12480   W (ret);
12481   return ret;
12482 }
12483
12484 static uword unformat_vxlan_decap_next
12485   (unformat_input_t * input, va_list * args)
12486 {
12487   u32 *result = va_arg (*args, u32 *);
12488   u32 tmp;
12489
12490   if (unformat (input, "l2"))
12491     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12492   else if (unformat (input, "%d", &tmp))
12493     *result = tmp;
12494   else
12495     return 0;
12496   return 1;
12497 }
12498
12499 static int
12500 api_vxlan_add_del_tunnel (vat_main_t * vam)
12501 {
12502   unformat_input_t *line_input = vam->input;
12503   vl_api_vxlan_add_del_tunnel_t *mp;
12504   ip46_address_t src, dst;
12505   u8 is_add = 1;
12506   u8 ipv4_set = 0, ipv6_set = 0;
12507   u8 src_set = 0;
12508   u8 dst_set = 0;
12509   u8 grp_set = 0;
12510   u32 mcast_sw_if_index = ~0;
12511   u32 encap_vrf_id = 0;
12512   u32 decap_next_index = ~0;
12513   u32 vni = 0;
12514   int ret;
12515
12516   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12517   memset (&src, 0, sizeof src);
12518   memset (&dst, 0, sizeof dst);
12519
12520   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12521     {
12522       if (unformat (line_input, "del"))
12523         is_add = 0;
12524       else
12525         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12526         {
12527           ipv4_set = 1;
12528           src_set = 1;
12529         }
12530       else
12531         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12532         {
12533           ipv4_set = 1;
12534           dst_set = 1;
12535         }
12536       else
12537         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12538         {
12539           ipv6_set = 1;
12540           src_set = 1;
12541         }
12542       else
12543         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12544         {
12545           ipv6_set = 1;
12546           dst_set = 1;
12547         }
12548       else if (unformat (line_input, "group %U %U",
12549                          unformat_ip4_address, &dst.ip4,
12550                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12551         {
12552           grp_set = dst_set = 1;
12553           ipv4_set = 1;
12554         }
12555       else if (unformat (line_input, "group %U",
12556                          unformat_ip4_address, &dst.ip4))
12557         {
12558           grp_set = dst_set = 1;
12559           ipv4_set = 1;
12560         }
12561       else if (unformat (line_input, "group %U %U",
12562                          unformat_ip6_address, &dst.ip6,
12563                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12564         {
12565           grp_set = dst_set = 1;
12566           ipv6_set = 1;
12567         }
12568       else if (unformat (line_input, "group %U",
12569                          unformat_ip6_address, &dst.ip6))
12570         {
12571           grp_set = dst_set = 1;
12572           ipv6_set = 1;
12573         }
12574       else
12575         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12576         ;
12577       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12578         ;
12579       else if (unformat (line_input, "decap-next %U",
12580                          unformat_vxlan_decap_next, &decap_next_index))
12581         ;
12582       else if (unformat (line_input, "vni %d", &vni))
12583         ;
12584       else
12585         {
12586           errmsg ("parse error '%U'", format_unformat_error, line_input);
12587           return -99;
12588         }
12589     }
12590
12591   if (src_set == 0)
12592     {
12593       errmsg ("tunnel src address not specified");
12594       return -99;
12595     }
12596   if (dst_set == 0)
12597     {
12598       errmsg ("tunnel dst address not specified");
12599       return -99;
12600     }
12601
12602   if (grp_set && !ip46_address_is_multicast (&dst))
12603     {
12604       errmsg ("tunnel group address not multicast");
12605       return -99;
12606     }
12607   if (grp_set && mcast_sw_if_index == ~0)
12608     {
12609       errmsg ("tunnel nonexistent multicast device");
12610       return -99;
12611     }
12612   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12613     {
12614       errmsg ("tunnel dst address must be unicast");
12615       return -99;
12616     }
12617
12618
12619   if (ipv4_set && ipv6_set)
12620     {
12621       errmsg ("both IPv4 and IPv6 addresses specified");
12622       return -99;
12623     }
12624
12625   if ((vni == 0) || (vni >> 24))
12626     {
12627       errmsg ("vni not specified or out of range");
12628       return -99;
12629     }
12630
12631   M (VXLAN_ADD_DEL_TUNNEL, mp);
12632
12633   if (ipv6_set)
12634     {
12635       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12636       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12637     }
12638   else
12639     {
12640       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12641       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12642     }
12643   mp->encap_vrf_id = ntohl (encap_vrf_id);
12644   mp->decap_next_index = ntohl (decap_next_index);
12645   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12646   mp->vni = ntohl (vni);
12647   mp->is_add = is_add;
12648   mp->is_ipv6 = ipv6_set;
12649
12650   S (mp);
12651   W (ret);
12652   return ret;
12653 }
12654
12655 static void vl_api_vxlan_tunnel_details_t_handler
12656   (vl_api_vxlan_tunnel_details_t * mp)
12657 {
12658   vat_main_t *vam = &vat_main;
12659   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12660   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12661
12662   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12663          ntohl (mp->sw_if_index),
12664          format_ip46_address, &src, IP46_TYPE_ANY,
12665          format_ip46_address, &dst, IP46_TYPE_ANY,
12666          ntohl (mp->encap_vrf_id),
12667          ntohl (mp->decap_next_index), ntohl (mp->vni),
12668          ntohl (mp->mcast_sw_if_index));
12669 }
12670
12671 static void vl_api_vxlan_tunnel_details_t_handler_json
12672   (vl_api_vxlan_tunnel_details_t * mp)
12673 {
12674   vat_main_t *vam = &vat_main;
12675   vat_json_node_t *node = NULL;
12676
12677   if (VAT_JSON_ARRAY != vam->json_tree.type)
12678     {
12679       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12680       vat_json_init_array (&vam->json_tree);
12681     }
12682   node = vat_json_array_add (&vam->json_tree);
12683
12684   vat_json_init_object (node);
12685   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12686   if (mp->is_ipv6)
12687     {
12688       struct in6_addr ip6;
12689
12690       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12691       vat_json_object_add_ip6 (node, "src_address", ip6);
12692       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12693       vat_json_object_add_ip6 (node, "dst_address", ip6);
12694     }
12695   else
12696     {
12697       struct in_addr ip4;
12698
12699       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12700       vat_json_object_add_ip4 (node, "src_address", ip4);
12701       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12702       vat_json_object_add_ip4 (node, "dst_address", ip4);
12703     }
12704   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12705   vat_json_object_add_uint (node, "decap_next_index",
12706                             ntohl (mp->decap_next_index));
12707   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12708   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12709   vat_json_object_add_uint (node, "mcast_sw_if_index",
12710                             ntohl (mp->mcast_sw_if_index));
12711 }
12712
12713 static int
12714 api_vxlan_tunnel_dump (vat_main_t * vam)
12715 {
12716   unformat_input_t *i = vam->input;
12717   vl_api_vxlan_tunnel_dump_t *mp;
12718   vl_api_control_ping_t *mp_ping;
12719   u32 sw_if_index;
12720   u8 sw_if_index_set = 0;
12721   int ret;
12722
12723   /* Parse args required to build the message */
12724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12725     {
12726       if (unformat (i, "sw_if_index %d", &sw_if_index))
12727         sw_if_index_set = 1;
12728       else
12729         break;
12730     }
12731
12732   if (sw_if_index_set == 0)
12733     {
12734       sw_if_index = ~0;
12735     }
12736
12737   if (!vam->json_output)
12738     {
12739       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12740              "sw_if_index", "src_address", "dst_address",
12741              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12742     }
12743
12744   /* Get list of vxlan-tunnel interfaces */
12745   M (VXLAN_TUNNEL_DUMP, mp);
12746
12747   mp->sw_if_index = htonl (sw_if_index);
12748
12749   S (mp);
12750
12751   /* Use a control ping for synchronization */
12752   MPING (CONTROL_PING, mp_ping);
12753   S (mp_ping);
12754
12755   W (ret);
12756   return ret;
12757 }
12758
12759 static uword unformat_geneve_decap_next
12760   (unformat_input_t * input, va_list * args)
12761 {
12762   u32 *result = va_arg (*args, u32 *);
12763   u32 tmp;
12764
12765   if (unformat (input, "l2"))
12766     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12767   else if (unformat (input, "%d", &tmp))
12768     *result = tmp;
12769   else
12770     return 0;
12771   return 1;
12772 }
12773
12774 static int
12775 api_geneve_add_del_tunnel (vat_main_t * vam)
12776 {
12777   unformat_input_t *line_input = vam->input;
12778   vl_api_geneve_add_del_tunnel_t *mp;
12779   ip46_address_t src, dst;
12780   u8 is_add = 1;
12781   u8 ipv4_set = 0, ipv6_set = 0;
12782   u8 src_set = 0;
12783   u8 dst_set = 0;
12784   u8 grp_set = 0;
12785   u32 mcast_sw_if_index = ~0;
12786   u32 encap_vrf_id = 0;
12787   u32 decap_next_index = ~0;
12788   u32 vni = 0;
12789   int ret;
12790
12791   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12792   memset (&src, 0, sizeof src);
12793   memset (&dst, 0, sizeof dst);
12794
12795   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12796     {
12797       if (unformat (line_input, "del"))
12798         is_add = 0;
12799       else
12800         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12801         {
12802           ipv4_set = 1;
12803           src_set = 1;
12804         }
12805       else
12806         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12807         {
12808           ipv4_set = 1;
12809           dst_set = 1;
12810         }
12811       else
12812         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12813         {
12814           ipv6_set = 1;
12815           src_set = 1;
12816         }
12817       else
12818         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12819         {
12820           ipv6_set = 1;
12821           dst_set = 1;
12822         }
12823       else if (unformat (line_input, "group %U %U",
12824                          unformat_ip4_address, &dst.ip4,
12825                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12826         {
12827           grp_set = dst_set = 1;
12828           ipv4_set = 1;
12829         }
12830       else if (unformat (line_input, "group %U",
12831                          unformat_ip4_address, &dst.ip4))
12832         {
12833           grp_set = dst_set = 1;
12834           ipv4_set = 1;
12835         }
12836       else if (unformat (line_input, "group %U %U",
12837                          unformat_ip6_address, &dst.ip6,
12838                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12839         {
12840           grp_set = dst_set = 1;
12841           ipv6_set = 1;
12842         }
12843       else if (unformat (line_input, "group %U",
12844                          unformat_ip6_address, &dst.ip6))
12845         {
12846           grp_set = dst_set = 1;
12847           ipv6_set = 1;
12848         }
12849       else
12850         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12851         ;
12852       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12853         ;
12854       else if (unformat (line_input, "decap-next %U",
12855                          unformat_geneve_decap_next, &decap_next_index))
12856         ;
12857       else if (unformat (line_input, "vni %d", &vni))
12858         ;
12859       else
12860         {
12861           errmsg ("parse error '%U'", format_unformat_error, line_input);
12862           return -99;
12863         }
12864     }
12865
12866   if (src_set == 0)
12867     {
12868       errmsg ("tunnel src address not specified");
12869       return -99;
12870     }
12871   if (dst_set == 0)
12872     {
12873       errmsg ("tunnel dst address not specified");
12874       return -99;
12875     }
12876
12877   if (grp_set && !ip46_address_is_multicast (&dst))
12878     {
12879       errmsg ("tunnel group address not multicast");
12880       return -99;
12881     }
12882   if (grp_set && mcast_sw_if_index == ~0)
12883     {
12884       errmsg ("tunnel nonexistent multicast device");
12885       return -99;
12886     }
12887   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12888     {
12889       errmsg ("tunnel dst address must be unicast");
12890       return -99;
12891     }
12892
12893
12894   if (ipv4_set && ipv6_set)
12895     {
12896       errmsg ("both IPv4 and IPv6 addresses specified");
12897       return -99;
12898     }
12899
12900   if ((vni == 0) || (vni >> 24))
12901     {
12902       errmsg ("vni not specified or out of range");
12903       return -99;
12904     }
12905
12906   M (GENEVE_ADD_DEL_TUNNEL, mp);
12907
12908   if (ipv6_set)
12909     {
12910       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12911       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12912     }
12913   else
12914     {
12915       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12916       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12917     }
12918   mp->encap_vrf_id = ntohl (encap_vrf_id);
12919   mp->decap_next_index = ntohl (decap_next_index);
12920   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12921   mp->vni = ntohl (vni);
12922   mp->is_add = is_add;
12923   mp->is_ipv6 = ipv6_set;
12924
12925   S (mp);
12926   W (ret);
12927   return ret;
12928 }
12929
12930 static void vl_api_geneve_tunnel_details_t_handler
12931   (vl_api_geneve_tunnel_details_t * mp)
12932 {
12933   vat_main_t *vam = &vat_main;
12934   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12935   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12936
12937   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12938          ntohl (mp->sw_if_index),
12939          format_ip46_address, &src, IP46_TYPE_ANY,
12940          format_ip46_address, &dst, IP46_TYPE_ANY,
12941          ntohl (mp->encap_vrf_id),
12942          ntohl (mp->decap_next_index), ntohl (mp->vni),
12943          ntohl (mp->mcast_sw_if_index));
12944 }
12945
12946 static void vl_api_geneve_tunnel_details_t_handler_json
12947   (vl_api_geneve_tunnel_details_t * mp)
12948 {
12949   vat_main_t *vam = &vat_main;
12950   vat_json_node_t *node = NULL;
12951
12952   if (VAT_JSON_ARRAY != vam->json_tree.type)
12953     {
12954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12955       vat_json_init_array (&vam->json_tree);
12956     }
12957   node = vat_json_array_add (&vam->json_tree);
12958
12959   vat_json_init_object (node);
12960   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12961   if (mp->is_ipv6)
12962     {
12963       struct in6_addr ip6;
12964
12965       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12966       vat_json_object_add_ip6 (node, "src_address", ip6);
12967       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12968       vat_json_object_add_ip6 (node, "dst_address", ip6);
12969     }
12970   else
12971     {
12972       struct in_addr ip4;
12973
12974       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12975       vat_json_object_add_ip4 (node, "src_address", ip4);
12976       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12977       vat_json_object_add_ip4 (node, "dst_address", ip4);
12978     }
12979   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12980   vat_json_object_add_uint (node, "decap_next_index",
12981                             ntohl (mp->decap_next_index));
12982   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12983   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12984   vat_json_object_add_uint (node, "mcast_sw_if_index",
12985                             ntohl (mp->mcast_sw_if_index));
12986 }
12987
12988 static int
12989 api_geneve_tunnel_dump (vat_main_t * vam)
12990 {
12991   unformat_input_t *i = vam->input;
12992   vl_api_geneve_tunnel_dump_t *mp;
12993   vl_api_control_ping_t *mp_ping;
12994   u32 sw_if_index;
12995   u8 sw_if_index_set = 0;
12996   int ret;
12997
12998   /* Parse args required to build the message */
12999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13000     {
13001       if (unformat (i, "sw_if_index %d", &sw_if_index))
13002         sw_if_index_set = 1;
13003       else
13004         break;
13005     }
13006
13007   if (sw_if_index_set == 0)
13008     {
13009       sw_if_index = ~0;
13010     }
13011
13012   if (!vam->json_output)
13013     {
13014       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13015              "sw_if_index", "local_address", "remote_address",
13016              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13017     }
13018
13019   /* Get list of geneve-tunnel interfaces */
13020   M (GENEVE_TUNNEL_DUMP, mp);
13021
13022   mp->sw_if_index = htonl (sw_if_index);
13023
13024   S (mp);
13025
13026   /* Use a control ping for synchronization */
13027   M (CONTROL_PING, mp_ping);
13028   S (mp_ping);
13029
13030   W (ret);
13031   return ret;
13032 }
13033
13034 static int
13035 api_gre_add_del_tunnel (vat_main_t * vam)
13036 {
13037   unformat_input_t *line_input = vam->input;
13038   vl_api_gre_add_del_tunnel_t *mp;
13039   ip4_address_t src4, dst4;
13040   ip6_address_t src6, dst6;
13041   u8 is_add = 1;
13042   u8 ipv4_set = 0;
13043   u8 ipv6_set = 0;
13044   u8 teb = 0;
13045   u8 src_set = 0;
13046   u8 dst_set = 0;
13047   u32 outer_fib_id = 0;
13048   int ret;
13049
13050   memset (&src4, 0, sizeof src4);
13051   memset (&dst4, 0, sizeof dst4);
13052   memset (&src6, 0, sizeof src6);
13053   memset (&dst6, 0, sizeof dst6);
13054
13055   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (line_input, "del"))
13058         is_add = 0;
13059       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13060         {
13061           src_set = 1;
13062           ipv4_set = 1;
13063         }
13064       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13065         {
13066           dst_set = 1;
13067           ipv4_set = 1;
13068         }
13069       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13070         {
13071           src_set = 1;
13072           ipv6_set = 1;
13073         }
13074       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13075         {
13076           dst_set = 1;
13077           ipv6_set = 1;
13078         }
13079       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13080         ;
13081       else if (unformat (line_input, "teb"))
13082         teb = 1;
13083       else
13084         {
13085           errmsg ("parse error '%U'", format_unformat_error, line_input);
13086           return -99;
13087         }
13088     }
13089
13090   if (src_set == 0)
13091     {
13092       errmsg ("tunnel src address not specified");
13093       return -99;
13094     }
13095   if (dst_set == 0)
13096     {
13097       errmsg ("tunnel dst address not specified");
13098       return -99;
13099     }
13100   if (ipv4_set && ipv6_set)
13101     {
13102       errmsg ("both IPv4 and IPv6 addresses specified");
13103       return -99;
13104     }
13105
13106
13107   M (GRE_ADD_DEL_TUNNEL, mp);
13108
13109   if (ipv4_set)
13110     {
13111       clib_memcpy (&mp->src_address, &src4, 4);
13112       clib_memcpy (&mp->dst_address, &dst4, 4);
13113     }
13114   else
13115     {
13116       clib_memcpy (&mp->src_address, &src6, 16);
13117       clib_memcpy (&mp->dst_address, &dst6, 16);
13118     }
13119   mp->outer_fib_id = ntohl (outer_fib_id);
13120   mp->is_add = is_add;
13121   mp->teb = teb;
13122   mp->is_ipv6 = ipv6_set;
13123
13124   S (mp);
13125   W (ret);
13126   return ret;
13127 }
13128
13129 static void vl_api_gre_tunnel_details_t_handler
13130   (vl_api_gre_tunnel_details_t * mp)
13131 {
13132   vat_main_t *vam = &vat_main;
13133   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13134   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13135
13136   print (vam->ofp, "%11d%24U%24U%6d%14d",
13137          ntohl (mp->sw_if_index),
13138          format_ip46_address, &src, IP46_TYPE_ANY,
13139          format_ip46_address, &dst, IP46_TYPE_ANY,
13140          mp->teb, ntohl (mp->outer_fib_id));
13141 }
13142
13143 static void vl_api_gre_tunnel_details_t_handler_json
13144   (vl_api_gre_tunnel_details_t * mp)
13145 {
13146   vat_main_t *vam = &vat_main;
13147   vat_json_node_t *node = NULL;
13148   struct in_addr ip4;
13149   struct in6_addr ip6;
13150
13151   if (VAT_JSON_ARRAY != vam->json_tree.type)
13152     {
13153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13154       vat_json_init_array (&vam->json_tree);
13155     }
13156   node = vat_json_array_add (&vam->json_tree);
13157
13158   vat_json_init_object (node);
13159   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13160   if (!mp->is_ipv6)
13161     {
13162       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13163       vat_json_object_add_ip4 (node, "src_address", ip4);
13164       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13165       vat_json_object_add_ip4 (node, "dst_address", ip4);
13166     }
13167   else
13168     {
13169       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13170       vat_json_object_add_ip6 (node, "src_address", ip6);
13171       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13172       vat_json_object_add_ip6 (node, "dst_address", ip6);
13173     }
13174   vat_json_object_add_uint (node, "teb", mp->teb);
13175   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13176   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13177 }
13178
13179 static int
13180 api_gre_tunnel_dump (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_gre_tunnel_dump_t *mp;
13184   vl_api_control_ping_t *mp_ping;
13185   u32 sw_if_index;
13186   u8 sw_if_index_set = 0;
13187   int ret;
13188
13189   /* Parse args required to build the message */
13190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191     {
13192       if (unformat (i, "sw_if_index %d", &sw_if_index))
13193         sw_if_index_set = 1;
13194       else
13195         break;
13196     }
13197
13198   if (sw_if_index_set == 0)
13199     {
13200       sw_if_index = ~0;
13201     }
13202
13203   if (!vam->json_output)
13204     {
13205       print (vam->ofp, "%11s%24s%24s%6s%14s",
13206              "sw_if_index", "src_address", "dst_address", "teb",
13207              "outer_fib_id");
13208     }
13209
13210   /* Get list of gre-tunnel interfaces */
13211   M (GRE_TUNNEL_DUMP, mp);
13212
13213   mp->sw_if_index = htonl (sw_if_index);
13214
13215   S (mp);
13216
13217   /* Use a control ping for synchronization */
13218   MPING (CONTROL_PING, mp_ping);
13219   S (mp_ping);
13220
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static int
13226 api_l2_fib_clear_table (vat_main_t * vam)
13227 {
13228 //  unformat_input_t * i = vam->input;
13229   vl_api_l2_fib_clear_table_t *mp;
13230   int ret;
13231
13232   M (L2_FIB_CLEAR_TABLE, mp);
13233
13234   S (mp);
13235   W (ret);
13236   return ret;
13237 }
13238
13239 static int
13240 api_l2_interface_efp_filter (vat_main_t * vam)
13241 {
13242   unformat_input_t *i = vam->input;
13243   vl_api_l2_interface_efp_filter_t *mp;
13244   u32 sw_if_index;
13245   u8 enable = 1;
13246   u8 sw_if_index_set = 0;
13247   int ret;
13248
13249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13250     {
13251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13252         sw_if_index_set = 1;
13253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13254         sw_if_index_set = 1;
13255       else if (unformat (i, "enable"))
13256         enable = 1;
13257       else if (unformat (i, "disable"))
13258         enable = 0;
13259       else
13260         {
13261           clib_warning ("parse error '%U'", format_unformat_error, i);
13262           return -99;
13263         }
13264     }
13265
13266   if (sw_if_index_set == 0)
13267     {
13268       errmsg ("missing sw_if_index");
13269       return -99;
13270     }
13271
13272   M (L2_INTERFACE_EFP_FILTER, mp);
13273
13274   mp->sw_if_index = ntohl (sw_if_index);
13275   mp->enable_disable = enable;
13276
13277   S (mp);
13278   W (ret);
13279   return ret;
13280 }
13281
13282 #define foreach_vtr_op                          \
13283 _("disable",  L2_VTR_DISABLED)                  \
13284 _("push-1",  L2_VTR_PUSH_1)                     \
13285 _("push-2",  L2_VTR_PUSH_2)                     \
13286 _("pop-1",  L2_VTR_POP_1)                       \
13287 _("pop-2",  L2_VTR_POP_2)                       \
13288 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13289 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13290 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13291 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13292
13293 static int
13294 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13295 {
13296   unformat_input_t *i = vam->input;
13297   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13298   u32 sw_if_index;
13299   u8 sw_if_index_set = 0;
13300   u8 vtr_op_set = 0;
13301   u32 vtr_op = 0;
13302   u32 push_dot1q = 1;
13303   u32 tag1 = ~0;
13304   u32 tag2 = ~0;
13305   int ret;
13306
13307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13308     {
13309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13310         sw_if_index_set = 1;
13311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13312         sw_if_index_set = 1;
13313       else if (unformat (i, "vtr_op %d", &vtr_op))
13314         vtr_op_set = 1;
13315 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13316       foreach_vtr_op
13317 #undef _
13318         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13319         ;
13320       else if (unformat (i, "tag1 %d", &tag1))
13321         ;
13322       else if (unformat (i, "tag2 %d", &tag2))
13323         ;
13324       else
13325         {
13326           clib_warning ("parse error '%U'", format_unformat_error, i);
13327           return -99;
13328         }
13329     }
13330
13331   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13332     {
13333       errmsg ("missing vtr operation or sw_if_index");
13334       return -99;
13335     }
13336
13337   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13338   mp->sw_if_index = ntohl (sw_if_index);
13339   mp->vtr_op = ntohl (vtr_op);
13340   mp->push_dot1q = ntohl (push_dot1q);
13341   mp->tag1 = ntohl (tag1);
13342   mp->tag2 = ntohl (tag2);
13343
13344   S (mp);
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_create_vhost_user_if (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_create_vhost_user_if_t *mp;
13354   u8 *file_name;
13355   u8 is_server = 0;
13356   u8 file_name_set = 0;
13357   u32 custom_dev_instance = ~0;
13358   u8 hwaddr[6];
13359   u8 use_custom_mac = 0;
13360   u8 *tag = 0;
13361   int ret;
13362
13363   /* Shut up coverity */
13364   memset (hwaddr, 0, sizeof (hwaddr));
13365
13366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13367     {
13368       if (unformat (i, "socket %s", &file_name))
13369         {
13370           file_name_set = 1;
13371         }
13372       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13373         ;
13374       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13375         use_custom_mac = 1;
13376       else if (unformat (i, "server"))
13377         is_server = 1;
13378       else if (unformat (i, "tag %s", &tag))
13379         ;
13380       else
13381         break;
13382     }
13383
13384   if (file_name_set == 0)
13385     {
13386       errmsg ("missing socket file name");
13387       return -99;
13388     }
13389
13390   if (vec_len (file_name) > 255)
13391     {
13392       errmsg ("socket file name too long");
13393       return -99;
13394     }
13395   vec_add1 (file_name, 0);
13396
13397   M (CREATE_VHOST_USER_IF, mp);
13398
13399   mp->is_server = is_server;
13400   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13401   vec_free (file_name);
13402   if (custom_dev_instance != ~0)
13403     {
13404       mp->renumber = 1;
13405       mp->custom_dev_instance = ntohl (custom_dev_instance);
13406     }
13407   mp->use_custom_mac = use_custom_mac;
13408   clib_memcpy (mp->mac_address, hwaddr, 6);
13409   if (tag)
13410     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13411   vec_free (tag);
13412
13413   S (mp);
13414   W (ret);
13415   return ret;
13416 }
13417
13418 static int
13419 api_modify_vhost_user_if (vat_main_t * vam)
13420 {
13421   unformat_input_t *i = vam->input;
13422   vl_api_modify_vhost_user_if_t *mp;
13423   u8 *file_name;
13424   u8 is_server = 0;
13425   u8 file_name_set = 0;
13426   u32 custom_dev_instance = ~0;
13427   u8 sw_if_index_set = 0;
13428   u32 sw_if_index = (u32) ~ 0;
13429   int ret;
13430
13431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13432     {
13433       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13434         sw_if_index_set = 1;
13435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13436         sw_if_index_set = 1;
13437       else if (unformat (i, "socket %s", &file_name))
13438         {
13439           file_name_set = 1;
13440         }
13441       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13442         ;
13443       else if (unformat (i, "server"))
13444         is_server = 1;
13445       else
13446         break;
13447     }
13448
13449   if (sw_if_index_set == 0)
13450     {
13451       errmsg ("missing sw_if_index or interface name");
13452       return -99;
13453     }
13454
13455   if (file_name_set == 0)
13456     {
13457       errmsg ("missing socket file name");
13458       return -99;
13459     }
13460
13461   if (vec_len (file_name) > 255)
13462     {
13463       errmsg ("socket file name too long");
13464       return -99;
13465     }
13466   vec_add1 (file_name, 0);
13467
13468   M (MODIFY_VHOST_USER_IF, mp);
13469
13470   mp->sw_if_index = ntohl (sw_if_index);
13471   mp->is_server = is_server;
13472   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13473   vec_free (file_name);
13474   if (custom_dev_instance != ~0)
13475     {
13476       mp->renumber = 1;
13477       mp->custom_dev_instance = ntohl (custom_dev_instance);
13478     }
13479
13480   S (mp);
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_delete_vhost_user_if (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_delete_vhost_user_if_t *mp;
13490   u32 sw_if_index = ~0;
13491   u8 sw_if_index_set = 0;
13492   int ret;
13493
13494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13495     {
13496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13497         sw_if_index_set = 1;
13498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13499         sw_if_index_set = 1;
13500       else
13501         break;
13502     }
13503
13504   if (sw_if_index_set == 0)
13505     {
13506       errmsg ("missing sw_if_index or interface name");
13507       return -99;
13508     }
13509
13510
13511   M (DELETE_VHOST_USER_IF, mp);
13512
13513   mp->sw_if_index = ntohl (sw_if_index);
13514
13515   S (mp);
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static void vl_api_sw_interface_vhost_user_details_t_handler
13521   (vl_api_sw_interface_vhost_user_details_t * mp)
13522 {
13523   vat_main_t *vam = &vat_main;
13524
13525   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13526          (char *) mp->interface_name,
13527          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13528          clib_net_to_host_u64 (mp->features), mp->is_server,
13529          ntohl (mp->num_regions), (char *) mp->sock_filename);
13530   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13531 }
13532
13533 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13534   (vl_api_sw_interface_vhost_user_details_t * mp)
13535 {
13536   vat_main_t *vam = &vat_main;
13537   vat_json_node_t *node = NULL;
13538
13539   if (VAT_JSON_ARRAY != vam->json_tree.type)
13540     {
13541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13542       vat_json_init_array (&vam->json_tree);
13543     }
13544   node = vat_json_array_add (&vam->json_tree);
13545
13546   vat_json_init_object (node);
13547   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13548   vat_json_object_add_string_copy (node, "interface_name",
13549                                    mp->interface_name);
13550   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13551                             ntohl (mp->virtio_net_hdr_sz));
13552   vat_json_object_add_uint (node, "features",
13553                             clib_net_to_host_u64 (mp->features));
13554   vat_json_object_add_uint (node, "is_server", mp->is_server);
13555   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13556   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13557   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13558 }
13559
13560 static int
13561 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13562 {
13563   vl_api_sw_interface_vhost_user_dump_t *mp;
13564   vl_api_control_ping_t *mp_ping;
13565   int ret;
13566   print (vam->ofp,
13567          "Interface name            idx hdr_sz features server regions filename");
13568
13569   /* Get list of vhost-user interfaces */
13570   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13571   S (mp);
13572
13573   /* Use a control ping for synchronization */
13574   MPING (CONTROL_PING, mp_ping);
13575   S (mp_ping);
13576
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_show_version (vat_main_t * vam)
13583 {
13584   vl_api_show_version_t *mp;
13585   int ret;
13586
13587   M (SHOW_VERSION, mp);
13588
13589   S (mp);
13590   W (ret);
13591   return ret;
13592 }
13593
13594
13595 static int
13596 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13597 {
13598   unformat_input_t *line_input = vam->input;
13599   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13600   ip4_address_t local4, remote4;
13601   ip6_address_t local6, remote6;
13602   u8 is_add = 1;
13603   u8 ipv4_set = 0, ipv6_set = 0;
13604   u8 local_set = 0;
13605   u8 remote_set = 0;
13606   u8 grp_set = 0;
13607   u32 mcast_sw_if_index = ~0;
13608   u32 encap_vrf_id = 0;
13609   u32 decap_vrf_id = 0;
13610   u8 protocol = ~0;
13611   u32 vni;
13612   u8 vni_set = 0;
13613   int ret;
13614
13615   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13616   memset (&local4, 0, sizeof local4);
13617   memset (&remote4, 0, sizeof remote4);
13618   memset (&local6, 0, sizeof local6);
13619   memset (&remote6, 0, sizeof remote6);
13620
13621   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (line_input, "del"))
13624         is_add = 0;
13625       else if (unformat (line_input, "local %U",
13626                          unformat_ip4_address, &local4))
13627         {
13628           local_set = 1;
13629           ipv4_set = 1;
13630         }
13631       else if (unformat (line_input, "remote %U",
13632                          unformat_ip4_address, &remote4))
13633         {
13634           remote_set = 1;
13635           ipv4_set = 1;
13636         }
13637       else if (unformat (line_input, "local %U",
13638                          unformat_ip6_address, &local6))
13639         {
13640           local_set = 1;
13641           ipv6_set = 1;
13642         }
13643       else if (unformat (line_input, "remote %U",
13644                          unformat_ip6_address, &remote6))
13645         {
13646           remote_set = 1;
13647           ipv6_set = 1;
13648         }
13649       else if (unformat (line_input, "group %U %U",
13650                          unformat_ip4_address, &remote4,
13651                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13652         {
13653           grp_set = remote_set = 1;
13654           ipv4_set = 1;
13655         }
13656       else if (unformat (line_input, "group %U",
13657                          unformat_ip4_address, &remote4))
13658         {
13659           grp_set = remote_set = 1;
13660           ipv4_set = 1;
13661         }
13662       else if (unformat (line_input, "group %U %U",
13663                          unformat_ip6_address, &remote6,
13664                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13665         {
13666           grp_set = remote_set = 1;
13667           ipv6_set = 1;
13668         }
13669       else if (unformat (line_input, "group %U",
13670                          unformat_ip6_address, &remote6))
13671         {
13672           grp_set = remote_set = 1;
13673           ipv6_set = 1;
13674         }
13675       else
13676         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13677         ;
13678       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13679         ;
13680       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13681         ;
13682       else if (unformat (line_input, "vni %d", &vni))
13683         vni_set = 1;
13684       else if (unformat (line_input, "next-ip4"))
13685         protocol = 1;
13686       else if (unformat (line_input, "next-ip6"))
13687         protocol = 2;
13688       else if (unformat (line_input, "next-ethernet"))
13689         protocol = 3;
13690       else if (unformat (line_input, "next-nsh"))
13691         protocol = 4;
13692       else
13693         {
13694           errmsg ("parse error '%U'", format_unformat_error, line_input);
13695           return -99;
13696         }
13697     }
13698
13699   if (local_set == 0)
13700     {
13701       errmsg ("tunnel local address not specified");
13702       return -99;
13703     }
13704   if (remote_set == 0)
13705     {
13706       errmsg ("tunnel remote address not specified");
13707       return -99;
13708     }
13709   if (grp_set && mcast_sw_if_index == ~0)
13710     {
13711       errmsg ("tunnel nonexistent multicast device");
13712       return -99;
13713     }
13714   if (ipv4_set && ipv6_set)
13715     {
13716       errmsg ("both IPv4 and IPv6 addresses specified");
13717       return -99;
13718     }
13719
13720   if (vni_set == 0)
13721     {
13722       errmsg ("vni not specified");
13723       return -99;
13724     }
13725
13726   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13727
13728
13729   if (ipv6_set)
13730     {
13731       clib_memcpy (&mp->local, &local6, sizeof (local6));
13732       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13733     }
13734   else
13735     {
13736       clib_memcpy (&mp->local, &local4, sizeof (local4));
13737       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13738     }
13739
13740   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13741   mp->encap_vrf_id = ntohl (encap_vrf_id);
13742   mp->decap_vrf_id = ntohl (decap_vrf_id);
13743   mp->protocol = protocol;
13744   mp->vni = ntohl (vni);
13745   mp->is_add = is_add;
13746   mp->is_ipv6 = ipv6_set;
13747
13748   S (mp);
13749   W (ret);
13750   return ret;
13751 }
13752
13753 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13754   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13755 {
13756   vat_main_t *vam = &vat_main;
13757   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13758   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13759
13760   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13761          ntohl (mp->sw_if_index),
13762          format_ip46_address, &local, IP46_TYPE_ANY,
13763          format_ip46_address, &remote, IP46_TYPE_ANY,
13764          ntohl (mp->vni), mp->protocol,
13765          ntohl (mp->mcast_sw_if_index),
13766          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13767 }
13768
13769
13770 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13771   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13772 {
13773   vat_main_t *vam = &vat_main;
13774   vat_json_node_t *node = NULL;
13775   struct in_addr ip4;
13776   struct in6_addr ip6;
13777
13778   if (VAT_JSON_ARRAY != vam->json_tree.type)
13779     {
13780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13781       vat_json_init_array (&vam->json_tree);
13782     }
13783   node = vat_json_array_add (&vam->json_tree);
13784
13785   vat_json_init_object (node);
13786   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13787   if (mp->is_ipv6)
13788     {
13789       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13790       vat_json_object_add_ip6 (node, "local", ip6);
13791       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13792       vat_json_object_add_ip6 (node, "remote", ip6);
13793     }
13794   else
13795     {
13796       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13797       vat_json_object_add_ip4 (node, "local", ip4);
13798       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13799       vat_json_object_add_ip4 (node, "remote", ip4);
13800     }
13801   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13802   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13803   vat_json_object_add_uint (node, "mcast_sw_if_index",
13804                             ntohl (mp->mcast_sw_if_index));
13805   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13806   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13807   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13808 }
13809
13810 static int
13811 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13812 {
13813   unformat_input_t *i = vam->input;
13814   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13815   vl_api_control_ping_t *mp_ping;
13816   u32 sw_if_index;
13817   u8 sw_if_index_set = 0;
13818   int ret;
13819
13820   /* Parse args required to build the message */
13821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13822     {
13823       if (unformat (i, "sw_if_index %d", &sw_if_index))
13824         sw_if_index_set = 1;
13825       else
13826         break;
13827     }
13828
13829   if (sw_if_index_set == 0)
13830     {
13831       sw_if_index = ~0;
13832     }
13833
13834   if (!vam->json_output)
13835     {
13836       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13837              "sw_if_index", "local", "remote", "vni",
13838              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13839     }
13840
13841   /* Get list of vxlan-tunnel interfaces */
13842   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13843
13844   mp->sw_if_index = htonl (sw_if_index);
13845
13846   S (mp);
13847
13848   /* Use a control ping for synchronization */
13849   MPING (CONTROL_PING, mp_ping);
13850   S (mp_ping);
13851
13852   W (ret);
13853   return ret;
13854 }
13855
13856 static void vl_api_l2_fib_table_details_t_handler
13857   (vl_api_l2_fib_table_details_t * mp)
13858 {
13859   vat_main_t *vam = &vat_main;
13860
13861   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13862          "       %d       %d     %d",
13863          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13864          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13865          mp->bvi_mac);
13866 }
13867
13868 static void vl_api_l2_fib_table_details_t_handler_json
13869   (vl_api_l2_fib_table_details_t * mp)
13870 {
13871   vat_main_t *vam = &vat_main;
13872   vat_json_node_t *node = NULL;
13873
13874   if (VAT_JSON_ARRAY != vam->json_tree.type)
13875     {
13876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13877       vat_json_init_array (&vam->json_tree);
13878     }
13879   node = vat_json_array_add (&vam->json_tree);
13880
13881   vat_json_init_object (node);
13882   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13883   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13885   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13886   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13887   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13888 }
13889
13890 static int
13891 api_l2_fib_table_dump (vat_main_t * vam)
13892 {
13893   unformat_input_t *i = vam->input;
13894   vl_api_l2_fib_table_dump_t *mp;
13895   vl_api_control_ping_t *mp_ping;
13896   u32 bd_id;
13897   u8 bd_id_set = 0;
13898   int ret;
13899
13900   /* Parse args required to build the message */
13901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13902     {
13903       if (unformat (i, "bd_id %d", &bd_id))
13904         bd_id_set = 1;
13905       else
13906         break;
13907     }
13908
13909   if (bd_id_set == 0)
13910     {
13911       errmsg ("missing bridge domain");
13912       return -99;
13913     }
13914
13915   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13916
13917   /* Get list of l2 fib entries */
13918   M (L2_FIB_TABLE_DUMP, mp);
13919
13920   mp->bd_id = ntohl (bd_id);
13921   S (mp);
13922
13923   /* Use a control ping for synchronization */
13924   MPING (CONTROL_PING, mp_ping);
13925   S (mp_ping);
13926
13927   W (ret);
13928   return ret;
13929 }
13930
13931
13932 static int
13933 api_interface_name_renumber (vat_main_t * vam)
13934 {
13935   unformat_input_t *line_input = vam->input;
13936   vl_api_interface_name_renumber_t *mp;
13937   u32 sw_if_index = ~0;
13938   u32 new_show_dev_instance = ~0;
13939   int ret;
13940
13941   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13942     {
13943       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13944                     &sw_if_index))
13945         ;
13946       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13947         ;
13948       else if (unformat (line_input, "new_show_dev_instance %d",
13949                          &new_show_dev_instance))
13950         ;
13951       else
13952         break;
13953     }
13954
13955   if (sw_if_index == ~0)
13956     {
13957       errmsg ("missing interface name or sw_if_index");
13958       return -99;
13959     }
13960
13961   if (new_show_dev_instance == ~0)
13962     {
13963       errmsg ("missing new_show_dev_instance");
13964       return -99;
13965     }
13966
13967   M (INTERFACE_NAME_RENUMBER, mp);
13968
13969   mp->sw_if_index = ntohl (sw_if_index);
13970   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13971
13972   S (mp);
13973   W (ret);
13974   return ret;
13975 }
13976
13977 static int
13978 api_want_ip4_arp_events (vat_main_t * vam)
13979 {
13980   unformat_input_t *line_input = vam->input;
13981   vl_api_want_ip4_arp_events_t *mp;
13982   ip4_address_t address;
13983   int address_set = 0;
13984   u32 enable_disable = 1;
13985   int ret;
13986
13987   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13990         address_set = 1;
13991       else if (unformat (line_input, "del"))
13992         enable_disable = 0;
13993       else
13994         break;
13995     }
13996
13997   if (address_set == 0)
13998     {
13999       errmsg ("missing addresses");
14000       return -99;
14001     }
14002
14003   M (WANT_IP4_ARP_EVENTS, mp);
14004   mp->enable_disable = enable_disable;
14005   mp->pid = htonl (getpid ());
14006   mp->address = address.as_u32;
14007
14008   S (mp);
14009   W (ret);
14010   return ret;
14011 }
14012
14013 static int
14014 api_want_ip6_nd_events (vat_main_t * vam)
14015 {
14016   unformat_input_t *line_input = vam->input;
14017   vl_api_want_ip6_nd_events_t *mp;
14018   ip6_address_t address;
14019   int address_set = 0;
14020   u32 enable_disable = 1;
14021   int ret;
14022
14023   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14024     {
14025       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14026         address_set = 1;
14027       else if (unformat (line_input, "del"))
14028         enable_disable = 0;
14029       else
14030         break;
14031     }
14032
14033   if (address_set == 0)
14034     {
14035       errmsg ("missing addresses");
14036       return -99;
14037     }
14038
14039   M (WANT_IP6_ND_EVENTS, mp);
14040   mp->enable_disable = enable_disable;
14041   mp->pid = htonl (getpid ());
14042   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14043
14044   S (mp);
14045   W (ret);
14046   return ret;
14047 }
14048
14049 static int
14050 api_want_l2_macs_events (vat_main_t * vam)
14051 {
14052   unformat_input_t *line_input = vam->input;
14053   vl_api_want_l2_macs_events_t *mp;
14054   u8 enable_disable = 1;
14055   u32 scan_delay = 0;
14056   u32 max_macs_in_event = 0;
14057   u32 learn_limit = 0;
14058   int ret;
14059
14060   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14061     {
14062       if (unformat (line_input, "learn-limit %d", &learn_limit))
14063         ;
14064       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14065         ;
14066       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14067         ;
14068       else if (unformat (line_input, "disable"))
14069         enable_disable = 0;
14070       else
14071         break;
14072     }
14073
14074   M (WANT_L2_MACS_EVENTS, mp);
14075   mp->enable_disable = enable_disable;
14076   mp->pid = htonl (getpid ());
14077   mp->learn_limit = htonl (learn_limit);
14078   mp->scan_delay = (u8) scan_delay;
14079   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14080   S (mp);
14081   W (ret);
14082   return ret;
14083 }
14084
14085 static int
14086 api_input_acl_set_interface (vat_main_t * vam)
14087 {
14088   unformat_input_t *i = vam->input;
14089   vl_api_input_acl_set_interface_t *mp;
14090   u32 sw_if_index;
14091   int sw_if_index_set;
14092   u32 ip4_table_index = ~0;
14093   u32 ip6_table_index = ~0;
14094   u32 l2_table_index = ~0;
14095   u8 is_add = 1;
14096   int ret;
14097
14098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14099     {
14100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14101         sw_if_index_set = 1;
14102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14103         sw_if_index_set = 1;
14104       else if (unformat (i, "del"))
14105         is_add = 0;
14106       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14107         ;
14108       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14109         ;
14110       else if (unformat (i, "l2-table %d", &l2_table_index))
14111         ;
14112       else
14113         {
14114           clib_warning ("parse error '%U'", format_unformat_error, i);
14115           return -99;
14116         }
14117     }
14118
14119   if (sw_if_index_set == 0)
14120     {
14121       errmsg ("missing interface name or sw_if_index");
14122       return -99;
14123     }
14124
14125   M (INPUT_ACL_SET_INTERFACE, mp);
14126
14127   mp->sw_if_index = ntohl (sw_if_index);
14128   mp->ip4_table_index = ntohl (ip4_table_index);
14129   mp->ip6_table_index = ntohl (ip6_table_index);
14130   mp->l2_table_index = ntohl (l2_table_index);
14131   mp->is_add = is_add;
14132
14133   S (mp);
14134   W (ret);
14135   return ret;
14136 }
14137
14138 static int
14139 api_ip_address_dump (vat_main_t * vam)
14140 {
14141   unformat_input_t *i = vam->input;
14142   vl_api_ip_address_dump_t *mp;
14143   vl_api_control_ping_t *mp_ping;
14144   u32 sw_if_index = ~0;
14145   u8 sw_if_index_set = 0;
14146   u8 ipv4_set = 0;
14147   u8 ipv6_set = 0;
14148   int ret;
14149
14150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14151     {
14152       if (unformat (i, "sw_if_index %d", &sw_if_index))
14153         sw_if_index_set = 1;
14154       else
14155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14156         sw_if_index_set = 1;
14157       else if (unformat (i, "ipv4"))
14158         ipv4_set = 1;
14159       else if (unformat (i, "ipv6"))
14160         ipv6_set = 1;
14161       else
14162         break;
14163     }
14164
14165   if (ipv4_set && ipv6_set)
14166     {
14167       errmsg ("ipv4 and ipv6 flags cannot be both set");
14168       return -99;
14169     }
14170
14171   if ((!ipv4_set) && (!ipv6_set))
14172     {
14173       errmsg ("no ipv4 nor ipv6 flag set");
14174       return -99;
14175     }
14176
14177   if (sw_if_index_set == 0)
14178     {
14179       errmsg ("missing interface name or sw_if_index");
14180       return -99;
14181     }
14182
14183   vam->current_sw_if_index = sw_if_index;
14184   vam->is_ipv6 = ipv6_set;
14185
14186   M (IP_ADDRESS_DUMP, mp);
14187   mp->sw_if_index = ntohl (sw_if_index);
14188   mp->is_ipv6 = ipv6_set;
14189   S (mp);
14190
14191   /* Use a control ping for synchronization */
14192   MPING (CONTROL_PING, mp_ping);
14193   S (mp_ping);
14194
14195   W (ret);
14196   return ret;
14197 }
14198
14199 static int
14200 api_ip_dump (vat_main_t * vam)
14201 {
14202   vl_api_ip_dump_t *mp;
14203   vl_api_control_ping_t *mp_ping;
14204   unformat_input_t *in = vam->input;
14205   int ipv4_set = 0;
14206   int ipv6_set = 0;
14207   int is_ipv6;
14208   int i;
14209   int ret;
14210
14211   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (in, "ipv4"))
14214         ipv4_set = 1;
14215       else if (unformat (in, "ipv6"))
14216         ipv6_set = 1;
14217       else
14218         break;
14219     }
14220
14221   if (ipv4_set && ipv6_set)
14222     {
14223       errmsg ("ipv4 and ipv6 flags cannot be both set");
14224       return -99;
14225     }
14226
14227   if ((!ipv4_set) && (!ipv6_set))
14228     {
14229       errmsg ("no ipv4 nor ipv6 flag set");
14230       return -99;
14231     }
14232
14233   is_ipv6 = ipv6_set;
14234   vam->is_ipv6 = is_ipv6;
14235
14236   /* free old data */
14237   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14238     {
14239       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14240     }
14241   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14242
14243   M (IP_DUMP, mp);
14244   mp->is_ipv6 = ipv6_set;
14245   S (mp);
14246
14247   /* Use a control ping for synchronization */
14248   MPING (CONTROL_PING, mp_ping);
14249   S (mp_ping);
14250
14251   W (ret);
14252   return ret;
14253 }
14254
14255 static int
14256 api_ipsec_spd_add_del (vat_main_t * vam)
14257 {
14258   unformat_input_t *i = vam->input;
14259   vl_api_ipsec_spd_add_del_t *mp;
14260   u32 spd_id = ~0;
14261   u8 is_add = 1;
14262   int ret;
14263
14264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14265     {
14266       if (unformat (i, "spd_id %d", &spd_id))
14267         ;
14268       else if (unformat (i, "del"))
14269         is_add = 0;
14270       else
14271         {
14272           clib_warning ("parse error '%U'", format_unformat_error, i);
14273           return -99;
14274         }
14275     }
14276   if (spd_id == ~0)
14277     {
14278       errmsg ("spd_id must be set");
14279       return -99;
14280     }
14281
14282   M (IPSEC_SPD_ADD_DEL, mp);
14283
14284   mp->spd_id = ntohl (spd_id);
14285   mp->is_add = is_add;
14286
14287   S (mp);
14288   W (ret);
14289   return ret;
14290 }
14291
14292 static int
14293 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14294 {
14295   unformat_input_t *i = vam->input;
14296   vl_api_ipsec_interface_add_del_spd_t *mp;
14297   u32 sw_if_index;
14298   u8 sw_if_index_set = 0;
14299   u32 spd_id = (u32) ~ 0;
14300   u8 is_add = 1;
14301   int ret;
14302
14303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14304     {
14305       if (unformat (i, "del"))
14306         is_add = 0;
14307       else if (unformat (i, "spd_id %d", &spd_id))
14308         ;
14309       else
14310         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14311         sw_if_index_set = 1;
14312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14313         sw_if_index_set = 1;
14314       else
14315         {
14316           clib_warning ("parse error '%U'", format_unformat_error, i);
14317           return -99;
14318         }
14319
14320     }
14321
14322   if (spd_id == (u32) ~ 0)
14323     {
14324       errmsg ("spd_id must be set");
14325       return -99;
14326     }
14327
14328   if (sw_if_index_set == 0)
14329     {
14330       errmsg ("missing interface name or sw_if_index");
14331       return -99;
14332     }
14333
14334   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14335
14336   mp->spd_id = ntohl (spd_id);
14337   mp->sw_if_index = ntohl (sw_if_index);
14338   mp->is_add = is_add;
14339
14340   S (mp);
14341   W (ret);
14342   return ret;
14343 }
14344
14345 static int
14346 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14347 {
14348   unformat_input_t *i = vam->input;
14349   vl_api_ipsec_spd_add_del_entry_t *mp;
14350   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14351   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14352   i32 priority = 0;
14353   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14354   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14355   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14356   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14357   int ret;
14358
14359   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14360   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14361   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14362   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14363   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14364   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14365
14366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14367     {
14368       if (unformat (i, "del"))
14369         is_add = 0;
14370       if (unformat (i, "outbound"))
14371         is_outbound = 1;
14372       if (unformat (i, "inbound"))
14373         is_outbound = 0;
14374       else if (unformat (i, "spd_id %d", &spd_id))
14375         ;
14376       else if (unformat (i, "sa_id %d", &sa_id))
14377         ;
14378       else if (unformat (i, "priority %d", &priority))
14379         ;
14380       else if (unformat (i, "protocol %d", &protocol))
14381         ;
14382       else if (unformat (i, "lport_start %d", &lport_start))
14383         ;
14384       else if (unformat (i, "lport_stop %d", &lport_stop))
14385         ;
14386       else if (unformat (i, "rport_start %d", &rport_start))
14387         ;
14388       else if (unformat (i, "rport_stop %d", &rport_stop))
14389         ;
14390       else
14391         if (unformat
14392             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14393         {
14394           is_ipv6 = 0;
14395           is_ip_any = 0;
14396         }
14397       else
14398         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14399         {
14400           is_ipv6 = 0;
14401           is_ip_any = 0;
14402         }
14403       else
14404         if (unformat
14405             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14406         {
14407           is_ipv6 = 0;
14408           is_ip_any = 0;
14409         }
14410       else
14411         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14412         {
14413           is_ipv6 = 0;
14414           is_ip_any = 0;
14415         }
14416       else
14417         if (unformat
14418             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14419         {
14420           is_ipv6 = 1;
14421           is_ip_any = 0;
14422         }
14423       else
14424         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14425         {
14426           is_ipv6 = 1;
14427           is_ip_any = 0;
14428         }
14429       else
14430         if (unformat
14431             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14432         {
14433           is_ipv6 = 1;
14434           is_ip_any = 0;
14435         }
14436       else
14437         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14438         {
14439           is_ipv6 = 1;
14440           is_ip_any = 0;
14441         }
14442       else
14443         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14444         {
14445           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14446             {
14447               clib_warning ("unsupported action: 'resolve'");
14448               return -99;
14449             }
14450         }
14451       else
14452         {
14453           clib_warning ("parse error '%U'", format_unformat_error, i);
14454           return -99;
14455         }
14456
14457     }
14458
14459   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14460
14461   mp->spd_id = ntohl (spd_id);
14462   mp->priority = ntohl (priority);
14463   mp->is_outbound = is_outbound;
14464
14465   mp->is_ipv6 = is_ipv6;
14466   if (is_ipv6 || is_ip_any)
14467     {
14468       clib_memcpy (mp->remote_address_start, &raddr6_start,
14469                    sizeof (ip6_address_t));
14470       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14471                    sizeof (ip6_address_t));
14472       clib_memcpy (mp->local_address_start, &laddr6_start,
14473                    sizeof (ip6_address_t));
14474       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14475                    sizeof (ip6_address_t));
14476     }
14477   else
14478     {
14479       clib_memcpy (mp->remote_address_start, &raddr4_start,
14480                    sizeof (ip4_address_t));
14481       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14482                    sizeof (ip4_address_t));
14483       clib_memcpy (mp->local_address_start, &laddr4_start,
14484                    sizeof (ip4_address_t));
14485       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14486                    sizeof (ip4_address_t));
14487     }
14488   mp->protocol = (u8) protocol;
14489   mp->local_port_start = ntohs ((u16) lport_start);
14490   mp->local_port_stop = ntohs ((u16) lport_stop);
14491   mp->remote_port_start = ntohs ((u16) rport_start);
14492   mp->remote_port_stop = ntohs ((u16) rport_stop);
14493   mp->policy = (u8) policy;
14494   mp->sa_id = ntohl (sa_id);
14495   mp->is_add = is_add;
14496   mp->is_ip_any = is_ip_any;
14497   S (mp);
14498   W (ret);
14499   return ret;
14500 }
14501
14502 static int
14503 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14504 {
14505   unformat_input_t *i = vam->input;
14506   vl_api_ipsec_sad_add_del_entry_t *mp;
14507   u32 sad_id = 0, spi = 0;
14508   u8 *ck = 0, *ik = 0;
14509   u8 is_add = 1;
14510
14511   u8 protocol = IPSEC_PROTOCOL_AH;
14512   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14513   u32 crypto_alg = 0, integ_alg = 0;
14514   ip4_address_t tun_src4;
14515   ip4_address_t tun_dst4;
14516   ip6_address_t tun_src6;
14517   ip6_address_t tun_dst6;
14518   int ret;
14519
14520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (i, "del"))
14523         is_add = 0;
14524       else if (unformat (i, "sad_id %d", &sad_id))
14525         ;
14526       else if (unformat (i, "spi %d", &spi))
14527         ;
14528       else if (unformat (i, "esp"))
14529         protocol = IPSEC_PROTOCOL_ESP;
14530       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14531         {
14532           is_tunnel = 1;
14533           is_tunnel_ipv6 = 0;
14534         }
14535       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14536         {
14537           is_tunnel = 1;
14538           is_tunnel_ipv6 = 0;
14539         }
14540       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14541         {
14542           is_tunnel = 1;
14543           is_tunnel_ipv6 = 1;
14544         }
14545       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14546         {
14547           is_tunnel = 1;
14548           is_tunnel_ipv6 = 1;
14549         }
14550       else
14551         if (unformat
14552             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14553         {
14554           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14555               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14556             {
14557               clib_warning ("unsupported crypto-alg: '%U'",
14558                             format_ipsec_crypto_alg, crypto_alg);
14559               return -99;
14560             }
14561         }
14562       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14563         ;
14564       else
14565         if (unformat
14566             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14567         {
14568           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14569               integ_alg >= IPSEC_INTEG_N_ALG)
14570             {
14571               clib_warning ("unsupported integ-alg: '%U'",
14572                             format_ipsec_integ_alg, integ_alg);
14573               return -99;
14574             }
14575         }
14576       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14577         ;
14578       else
14579         {
14580           clib_warning ("parse error '%U'", format_unformat_error, i);
14581           return -99;
14582         }
14583
14584     }
14585
14586   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14587
14588   mp->sad_id = ntohl (sad_id);
14589   mp->is_add = is_add;
14590   mp->protocol = protocol;
14591   mp->spi = ntohl (spi);
14592   mp->is_tunnel = is_tunnel;
14593   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14594   mp->crypto_algorithm = crypto_alg;
14595   mp->integrity_algorithm = integ_alg;
14596   mp->crypto_key_length = vec_len (ck);
14597   mp->integrity_key_length = vec_len (ik);
14598
14599   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14600     mp->crypto_key_length = sizeof (mp->crypto_key);
14601
14602   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14603     mp->integrity_key_length = sizeof (mp->integrity_key);
14604
14605   if (ck)
14606     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14607   if (ik)
14608     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14609
14610   if (is_tunnel)
14611     {
14612       if (is_tunnel_ipv6)
14613         {
14614           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14615                        sizeof (ip6_address_t));
14616           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14617                        sizeof (ip6_address_t));
14618         }
14619       else
14620         {
14621           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14622                        sizeof (ip4_address_t));
14623           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14624                        sizeof (ip4_address_t));
14625         }
14626     }
14627
14628   S (mp);
14629   W (ret);
14630   return ret;
14631 }
14632
14633 static int
14634 api_ipsec_sa_set_key (vat_main_t * vam)
14635 {
14636   unformat_input_t *i = vam->input;
14637   vl_api_ipsec_sa_set_key_t *mp;
14638   u32 sa_id;
14639   u8 *ck = 0, *ik = 0;
14640   int ret;
14641
14642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14643     {
14644       if (unformat (i, "sa_id %d", &sa_id))
14645         ;
14646       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14647         ;
14648       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14649         ;
14650       else
14651         {
14652           clib_warning ("parse error '%U'", format_unformat_error, i);
14653           return -99;
14654         }
14655     }
14656
14657   M (IPSEC_SA_SET_KEY, mp);
14658
14659   mp->sa_id = ntohl (sa_id);
14660   mp->crypto_key_length = vec_len (ck);
14661   mp->integrity_key_length = vec_len (ik);
14662
14663   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14664     mp->crypto_key_length = sizeof (mp->crypto_key);
14665
14666   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14667     mp->integrity_key_length = sizeof (mp->integrity_key);
14668
14669   if (ck)
14670     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14671   if (ik)
14672     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14673
14674   S (mp);
14675   W (ret);
14676   return ret;
14677 }
14678
14679 static int
14680 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14681 {
14682   unformat_input_t *i = vam->input;
14683   vl_api_ipsec_tunnel_if_add_del_t *mp;
14684   u32 local_spi = 0, remote_spi = 0;
14685   u32 crypto_alg = 0, integ_alg = 0;
14686   u8 *lck = NULL, *rck = NULL;
14687   u8 *lik = NULL, *rik = NULL;
14688   ip4_address_t local_ip = { {0} };
14689   ip4_address_t remote_ip = { {0} };
14690   u8 is_add = 1;
14691   u8 esn = 0;
14692   u8 anti_replay = 0;
14693   int ret;
14694
14695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (i, "del"))
14698         is_add = 0;
14699       else if (unformat (i, "esn"))
14700         esn = 1;
14701       else if (unformat (i, "anti_replay"))
14702         anti_replay = 1;
14703       else if (unformat (i, "local_spi %d", &local_spi))
14704         ;
14705       else if (unformat (i, "remote_spi %d", &remote_spi))
14706         ;
14707       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14708         ;
14709       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14710         ;
14711       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14712         ;
14713       else
14714         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14715         ;
14716       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14717         ;
14718       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14719         ;
14720       else
14721         if (unformat
14722             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14723         {
14724           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14725               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14726             {
14727               errmsg ("unsupported crypto-alg: '%U'\n",
14728                       format_ipsec_crypto_alg, crypto_alg);
14729               return -99;
14730             }
14731         }
14732       else
14733         if (unformat
14734             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14735         {
14736           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14737               integ_alg >= IPSEC_INTEG_N_ALG)
14738             {
14739               errmsg ("unsupported integ-alg: '%U'\n",
14740                       format_ipsec_integ_alg, integ_alg);
14741               return -99;
14742             }
14743         }
14744       else
14745         {
14746           errmsg ("parse error '%U'\n", format_unformat_error, i);
14747           return -99;
14748         }
14749     }
14750
14751   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14752
14753   mp->is_add = is_add;
14754   mp->esn = esn;
14755   mp->anti_replay = anti_replay;
14756
14757   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14758   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14759
14760   mp->local_spi = htonl (local_spi);
14761   mp->remote_spi = htonl (remote_spi);
14762   mp->crypto_alg = (u8) crypto_alg;
14763
14764   mp->local_crypto_key_len = 0;
14765   if (lck)
14766     {
14767       mp->local_crypto_key_len = vec_len (lck);
14768       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14769         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14770       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14771     }
14772
14773   mp->remote_crypto_key_len = 0;
14774   if (rck)
14775     {
14776       mp->remote_crypto_key_len = vec_len (rck);
14777       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14778         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14779       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14780     }
14781
14782   mp->integ_alg = (u8) integ_alg;
14783
14784   mp->local_integ_key_len = 0;
14785   if (lik)
14786     {
14787       mp->local_integ_key_len = vec_len (lik);
14788       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14789         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14790       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14791     }
14792
14793   mp->remote_integ_key_len = 0;
14794   if (rik)
14795     {
14796       mp->remote_integ_key_len = vec_len (rik);
14797       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14798         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14799       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14800     }
14801
14802   S (mp);
14803   W (ret);
14804   return ret;
14805 }
14806
14807 static void
14808 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14809 {
14810   vat_main_t *vam = &vat_main;
14811
14812   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14813          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14814          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14815          "tunnel_src_addr %U tunnel_dst_addr %U "
14816          "salt %u seq_outbound %lu last_seq_inbound %lu "
14817          "replay_window %lu total_data_size %lu\n",
14818          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14819          mp->protocol,
14820          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14821          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14822          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14823          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14824          mp->tunnel_src_addr,
14825          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14826          mp->tunnel_dst_addr,
14827          ntohl (mp->salt),
14828          clib_net_to_host_u64 (mp->seq_outbound),
14829          clib_net_to_host_u64 (mp->last_seq_inbound),
14830          clib_net_to_host_u64 (mp->replay_window),
14831          clib_net_to_host_u64 (mp->total_data_size));
14832 }
14833
14834 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14835 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14836
14837 static void vl_api_ipsec_sa_details_t_handler_json
14838   (vl_api_ipsec_sa_details_t * mp)
14839 {
14840   vat_main_t *vam = &vat_main;
14841   vat_json_node_t *node = NULL;
14842   struct in_addr src_ip4, dst_ip4;
14843   struct in6_addr src_ip6, dst_ip6;
14844
14845   if (VAT_JSON_ARRAY != vam->json_tree.type)
14846     {
14847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14848       vat_json_init_array (&vam->json_tree);
14849     }
14850   node = vat_json_array_add (&vam->json_tree);
14851
14852   vat_json_init_object (node);
14853   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14855   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14856   vat_json_object_add_uint (node, "proto", mp->protocol);
14857   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14858   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14859   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14860   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14861   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14862   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14863   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14864                              mp->crypto_key_len);
14865   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14866                              mp->integ_key_len);
14867   if (mp->is_tunnel_ip6)
14868     {
14869       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14870       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14871       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14872       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14873     }
14874   else
14875     {
14876       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14877       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14878       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14879       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14880     }
14881   vat_json_object_add_uint (node, "replay_window",
14882                             clib_net_to_host_u64 (mp->replay_window));
14883   vat_json_object_add_uint (node, "total_data_size",
14884                             clib_net_to_host_u64 (mp->total_data_size));
14885
14886 }
14887
14888 static int
14889 api_ipsec_sa_dump (vat_main_t * vam)
14890 {
14891   unformat_input_t *i = vam->input;
14892   vl_api_ipsec_sa_dump_t *mp;
14893   vl_api_control_ping_t *mp_ping;
14894   u32 sa_id = ~0;
14895   int ret;
14896
14897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (i, "sa_id %d", &sa_id))
14900         ;
14901       else
14902         {
14903           clib_warning ("parse error '%U'", format_unformat_error, i);
14904           return -99;
14905         }
14906     }
14907
14908   M (IPSEC_SA_DUMP, mp);
14909
14910   mp->sa_id = ntohl (sa_id);
14911
14912   S (mp);
14913
14914   /* Use a control ping for synchronization */
14915   M (CONTROL_PING, mp_ping);
14916   S (mp_ping);
14917
14918   W (ret);
14919   return ret;
14920 }
14921
14922 static int
14923 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14924 {
14925   unformat_input_t *i = vam->input;
14926   vl_api_ipsec_tunnel_if_set_key_t *mp;
14927   u32 sw_if_index = ~0;
14928   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14929   u8 *key = 0;
14930   u32 alg = ~0;
14931   int ret;
14932
14933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14934     {
14935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14936         ;
14937       else
14938         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14939         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14940       else
14941         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14942         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14943       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14944         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14945       else
14946         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14947         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14948       else if (unformat (i, "%U", unformat_hex_string, &key))
14949         ;
14950       else
14951         {
14952           clib_warning ("parse error '%U'", format_unformat_error, i);
14953           return -99;
14954         }
14955     }
14956
14957   if (sw_if_index == ~0)
14958     {
14959       errmsg ("interface must be specified");
14960       return -99;
14961     }
14962
14963   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14964     {
14965       errmsg ("key type must be specified");
14966       return -99;
14967     }
14968
14969   if (alg == ~0)
14970     {
14971       errmsg ("algorithm must be specified");
14972       return -99;
14973     }
14974
14975   if (vec_len (key) == 0)
14976     {
14977       errmsg ("key must be specified");
14978       return -99;
14979     }
14980
14981   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14982
14983   mp->sw_if_index = htonl (sw_if_index);
14984   mp->alg = alg;
14985   mp->key_type = key_type;
14986   mp->key_len = vec_len (key);
14987   clib_memcpy (mp->key, key, vec_len (key));
14988
14989   S (mp);
14990   W (ret);
14991
14992   return ret;
14993 }
14994
14995 static int
14996 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14997 {
14998   unformat_input_t *i = vam->input;
14999   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15000   u32 sw_if_index = ~0;
15001   u32 sa_id = ~0;
15002   u8 is_outbound = (u8) ~ 0;
15003   int ret;
15004
15005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15006     {
15007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15008         ;
15009       else if (unformat (i, "sa_id %d", &sa_id))
15010         ;
15011       else if (unformat (i, "outbound"))
15012         is_outbound = 1;
15013       else if (unformat (i, "inbound"))
15014         is_outbound = 0;
15015       else
15016         {
15017           clib_warning ("parse error '%U'", format_unformat_error, i);
15018           return -99;
15019         }
15020     }
15021
15022   if (sw_if_index == ~0)
15023     {
15024       errmsg ("interface must be specified");
15025       return -99;
15026     }
15027
15028   if (sa_id == ~0)
15029     {
15030       errmsg ("SA ID must be specified");
15031       return -99;
15032     }
15033
15034   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15035
15036   mp->sw_if_index = htonl (sw_if_index);
15037   mp->sa_id = htonl (sa_id);
15038   mp->is_outbound = is_outbound;
15039
15040   S (mp);
15041   W (ret);
15042
15043   return ret;
15044 }
15045
15046 static int
15047 api_ikev2_profile_add_del (vat_main_t * vam)
15048 {
15049   unformat_input_t *i = vam->input;
15050   vl_api_ikev2_profile_add_del_t *mp;
15051   u8 is_add = 1;
15052   u8 *name = 0;
15053   int ret;
15054
15055   const char *valid_chars = "a-zA-Z0-9_";
15056
15057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15058     {
15059       if (unformat (i, "del"))
15060         is_add = 0;
15061       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15062         vec_add1 (name, 0);
15063       else
15064         {
15065           errmsg ("parse error '%U'", format_unformat_error, i);
15066           return -99;
15067         }
15068     }
15069
15070   if (!vec_len (name))
15071     {
15072       errmsg ("profile name must be specified");
15073       return -99;
15074     }
15075
15076   if (vec_len (name) > 64)
15077     {
15078       errmsg ("profile name too long");
15079       return -99;
15080     }
15081
15082   M (IKEV2_PROFILE_ADD_DEL, mp);
15083
15084   clib_memcpy (mp->name, name, vec_len (name));
15085   mp->is_add = is_add;
15086   vec_free (name);
15087
15088   S (mp);
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_ikev2_profile_set_auth (vat_main_t * vam)
15095 {
15096   unformat_input_t *i = vam->input;
15097   vl_api_ikev2_profile_set_auth_t *mp;
15098   u8 *name = 0;
15099   u8 *data = 0;
15100   u32 auth_method = 0;
15101   u8 is_hex = 0;
15102   int ret;
15103
15104   const char *valid_chars = "a-zA-Z0-9_";
15105
15106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15107     {
15108       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15109         vec_add1 (name, 0);
15110       else if (unformat (i, "auth_method %U",
15111                          unformat_ikev2_auth_method, &auth_method))
15112         ;
15113       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15114         is_hex = 1;
15115       else if (unformat (i, "auth_data %v", &data))
15116         ;
15117       else
15118         {
15119           errmsg ("parse error '%U'", format_unformat_error, i);
15120           return -99;
15121         }
15122     }
15123
15124   if (!vec_len (name))
15125     {
15126       errmsg ("profile name must be specified");
15127       return -99;
15128     }
15129
15130   if (vec_len (name) > 64)
15131     {
15132       errmsg ("profile name too long");
15133       return -99;
15134     }
15135
15136   if (!vec_len (data))
15137     {
15138       errmsg ("auth_data must be specified");
15139       return -99;
15140     }
15141
15142   if (!auth_method)
15143     {
15144       errmsg ("auth_method must be specified");
15145       return -99;
15146     }
15147
15148   M (IKEV2_PROFILE_SET_AUTH, mp);
15149
15150   mp->is_hex = is_hex;
15151   mp->auth_method = (u8) auth_method;
15152   mp->data_len = vec_len (data);
15153   clib_memcpy (mp->name, name, vec_len (name));
15154   clib_memcpy (mp->data, data, vec_len (data));
15155   vec_free (name);
15156   vec_free (data);
15157
15158   S (mp);
15159   W (ret);
15160   return ret;
15161 }
15162
15163 static int
15164 api_ikev2_profile_set_id (vat_main_t * vam)
15165 {
15166   unformat_input_t *i = vam->input;
15167   vl_api_ikev2_profile_set_id_t *mp;
15168   u8 *name = 0;
15169   u8 *data = 0;
15170   u8 is_local = 0;
15171   u32 id_type = 0;
15172   ip4_address_t ip4;
15173   int ret;
15174
15175   const char *valid_chars = "a-zA-Z0-9_";
15176
15177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15178     {
15179       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15180         vec_add1 (name, 0);
15181       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15182         ;
15183       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15184         {
15185           data = vec_new (u8, 4);
15186           clib_memcpy (data, ip4.as_u8, 4);
15187         }
15188       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15189         ;
15190       else if (unformat (i, "id_data %v", &data))
15191         ;
15192       else if (unformat (i, "local"))
15193         is_local = 1;
15194       else if (unformat (i, "remote"))
15195         is_local = 0;
15196       else
15197         {
15198           errmsg ("parse error '%U'", format_unformat_error, i);
15199           return -99;
15200         }
15201     }
15202
15203   if (!vec_len (name))
15204     {
15205       errmsg ("profile name must be specified");
15206       return -99;
15207     }
15208
15209   if (vec_len (name) > 64)
15210     {
15211       errmsg ("profile name too long");
15212       return -99;
15213     }
15214
15215   if (!vec_len (data))
15216     {
15217       errmsg ("id_data must be specified");
15218       return -99;
15219     }
15220
15221   if (!id_type)
15222     {
15223       errmsg ("id_type must be specified");
15224       return -99;
15225     }
15226
15227   M (IKEV2_PROFILE_SET_ID, mp);
15228
15229   mp->is_local = is_local;
15230   mp->id_type = (u8) id_type;
15231   mp->data_len = vec_len (data);
15232   clib_memcpy (mp->name, name, vec_len (name));
15233   clib_memcpy (mp->data, data, vec_len (data));
15234   vec_free (name);
15235   vec_free (data);
15236
15237   S (mp);
15238   W (ret);
15239   return ret;
15240 }
15241
15242 static int
15243 api_ikev2_profile_set_ts (vat_main_t * vam)
15244 {
15245   unformat_input_t *i = vam->input;
15246   vl_api_ikev2_profile_set_ts_t *mp;
15247   u8 *name = 0;
15248   u8 is_local = 0;
15249   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15250   ip4_address_t start_addr, end_addr;
15251
15252   const char *valid_chars = "a-zA-Z0-9_";
15253   int ret;
15254
15255   start_addr.as_u32 = 0;
15256   end_addr.as_u32 = (u32) ~ 0;
15257
15258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15259     {
15260       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15261         vec_add1 (name, 0);
15262       else if (unformat (i, "protocol %d", &proto))
15263         ;
15264       else if (unformat (i, "start_port %d", &start_port))
15265         ;
15266       else if (unformat (i, "end_port %d", &end_port))
15267         ;
15268       else
15269         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15270         ;
15271       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15272         ;
15273       else if (unformat (i, "local"))
15274         is_local = 1;
15275       else if (unformat (i, "remote"))
15276         is_local = 0;
15277       else
15278         {
15279           errmsg ("parse error '%U'", format_unformat_error, i);
15280           return -99;
15281         }
15282     }
15283
15284   if (!vec_len (name))
15285     {
15286       errmsg ("profile name must be specified");
15287       return -99;
15288     }
15289
15290   if (vec_len (name) > 64)
15291     {
15292       errmsg ("profile name too long");
15293       return -99;
15294     }
15295
15296   M (IKEV2_PROFILE_SET_TS, mp);
15297
15298   mp->is_local = is_local;
15299   mp->proto = (u8) proto;
15300   mp->start_port = (u16) start_port;
15301   mp->end_port = (u16) end_port;
15302   mp->start_addr = start_addr.as_u32;
15303   mp->end_addr = end_addr.as_u32;
15304   clib_memcpy (mp->name, name, vec_len (name));
15305   vec_free (name);
15306
15307   S (mp);
15308   W (ret);
15309   return ret;
15310 }
15311
15312 static int
15313 api_ikev2_set_local_key (vat_main_t * vam)
15314 {
15315   unformat_input_t *i = vam->input;
15316   vl_api_ikev2_set_local_key_t *mp;
15317   u8 *file = 0;
15318   int ret;
15319
15320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15321     {
15322       if (unformat (i, "file %v", &file))
15323         vec_add1 (file, 0);
15324       else
15325         {
15326           errmsg ("parse error '%U'", format_unformat_error, i);
15327           return -99;
15328         }
15329     }
15330
15331   if (!vec_len (file))
15332     {
15333       errmsg ("RSA key file must be specified");
15334       return -99;
15335     }
15336
15337   if (vec_len (file) > 256)
15338     {
15339       errmsg ("file name too long");
15340       return -99;
15341     }
15342
15343   M (IKEV2_SET_LOCAL_KEY, mp);
15344
15345   clib_memcpy (mp->key_file, file, vec_len (file));
15346   vec_free (file);
15347
15348   S (mp);
15349   W (ret);
15350   return ret;
15351 }
15352
15353 static int
15354 api_ikev2_set_responder (vat_main_t * vam)
15355 {
15356   unformat_input_t *i = vam->input;
15357   vl_api_ikev2_set_responder_t *mp;
15358   int ret;
15359   u8 *name = 0;
15360   u32 sw_if_index = ~0;
15361   ip4_address_t address;
15362
15363   const char *valid_chars = "a-zA-Z0-9_";
15364
15365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15366     {
15367       if (unformat
15368           (i, "%U interface %d address %U", unformat_token, valid_chars,
15369            &name, &sw_if_index, unformat_ip4_address, &address))
15370         vec_add1 (name, 0);
15371       else
15372         {
15373           errmsg ("parse error '%U'", format_unformat_error, i);
15374           return -99;
15375         }
15376     }
15377
15378   if (!vec_len (name))
15379     {
15380       errmsg ("profile name must be specified");
15381       return -99;
15382     }
15383
15384   if (vec_len (name) > 64)
15385     {
15386       errmsg ("profile name too long");
15387       return -99;
15388     }
15389
15390   M (IKEV2_SET_RESPONDER, mp);
15391
15392   clib_memcpy (mp->name, name, vec_len (name));
15393   vec_free (name);
15394
15395   mp->sw_if_index = sw_if_index;
15396   clib_memcpy (mp->address, &address, sizeof (address));
15397
15398   S (mp);
15399   W (ret);
15400   return ret;
15401 }
15402
15403 static int
15404 api_ikev2_set_ike_transforms (vat_main_t * vam)
15405 {
15406   unformat_input_t *i = vam->input;
15407   vl_api_ikev2_set_ike_transforms_t *mp;
15408   int ret;
15409   u8 *name = 0;
15410   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15411
15412   const char *valid_chars = "a-zA-Z0-9_";
15413
15414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15415     {
15416       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15417                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15418         vec_add1 (name, 0);
15419       else
15420         {
15421           errmsg ("parse error '%U'", format_unformat_error, i);
15422           return -99;
15423         }
15424     }
15425
15426   if (!vec_len (name))
15427     {
15428       errmsg ("profile name must be specified");
15429       return -99;
15430     }
15431
15432   if (vec_len (name) > 64)
15433     {
15434       errmsg ("profile name too long");
15435       return -99;
15436     }
15437
15438   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15439
15440   clib_memcpy (mp->name, name, vec_len (name));
15441   vec_free (name);
15442   mp->crypto_alg = crypto_alg;
15443   mp->crypto_key_size = crypto_key_size;
15444   mp->integ_alg = integ_alg;
15445   mp->dh_group = dh_group;
15446
15447   S (mp);
15448   W (ret);
15449   return ret;
15450 }
15451
15452
15453 static int
15454 api_ikev2_set_esp_transforms (vat_main_t * vam)
15455 {
15456   unformat_input_t *i = vam->input;
15457   vl_api_ikev2_set_esp_transforms_t *mp;
15458   int ret;
15459   u8 *name = 0;
15460   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15461
15462   const char *valid_chars = "a-zA-Z0-9_";
15463
15464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15465     {
15466       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15467                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15468         vec_add1 (name, 0);
15469       else
15470         {
15471           errmsg ("parse error '%U'", format_unformat_error, i);
15472           return -99;
15473         }
15474     }
15475
15476   if (!vec_len (name))
15477     {
15478       errmsg ("profile name must be specified");
15479       return -99;
15480     }
15481
15482   if (vec_len (name) > 64)
15483     {
15484       errmsg ("profile name too long");
15485       return -99;
15486     }
15487
15488   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15489
15490   clib_memcpy (mp->name, name, vec_len (name));
15491   vec_free (name);
15492   mp->crypto_alg = crypto_alg;
15493   mp->crypto_key_size = crypto_key_size;
15494   mp->integ_alg = integ_alg;
15495   mp->dh_group = dh_group;
15496
15497   S (mp);
15498   W (ret);
15499   return ret;
15500 }
15501
15502 static int
15503 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15504 {
15505   unformat_input_t *i = vam->input;
15506   vl_api_ikev2_set_sa_lifetime_t *mp;
15507   int ret;
15508   u8 *name = 0;
15509   u64 lifetime, lifetime_maxdata;
15510   u32 lifetime_jitter, handover;
15511
15512   const char *valid_chars = "a-zA-Z0-9_";
15513
15514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15515     {
15516       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15517                     &lifetime, &lifetime_jitter, &handover,
15518                     &lifetime_maxdata))
15519         vec_add1 (name, 0);
15520       else
15521         {
15522           errmsg ("parse error '%U'", format_unformat_error, i);
15523           return -99;
15524         }
15525     }
15526
15527   if (!vec_len (name))
15528     {
15529       errmsg ("profile name must be specified");
15530       return -99;
15531     }
15532
15533   if (vec_len (name) > 64)
15534     {
15535       errmsg ("profile name too long");
15536       return -99;
15537     }
15538
15539   M (IKEV2_SET_SA_LIFETIME, mp);
15540
15541   clib_memcpy (mp->name, name, vec_len (name));
15542   vec_free (name);
15543   mp->lifetime = lifetime;
15544   mp->lifetime_jitter = lifetime_jitter;
15545   mp->handover = handover;
15546   mp->lifetime_maxdata = lifetime_maxdata;
15547
15548   S (mp);
15549   W (ret);
15550   return ret;
15551 }
15552
15553 static int
15554 api_ikev2_initiate_sa_init (vat_main_t * vam)
15555 {
15556   unformat_input_t *i = vam->input;
15557   vl_api_ikev2_initiate_sa_init_t *mp;
15558   int ret;
15559   u8 *name = 0;
15560
15561   const char *valid_chars = "a-zA-Z0-9_";
15562
15563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15564     {
15565       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15566         vec_add1 (name, 0);
15567       else
15568         {
15569           errmsg ("parse error '%U'", format_unformat_error, i);
15570           return -99;
15571         }
15572     }
15573
15574   if (!vec_len (name))
15575     {
15576       errmsg ("profile name must be specified");
15577       return -99;
15578     }
15579
15580   if (vec_len (name) > 64)
15581     {
15582       errmsg ("profile name too long");
15583       return -99;
15584     }
15585
15586   M (IKEV2_INITIATE_SA_INIT, mp);
15587
15588   clib_memcpy (mp->name, name, vec_len (name));
15589   vec_free (name);
15590
15591   S (mp);
15592   W (ret);
15593   return ret;
15594 }
15595
15596 static int
15597 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15598 {
15599   unformat_input_t *i = vam->input;
15600   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15601   int ret;
15602   u64 ispi;
15603
15604
15605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15606     {
15607       if (unformat (i, "%lx", &ispi))
15608         ;
15609       else
15610         {
15611           errmsg ("parse error '%U'", format_unformat_error, i);
15612           return -99;
15613         }
15614     }
15615
15616   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15617
15618   mp->ispi = ispi;
15619
15620   S (mp);
15621   W (ret);
15622   return ret;
15623 }
15624
15625 static int
15626 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15627 {
15628   unformat_input_t *i = vam->input;
15629   vl_api_ikev2_initiate_del_child_sa_t *mp;
15630   int ret;
15631   u32 ispi;
15632
15633
15634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15635     {
15636       if (unformat (i, "%x", &ispi))
15637         ;
15638       else
15639         {
15640           errmsg ("parse error '%U'", format_unformat_error, i);
15641           return -99;
15642         }
15643     }
15644
15645   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15646
15647   mp->ispi = ispi;
15648
15649   S (mp);
15650   W (ret);
15651   return ret;
15652 }
15653
15654 static int
15655 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15656 {
15657   unformat_input_t *i = vam->input;
15658   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15659   int ret;
15660   u32 ispi;
15661
15662
15663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15664     {
15665       if (unformat (i, "%x", &ispi))
15666         ;
15667       else
15668         {
15669           errmsg ("parse error '%U'", format_unformat_error, i);
15670           return -99;
15671         }
15672     }
15673
15674   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15675
15676   mp->ispi = ispi;
15677
15678   S (mp);
15679   W (ret);
15680   return ret;
15681 }
15682
15683 /*
15684  * MAP
15685  */
15686 static int
15687 api_map_add_domain (vat_main_t * vam)
15688 {
15689   unformat_input_t *i = vam->input;
15690   vl_api_map_add_domain_t *mp;
15691
15692   ip4_address_t ip4_prefix;
15693   ip6_address_t ip6_prefix;
15694   ip6_address_t ip6_src;
15695   u32 num_m_args = 0;
15696   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15697     0, psid_length = 0;
15698   u8 is_translation = 0;
15699   u32 mtu = 0;
15700   u32 ip6_src_len = 128;
15701   int ret;
15702
15703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15704     {
15705       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15706                     &ip4_prefix, &ip4_prefix_len))
15707         num_m_args++;
15708       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15709                          &ip6_prefix, &ip6_prefix_len))
15710         num_m_args++;
15711       else
15712         if (unformat
15713             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15714              &ip6_src_len))
15715         num_m_args++;
15716       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15717         num_m_args++;
15718       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15719         num_m_args++;
15720       else if (unformat (i, "psid-offset %d", &psid_offset))
15721         num_m_args++;
15722       else if (unformat (i, "psid-len %d", &psid_length))
15723         num_m_args++;
15724       else if (unformat (i, "mtu %d", &mtu))
15725         num_m_args++;
15726       else if (unformat (i, "map-t"))
15727         is_translation = 1;
15728       else
15729         {
15730           clib_warning ("parse error '%U'", format_unformat_error, i);
15731           return -99;
15732         }
15733     }
15734
15735   if (num_m_args < 3)
15736     {
15737       errmsg ("mandatory argument(s) missing");
15738       return -99;
15739     }
15740
15741   /* Construct the API message */
15742   M (MAP_ADD_DOMAIN, mp);
15743
15744   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15745   mp->ip4_prefix_len = ip4_prefix_len;
15746
15747   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15748   mp->ip6_prefix_len = ip6_prefix_len;
15749
15750   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15751   mp->ip6_src_prefix_len = ip6_src_len;
15752
15753   mp->ea_bits_len = ea_bits_len;
15754   mp->psid_offset = psid_offset;
15755   mp->psid_length = psid_length;
15756   mp->is_translation = is_translation;
15757   mp->mtu = htons (mtu);
15758
15759   /* send it... */
15760   S (mp);
15761
15762   /* Wait for a reply, return good/bad news  */
15763   W (ret);
15764   return ret;
15765 }
15766
15767 static int
15768 api_map_del_domain (vat_main_t * vam)
15769 {
15770   unformat_input_t *i = vam->input;
15771   vl_api_map_del_domain_t *mp;
15772
15773   u32 num_m_args = 0;
15774   u32 index;
15775   int ret;
15776
15777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15778     {
15779       if (unformat (i, "index %d", &index))
15780         num_m_args++;
15781       else
15782         {
15783           clib_warning ("parse error '%U'", format_unformat_error, i);
15784           return -99;
15785         }
15786     }
15787
15788   if (num_m_args != 1)
15789     {
15790       errmsg ("mandatory argument(s) missing");
15791       return -99;
15792     }
15793
15794   /* Construct the API message */
15795   M (MAP_DEL_DOMAIN, mp);
15796
15797   mp->index = ntohl (index);
15798
15799   /* send it... */
15800   S (mp);
15801
15802   /* Wait for a reply, return good/bad news  */
15803   W (ret);
15804   return ret;
15805 }
15806
15807 static int
15808 api_map_add_del_rule (vat_main_t * vam)
15809 {
15810   unformat_input_t *i = vam->input;
15811   vl_api_map_add_del_rule_t *mp;
15812   u8 is_add = 1;
15813   ip6_address_t ip6_dst;
15814   u32 num_m_args = 0, index, psid = 0;
15815   int ret;
15816
15817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15818     {
15819       if (unformat (i, "index %d", &index))
15820         num_m_args++;
15821       else if (unformat (i, "psid %d", &psid))
15822         num_m_args++;
15823       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15824         num_m_args++;
15825       else if (unformat (i, "del"))
15826         {
15827           is_add = 0;
15828         }
15829       else
15830         {
15831           clib_warning ("parse error '%U'", format_unformat_error, i);
15832           return -99;
15833         }
15834     }
15835
15836   /* Construct the API message */
15837   M (MAP_ADD_DEL_RULE, mp);
15838
15839   mp->index = ntohl (index);
15840   mp->is_add = is_add;
15841   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15842   mp->psid = ntohs (psid);
15843
15844   /* send it... */
15845   S (mp);
15846
15847   /* Wait for a reply, return good/bad news  */
15848   W (ret);
15849   return ret;
15850 }
15851
15852 static int
15853 api_map_domain_dump (vat_main_t * vam)
15854 {
15855   vl_api_map_domain_dump_t *mp;
15856   vl_api_control_ping_t *mp_ping;
15857   int ret;
15858
15859   /* Construct the API message */
15860   M (MAP_DOMAIN_DUMP, mp);
15861
15862   /* send it... */
15863   S (mp);
15864
15865   /* Use a control ping for synchronization */
15866   MPING (CONTROL_PING, mp_ping);
15867   S (mp_ping);
15868
15869   W (ret);
15870   return ret;
15871 }
15872
15873 static int
15874 api_map_rule_dump (vat_main_t * vam)
15875 {
15876   unformat_input_t *i = vam->input;
15877   vl_api_map_rule_dump_t *mp;
15878   vl_api_control_ping_t *mp_ping;
15879   u32 domain_index = ~0;
15880   int ret;
15881
15882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15883     {
15884       if (unformat (i, "index %u", &domain_index))
15885         ;
15886       else
15887         break;
15888     }
15889
15890   if (domain_index == ~0)
15891     {
15892       clib_warning ("parse error: domain index expected");
15893       return -99;
15894     }
15895
15896   /* Construct the API message */
15897   M (MAP_RULE_DUMP, mp);
15898
15899   mp->domain_index = htonl (domain_index);
15900
15901   /* send it... */
15902   S (mp);
15903
15904   /* Use a control ping for synchronization */
15905   MPING (CONTROL_PING, mp_ping);
15906   S (mp_ping);
15907
15908   W (ret);
15909   return ret;
15910 }
15911
15912 static void vl_api_map_add_domain_reply_t_handler
15913   (vl_api_map_add_domain_reply_t * mp)
15914 {
15915   vat_main_t *vam = &vat_main;
15916   i32 retval = ntohl (mp->retval);
15917
15918   if (vam->async_mode)
15919     {
15920       vam->async_errors += (retval < 0);
15921     }
15922   else
15923     {
15924       vam->retval = retval;
15925       vam->result_ready = 1;
15926     }
15927 }
15928
15929 static void vl_api_map_add_domain_reply_t_handler_json
15930   (vl_api_map_add_domain_reply_t * mp)
15931 {
15932   vat_main_t *vam = &vat_main;
15933   vat_json_node_t node;
15934
15935   vat_json_init_object (&node);
15936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15937   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15938
15939   vat_json_print (vam->ofp, &node);
15940   vat_json_free (&node);
15941
15942   vam->retval = ntohl (mp->retval);
15943   vam->result_ready = 1;
15944 }
15945
15946 static int
15947 api_get_first_msg_id (vat_main_t * vam)
15948 {
15949   vl_api_get_first_msg_id_t *mp;
15950   unformat_input_t *i = vam->input;
15951   u8 *name;
15952   u8 name_set = 0;
15953   int ret;
15954
15955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15956     {
15957       if (unformat (i, "client %s", &name))
15958         name_set = 1;
15959       else
15960         break;
15961     }
15962
15963   if (name_set == 0)
15964     {
15965       errmsg ("missing client name");
15966       return -99;
15967     }
15968   vec_add1 (name, 0);
15969
15970   if (vec_len (name) > 63)
15971     {
15972       errmsg ("client name too long");
15973       return -99;
15974     }
15975
15976   M (GET_FIRST_MSG_ID, mp);
15977   clib_memcpy (mp->name, name, vec_len (name));
15978   S (mp);
15979   W (ret);
15980   return ret;
15981 }
15982
15983 static int
15984 api_cop_interface_enable_disable (vat_main_t * vam)
15985 {
15986   unformat_input_t *line_input = vam->input;
15987   vl_api_cop_interface_enable_disable_t *mp;
15988   u32 sw_if_index = ~0;
15989   u8 enable_disable = 1;
15990   int ret;
15991
15992   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15993     {
15994       if (unformat (line_input, "disable"))
15995         enable_disable = 0;
15996       if (unformat (line_input, "enable"))
15997         enable_disable = 1;
15998       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15999                          vam, &sw_if_index))
16000         ;
16001       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16002         ;
16003       else
16004         break;
16005     }
16006
16007   if (sw_if_index == ~0)
16008     {
16009       errmsg ("missing interface name or sw_if_index");
16010       return -99;
16011     }
16012
16013   /* Construct the API message */
16014   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16015   mp->sw_if_index = ntohl (sw_if_index);
16016   mp->enable_disable = enable_disable;
16017
16018   /* send it... */
16019   S (mp);
16020   /* Wait for the reply */
16021   W (ret);
16022   return ret;
16023 }
16024
16025 static int
16026 api_cop_whitelist_enable_disable (vat_main_t * vam)
16027 {
16028   unformat_input_t *line_input = vam->input;
16029   vl_api_cop_whitelist_enable_disable_t *mp;
16030   u32 sw_if_index = ~0;
16031   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16032   u32 fib_id = 0;
16033   int ret;
16034
16035   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16036     {
16037       if (unformat (line_input, "ip4"))
16038         ip4 = 1;
16039       else if (unformat (line_input, "ip6"))
16040         ip6 = 1;
16041       else if (unformat (line_input, "default"))
16042         default_cop = 1;
16043       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16044                          vam, &sw_if_index))
16045         ;
16046       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16047         ;
16048       else if (unformat (line_input, "fib-id %d", &fib_id))
16049         ;
16050       else
16051         break;
16052     }
16053
16054   if (sw_if_index == ~0)
16055     {
16056       errmsg ("missing interface name or sw_if_index");
16057       return -99;
16058     }
16059
16060   /* Construct the API message */
16061   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16062   mp->sw_if_index = ntohl (sw_if_index);
16063   mp->fib_id = ntohl (fib_id);
16064   mp->ip4 = ip4;
16065   mp->ip6 = ip6;
16066   mp->default_cop = default_cop;
16067
16068   /* send it... */
16069   S (mp);
16070   /* Wait for the reply */
16071   W (ret);
16072   return ret;
16073 }
16074
16075 static int
16076 api_get_node_graph (vat_main_t * vam)
16077 {
16078   vl_api_get_node_graph_t *mp;
16079   int ret;
16080
16081   M (GET_NODE_GRAPH, mp);
16082
16083   /* send it... */
16084   S (mp);
16085   /* Wait for the reply */
16086   W (ret);
16087   return ret;
16088 }
16089
16090 /* *INDENT-OFF* */
16091 /** Used for parsing LISP eids */
16092 typedef CLIB_PACKED(struct{
16093   u8 addr[16];   /**< eid address */
16094   u32 len;       /**< prefix length if IP */
16095   u8 type;      /**< type of eid */
16096 }) lisp_eid_vat_t;
16097 /* *INDENT-ON* */
16098
16099 static uword
16100 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16101 {
16102   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16103
16104   memset (a, 0, sizeof (a[0]));
16105
16106   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16107     {
16108       a->type = 0;              /* ipv4 type */
16109     }
16110   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16111     {
16112       a->type = 1;              /* ipv6 type */
16113     }
16114   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16115     {
16116       a->type = 2;              /* mac type */
16117     }
16118   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16119     {
16120       a->type = 3;              /* NSH type */
16121       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16122       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16123     }
16124   else
16125     {
16126       return 0;
16127     }
16128
16129   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16130     {
16131       return 0;
16132     }
16133
16134   return 1;
16135 }
16136
16137 static int
16138 lisp_eid_size_vat (u8 type)
16139 {
16140   switch (type)
16141     {
16142     case 0:
16143       return 4;
16144     case 1:
16145       return 16;
16146     case 2:
16147       return 6;
16148     case 3:
16149       return 5;
16150     }
16151   return 0;
16152 }
16153
16154 static void
16155 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16156 {
16157   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16158 }
16159
16160 static int
16161 api_one_add_del_locator_set (vat_main_t * vam)
16162 {
16163   unformat_input_t *input = vam->input;
16164   vl_api_one_add_del_locator_set_t *mp;
16165   u8 is_add = 1;
16166   u8 *locator_set_name = NULL;
16167   u8 locator_set_name_set = 0;
16168   vl_api_local_locator_t locator, *locators = 0;
16169   u32 sw_if_index, priority, weight;
16170   u32 data_len = 0;
16171
16172   int ret;
16173   /* Parse args required to build the message */
16174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16175     {
16176       if (unformat (input, "del"))
16177         {
16178           is_add = 0;
16179         }
16180       else if (unformat (input, "locator-set %s", &locator_set_name))
16181         {
16182           locator_set_name_set = 1;
16183         }
16184       else if (unformat (input, "sw_if_index %u p %u w %u",
16185                          &sw_if_index, &priority, &weight))
16186         {
16187           locator.sw_if_index = htonl (sw_if_index);
16188           locator.priority = priority;
16189           locator.weight = weight;
16190           vec_add1 (locators, locator);
16191         }
16192       else
16193         if (unformat
16194             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16195              &sw_if_index, &priority, &weight))
16196         {
16197           locator.sw_if_index = htonl (sw_if_index);
16198           locator.priority = priority;
16199           locator.weight = weight;
16200           vec_add1 (locators, locator);
16201         }
16202       else
16203         break;
16204     }
16205
16206   if (locator_set_name_set == 0)
16207     {
16208       errmsg ("missing locator-set name");
16209       vec_free (locators);
16210       return -99;
16211     }
16212
16213   if (vec_len (locator_set_name) > 64)
16214     {
16215       errmsg ("locator-set name too long");
16216       vec_free (locator_set_name);
16217       vec_free (locators);
16218       return -99;
16219     }
16220   vec_add1 (locator_set_name, 0);
16221
16222   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16223
16224   /* Construct the API message */
16225   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16226
16227   mp->is_add = is_add;
16228   clib_memcpy (mp->locator_set_name, locator_set_name,
16229                vec_len (locator_set_name));
16230   vec_free (locator_set_name);
16231
16232   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16233   if (locators)
16234     clib_memcpy (mp->locators, locators, data_len);
16235   vec_free (locators);
16236
16237   /* send it... */
16238   S (mp);
16239
16240   /* Wait for a reply... */
16241   W (ret);
16242   return ret;
16243 }
16244
16245 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16246
16247 static int
16248 api_one_add_del_locator (vat_main_t * vam)
16249 {
16250   unformat_input_t *input = vam->input;
16251   vl_api_one_add_del_locator_t *mp;
16252   u32 tmp_if_index = ~0;
16253   u32 sw_if_index = ~0;
16254   u8 sw_if_index_set = 0;
16255   u8 sw_if_index_if_name_set = 0;
16256   u32 priority = ~0;
16257   u8 priority_set = 0;
16258   u32 weight = ~0;
16259   u8 weight_set = 0;
16260   u8 is_add = 1;
16261   u8 *locator_set_name = NULL;
16262   u8 locator_set_name_set = 0;
16263   int ret;
16264
16265   /* Parse args required to build the message */
16266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16267     {
16268       if (unformat (input, "del"))
16269         {
16270           is_add = 0;
16271         }
16272       else if (unformat (input, "locator-set %s", &locator_set_name))
16273         {
16274           locator_set_name_set = 1;
16275         }
16276       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16277                          &tmp_if_index))
16278         {
16279           sw_if_index_if_name_set = 1;
16280           sw_if_index = tmp_if_index;
16281         }
16282       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16283         {
16284           sw_if_index_set = 1;
16285           sw_if_index = tmp_if_index;
16286         }
16287       else if (unformat (input, "p %d", &priority))
16288         {
16289           priority_set = 1;
16290         }
16291       else if (unformat (input, "w %d", &weight))
16292         {
16293           weight_set = 1;
16294         }
16295       else
16296         break;
16297     }
16298
16299   if (locator_set_name_set == 0)
16300     {
16301       errmsg ("missing locator-set name");
16302       return -99;
16303     }
16304
16305   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16306     {
16307       errmsg ("missing sw_if_index");
16308       vec_free (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 ("cannot use both params interface name and sw_if_index");
16315       vec_free (locator_set_name);
16316       return -99;
16317     }
16318
16319   if (priority_set == 0)
16320     {
16321       errmsg ("missing locator-set priority");
16322       vec_free (locator_set_name);
16323       return -99;
16324     }
16325
16326   if (weight_set == 0)
16327     {
16328       errmsg ("missing locator-set weight");
16329       vec_free (locator_set_name);
16330       return -99;
16331     }
16332
16333   if (vec_len (locator_set_name) > 64)
16334     {
16335       errmsg ("locator-set name too long");
16336       vec_free (locator_set_name);
16337       return -99;
16338     }
16339   vec_add1 (locator_set_name, 0);
16340
16341   /* Construct the API message */
16342   M (ONE_ADD_DEL_LOCATOR, mp);
16343
16344   mp->is_add = is_add;
16345   mp->sw_if_index = ntohl (sw_if_index);
16346   mp->priority = priority;
16347   mp->weight = weight;
16348   clib_memcpy (mp->locator_set_name, locator_set_name,
16349                vec_len (locator_set_name));
16350   vec_free (locator_set_name);
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Wait for a reply... */
16356   W (ret);
16357   return ret;
16358 }
16359
16360 #define api_lisp_add_del_locator api_one_add_del_locator
16361
16362 uword
16363 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16364 {
16365   u32 *key_id = va_arg (*args, u32 *);
16366   u8 *s = 0;
16367
16368   if (unformat (input, "%s", &s))
16369     {
16370       if (!strcmp ((char *) s, "sha1"))
16371         key_id[0] = HMAC_SHA_1_96;
16372       else if (!strcmp ((char *) s, "sha256"))
16373         key_id[0] = HMAC_SHA_256_128;
16374       else
16375         {
16376           clib_warning ("invalid key_id: '%s'", s);
16377           key_id[0] = HMAC_NO_KEY;
16378         }
16379     }
16380   else
16381     return 0;
16382
16383   vec_free (s);
16384   return 1;
16385 }
16386
16387 static int
16388 api_one_add_del_local_eid (vat_main_t * vam)
16389 {
16390   unformat_input_t *input = vam->input;
16391   vl_api_one_add_del_local_eid_t *mp;
16392   u8 is_add = 1;
16393   u8 eid_set = 0;
16394   lisp_eid_vat_t _eid, *eid = &_eid;
16395   u8 *locator_set_name = 0;
16396   u8 locator_set_name_set = 0;
16397   u32 vni = 0;
16398   u16 key_id = 0;
16399   u8 *key = 0;
16400   int ret;
16401
16402   /* Parse args required to build the message */
16403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16404     {
16405       if (unformat (input, "del"))
16406         {
16407           is_add = 0;
16408         }
16409       else if (unformat (input, "vni %d", &vni))
16410         {
16411           ;
16412         }
16413       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16414         {
16415           eid_set = 1;
16416         }
16417       else if (unformat (input, "locator-set %s", &locator_set_name))
16418         {
16419           locator_set_name_set = 1;
16420         }
16421       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16422         ;
16423       else if (unformat (input, "secret-key %_%v%_", &key))
16424         ;
16425       else
16426         break;
16427     }
16428
16429   if (locator_set_name_set == 0)
16430     {
16431       errmsg ("missing locator-set name");
16432       return -99;
16433     }
16434
16435   if (0 == eid_set)
16436     {
16437       errmsg ("EID address not set!");
16438       vec_free (locator_set_name);
16439       return -99;
16440     }
16441
16442   if (key && (0 == key_id))
16443     {
16444       errmsg ("invalid key_id!");
16445       return -99;
16446     }
16447
16448   if (vec_len (key) > 64)
16449     {
16450       errmsg ("key too long");
16451       vec_free (key);
16452       return -99;
16453     }
16454
16455   if (vec_len (locator_set_name) > 64)
16456     {
16457       errmsg ("locator-set name too long");
16458       vec_free (locator_set_name);
16459       return -99;
16460     }
16461   vec_add1 (locator_set_name, 0);
16462
16463   /* Construct the API message */
16464   M (ONE_ADD_DEL_LOCAL_EID, mp);
16465
16466   mp->is_add = is_add;
16467   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16468   mp->eid_type = eid->type;
16469   mp->prefix_len = eid->len;
16470   mp->vni = clib_host_to_net_u32 (vni);
16471   mp->key_id = clib_host_to_net_u16 (key_id);
16472   clib_memcpy (mp->locator_set_name, locator_set_name,
16473                vec_len (locator_set_name));
16474   clib_memcpy (mp->key, key, vec_len (key));
16475
16476   vec_free (locator_set_name);
16477   vec_free (key);
16478
16479   /* send it... */
16480   S (mp);
16481
16482   /* Wait for a reply... */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16488
16489 static int
16490 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16491 {
16492   u32 dp_table = 0, vni = 0;;
16493   unformat_input_t *input = vam->input;
16494   vl_api_gpe_add_del_fwd_entry_t *mp;
16495   u8 is_add = 1;
16496   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16497   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16498   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16499   u32 action = ~0, w;
16500   ip4_address_t rmt_rloc4, lcl_rloc4;
16501   ip6_address_t rmt_rloc6, lcl_rloc6;
16502   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16503   int ret;
16504
16505   memset (&rloc, 0, sizeof (rloc));
16506
16507   /* Parse args required to build the message */
16508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16509     {
16510       if (unformat (input, "del"))
16511         is_add = 0;
16512       else if (unformat (input, "add"))
16513         is_add = 1;
16514       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16515         {
16516           rmt_eid_set = 1;
16517         }
16518       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16519         {
16520           lcl_eid_set = 1;
16521         }
16522       else if (unformat (input, "vrf %d", &dp_table))
16523         ;
16524       else if (unformat (input, "bd %d", &dp_table))
16525         ;
16526       else if (unformat (input, "vni %d", &vni))
16527         ;
16528       else if (unformat (input, "w %d", &w))
16529         {
16530           if (!curr_rloc)
16531             {
16532               errmsg ("No RLOC configured for setting priority/weight!");
16533               return -99;
16534             }
16535           curr_rloc->weight = w;
16536         }
16537       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16538                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16539         {
16540           rloc.is_ip4 = 1;
16541
16542           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16543           rloc.weight = 0;
16544           vec_add1 (lcl_locs, rloc);
16545
16546           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16547           vec_add1 (rmt_locs, rloc);
16548           /* weight saved in rmt loc */
16549           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16550         }
16551       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16552                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16553         {
16554           rloc.is_ip4 = 0;
16555           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16556           rloc.weight = 0;
16557           vec_add1 (lcl_locs, rloc);
16558
16559           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16560           vec_add1 (rmt_locs, rloc);
16561           /* weight saved in rmt loc */
16562           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16563         }
16564       else if (unformat (input, "action %d", &action))
16565         {
16566           ;
16567         }
16568       else
16569         {
16570           clib_warning ("parse error '%U'", format_unformat_error, input);
16571           return -99;
16572         }
16573     }
16574
16575   if (!rmt_eid_set)
16576     {
16577       errmsg ("remote eid addresses not set");
16578       return -99;
16579     }
16580
16581   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16582     {
16583       errmsg ("eid types don't match");
16584       return -99;
16585     }
16586
16587   if (0 == rmt_locs && (u32) ~ 0 == action)
16588     {
16589       errmsg ("action not set for negative mapping");
16590       return -99;
16591     }
16592
16593   /* Construct the API message */
16594   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16595       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16596
16597   mp->is_add = is_add;
16598   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16599   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16600   mp->eid_type = rmt_eid->type;
16601   mp->dp_table = clib_host_to_net_u32 (dp_table);
16602   mp->vni = clib_host_to_net_u32 (vni);
16603   mp->rmt_len = rmt_eid->len;
16604   mp->lcl_len = lcl_eid->len;
16605   mp->action = action;
16606
16607   if (0 != rmt_locs && 0 != lcl_locs)
16608     {
16609       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16610       clib_memcpy (mp->locs, lcl_locs,
16611                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16612
16613       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16614       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16615                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16616     }
16617   vec_free (lcl_locs);
16618   vec_free (rmt_locs);
16619
16620   /* send it... */
16621   S (mp);
16622
16623   /* Wait for a reply... */
16624   W (ret);
16625   return ret;
16626 }
16627
16628 static int
16629 api_one_add_del_map_server (vat_main_t * vam)
16630 {
16631   unformat_input_t *input = vam->input;
16632   vl_api_one_add_del_map_server_t *mp;
16633   u8 is_add = 1;
16634   u8 ipv4_set = 0;
16635   u8 ipv6_set = 0;
16636   ip4_address_t ipv4;
16637   ip6_address_t ipv6;
16638   int ret;
16639
16640   /* Parse args required to build the message */
16641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16642     {
16643       if (unformat (input, "del"))
16644         {
16645           is_add = 0;
16646         }
16647       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16648         {
16649           ipv4_set = 1;
16650         }
16651       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16652         {
16653           ipv6_set = 1;
16654         }
16655       else
16656         break;
16657     }
16658
16659   if (ipv4_set && ipv6_set)
16660     {
16661       errmsg ("both eid v4 and v6 addresses set");
16662       return -99;
16663     }
16664
16665   if (!ipv4_set && !ipv6_set)
16666     {
16667       errmsg ("eid addresses not set");
16668       return -99;
16669     }
16670
16671   /* Construct the API message */
16672   M (ONE_ADD_DEL_MAP_SERVER, mp);
16673
16674   mp->is_add = is_add;
16675   if (ipv6_set)
16676     {
16677       mp->is_ipv6 = 1;
16678       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16679     }
16680   else
16681     {
16682       mp->is_ipv6 = 0;
16683       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16684     }
16685
16686   /* send it... */
16687   S (mp);
16688
16689   /* Wait for a reply... */
16690   W (ret);
16691   return ret;
16692 }
16693
16694 #define api_lisp_add_del_map_server api_one_add_del_map_server
16695
16696 static int
16697 api_one_add_del_map_resolver (vat_main_t * vam)
16698 {
16699   unformat_input_t *input = vam->input;
16700   vl_api_one_add_del_map_resolver_t *mp;
16701   u8 is_add = 1;
16702   u8 ipv4_set = 0;
16703   u8 ipv6_set = 0;
16704   ip4_address_t ipv4;
16705   ip6_address_t ipv6;
16706   int ret;
16707
16708   /* Parse args required to build the message */
16709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16710     {
16711       if (unformat (input, "del"))
16712         {
16713           is_add = 0;
16714         }
16715       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16716         {
16717           ipv4_set = 1;
16718         }
16719       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16720         {
16721           ipv6_set = 1;
16722         }
16723       else
16724         break;
16725     }
16726
16727   if (ipv4_set && ipv6_set)
16728     {
16729       errmsg ("both eid v4 and v6 addresses set");
16730       return -99;
16731     }
16732
16733   if (!ipv4_set && !ipv6_set)
16734     {
16735       errmsg ("eid addresses not set");
16736       return -99;
16737     }
16738
16739   /* Construct the API message */
16740   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16741
16742   mp->is_add = is_add;
16743   if (ipv6_set)
16744     {
16745       mp->is_ipv6 = 1;
16746       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16747     }
16748   else
16749     {
16750       mp->is_ipv6 = 0;
16751       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16752     }
16753
16754   /* send it... */
16755   S (mp);
16756
16757   /* Wait for a reply... */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16763
16764 static int
16765 api_lisp_gpe_enable_disable (vat_main_t * vam)
16766 {
16767   unformat_input_t *input = vam->input;
16768   vl_api_gpe_enable_disable_t *mp;
16769   u8 is_set = 0;
16770   u8 is_en = 1;
16771   int ret;
16772
16773   /* Parse args required to build the message */
16774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16775     {
16776       if (unformat (input, "enable"))
16777         {
16778           is_set = 1;
16779           is_en = 1;
16780         }
16781       else if (unformat (input, "disable"))
16782         {
16783           is_set = 1;
16784           is_en = 0;
16785         }
16786       else
16787         break;
16788     }
16789
16790   if (is_set == 0)
16791     {
16792       errmsg ("Value not set");
16793       return -99;
16794     }
16795
16796   /* Construct the API message */
16797   M (GPE_ENABLE_DISABLE, mp);
16798
16799   mp->is_en = is_en;
16800
16801   /* send it... */
16802   S (mp);
16803
16804   /* Wait for a reply... */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 static int
16810 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16811 {
16812   unformat_input_t *input = vam->input;
16813   vl_api_one_rloc_probe_enable_disable_t *mp;
16814   u8 is_set = 0;
16815   u8 is_en = 0;
16816   int ret;
16817
16818   /* Parse args required to build the message */
16819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16820     {
16821       if (unformat (input, "enable"))
16822         {
16823           is_set = 1;
16824           is_en = 1;
16825         }
16826       else if (unformat (input, "disable"))
16827         is_set = 1;
16828       else
16829         break;
16830     }
16831
16832   if (!is_set)
16833     {
16834       errmsg ("Value not set");
16835       return -99;
16836     }
16837
16838   /* Construct the API message */
16839   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16840
16841   mp->is_enabled = is_en;
16842
16843   /* send it... */
16844   S (mp);
16845
16846   /* Wait for a reply... */
16847   W (ret);
16848   return ret;
16849 }
16850
16851 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16852
16853 static int
16854 api_one_map_register_enable_disable (vat_main_t * vam)
16855 {
16856   unformat_input_t *input = vam->input;
16857   vl_api_one_map_register_enable_disable_t *mp;
16858   u8 is_set = 0;
16859   u8 is_en = 0;
16860   int ret;
16861
16862   /* Parse args required to build the message */
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "enable"))
16866         {
16867           is_set = 1;
16868           is_en = 1;
16869         }
16870       else if (unformat (input, "disable"))
16871         is_set = 1;
16872       else
16873         break;
16874     }
16875
16876   if (!is_set)
16877     {
16878       errmsg ("Value not set");
16879       return -99;
16880     }
16881
16882   /* Construct the API message */
16883   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16884
16885   mp->is_enabled = is_en;
16886
16887   /* send it... */
16888   S (mp);
16889
16890   /* Wait for a reply... */
16891   W (ret);
16892   return ret;
16893 }
16894
16895 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16896
16897 static int
16898 api_one_enable_disable (vat_main_t * vam)
16899 {
16900   unformat_input_t *input = vam->input;
16901   vl_api_one_enable_disable_t *mp;
16902   u8 is_set = 0;
16903   u8 is_en = 0;
16904   int ret;
16905
16906   /* Parse args required to build the message */
16907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16908     {
16909       if (unformat (input, "enable"))
16910         {
16911           is_set = 1;
16912           is_en = 1;
16913         }
16914       else if (unformat (input, "disable"))
16915         {
16916           is_set = 1;
16917         }
16918       else
16919         break;
16920     }
16921
16922   if (!is_set)
16923     {
16924       errmsg ("Value not set");
16925       return -99;
16926     }
16927
16928   /* Construct the API message */
16929   M (ONE_ENABLE_DISABLE, mp);
16930
16931   mp->is_en = is_en;
16932
16933   /* send it... */
16934   S (mp);
16935
16936   /* Wait for a reply... */
16937   W (ret);
16938   return ret;
16939 }
16940
16941 #define api_lisp_enable_disable api_one_enable_disable
16942
16943 static int
16944 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16945 {
16946   unformat_input_t *input = vam->input;
16947   vl_api_one_enable_disable_xtr_mode_t *mp;
16948   u8 is_set = 0;
16949   u8 is_en = 0;
16950   int ret;
16951
16952   /* Parse args required to build the message */
16953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16954     {
16955       if (unformat (input, "enable"))
16956         {
16957           is_set = 1;
16958           is_en = 1;
16959         }
16960       else if (unformat (input, "disable"))
16961         {
16962           is_set = 1;
16963         }
16964       else
16965         break;
16966     }
16967
16968   if (!is_set)
16969     {
16970       errmsg ("Value not set");
16971       return -99;
16972     }
16973
16974   /* Construct the API message */
16975   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16976
16977   mp->is_en = is_en;
16978
16979   /* send it... */
16980   S (mp);
16981
16982   /* Wait for a reply... */
16983   W (ret);
16984   return ret;
16985 }
16986
16987 static int
16988 api_one_show_xtr_mode (vat_main_t * vam)
16989 {
16990   vl_api_one_show_xtr_mode_t *mp;
16991   int ret;
16992
16993   /* Construct the API message */
16994   M (ONE_SHOW_XTR_MODE, mp);
16995
16996   /* send it... */
16997   S (mp);
16998
16999   /* Wait for a reply... */
17000   W (ret);
17001   return ret;
17002 }
17003
17004 static int
17005 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17006 {
17007   unformat_input_t *input = vam->input;
17008   vl_api_one_enable_disable_pitr_mode_t *mp;
17009   u8 is_set = 0;
17010   u8 is_en = 0;
17011   int ret;
17012
17013   /* Parse args required to build the message */
17014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17015     {
17016       if (unformat (input, "enable"))
17017         {
17018           is_set = 1;
17019           is_en = 1;
17020         }
17021       else if (unformat (input, "disable"))
17022         {
17023           is_set = 1;
17024         }
17025       else
17026         break;
17027     }
17028
17029   if (!is_set)
17030     {
17031       errmsg ("Value not set");
17032       return -99;
17033     }
17034
17035   /* Construct the API message */
17036   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17037
17038   mp->is_en = is_en;
17039
17040   /* send it... */
17041   S (mp);
17042
17043   /* Wait for a reply... */
17044   W (ret);
17045   return ret;
17046 }
17047
17048 static int
17049 api_one_show_pitr_mode (vat_main_t * vam)
17050 {
17051   vl_api_one_show_pitr_mode_t *mp;
17052   int ret;
17053
17054   /* Construct the API message */
17055   M (ONE_SHOW_PITR_MODE, mp);
17056
17057   /* send it... */
17058   S (mp);
17059
17060   /* Wait for a reply... */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_one_enable_disable_petr_mode (vat_main_t * vam)
17067 {
17068   unformat_input_t *input = vam->input;
17069   vl_api_one_enable_disable_petr_mode_t *mp;
17070   u8 is_set = 0;
17071   u8 is_en = 0;
17072   int ret;
17073
17074   /* Parse args required to build the message */
17075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17076     {
17077       if (unformat (input, "enable"))
17078         {
17079           is_set = 1;
17080           is_en = 1;
17081         }
17082       else if (unformat (input, "disable"))
17083         {
17084           is_set = 1;
17085         }
17086       else
17087         break;
17088     }
17089
17090   if (!is_set)
17091     {
17092       errmsg ("Value not set");
17093       return -99;
17094     }
17095
17096   /* Construct the API message */
17097   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17098
17099   mp->is_en = is_en;
17100
17101   /* send it... */
17102   S (mp);
17103
17104   /* Wait for a reply... */
17105   W (ret);
17106   return ret;
17107 }
17108
17109 static int
17110 api_one_show_petr_mode (vat_main_t * vam)
17111 {
17112   vl_api_one_show_petr_mode_t *mp;
17113   int ret;
17114
17115   /* Construct the API message */
17116   M (ONE_SHOW_PETR_MODE, mp);
17117
17118   /* send it... */
17119   S (mp);
17120
17121   /* Wait for a reply... */
17122   W (ret);
17123   return ret;
17124 }
17125
17126 static int
17127 api_show_one_map_register_state (vat_main_t * vam)
17128 {
17129   vl_api_show_one_map_register_state_t *mp;
17130   int ret;
17131
17132   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17133
17134   /* send */
17135   S (mp);
17136
17137   /* wait for reply */
17138   W (ret);
17139   return ret;
17140 }
17141
17142 #define api_show_lisp_map_register_state api_show_one_map_register_state
17143
17144 static int
17145 api_show_one_rloc_probe_state (vat_main_t * vam)
17146 {
17147   vl_api_show_one_rloc_probe_state_t *mp;
17148   int ret;
17149
17150   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17151
17152   /* send */
17153   S (mp);
17154
17155   /* wait for reply */
17156   W (ret);
17157   return ret;
17158 }
17159
17160 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17161
17162 static int
17163 api_one_add_del_ndp_entry (vat_main_t * vam)
17164 {
17165   vl_api_one_add_del_ndp_entry_t *mp;
17166   unformat_input_t *input = vam->input;
17167   u8 is_add = 1;
17168   u8 mac_set = 0;
17169   u8 bd_set = 0;
17170   u8 ip_set = 0;
17171   u8 mac[6] = { 0, };
17172   u8 ip6[16] = { 0, };
17173   u32 bd = ~0;
17174   int ret;
17175
17176   /* Parse args required to build the message */
17177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17178     {
17179       if (unformat (input, "del"))
17180         is_add = 0;
17181       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17182         mac_set = 1;
17183       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17184         ip_set = 1;
17185       else if (unformat (input, "bd %d", &bd))
17186         bd_set = 1;
17187       else
17188         {
17189           errmsg ("parse error '%U'", format_unformat_error, input);
17190           return -99;
17191         }
17192     }
17193
17194   if (!bd_set || !ip_set || (!mac_set && is_add))
17195     {
17196       errmsg ("Missing BD, IP or MAC!");
17197       return -99;
17198     }
17199
17200   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17201   mp->is_add = is_add;
17202   clib_memcpy (mp->mac, mac, 6);
17203   mp->bd = clib_host_to_net_u32 (bd);
17204   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17205
17206   /* send */
17207   S (mp);
17208
17209   /* wait for reply */
17210   W (ret);
17211   return ret;
17212 }
17213
17214 static int
17215 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17216 {
17217   vl_api_one_add_del_l2_arp_entry_t *mp;
17218   unformat_input_t *input = vam->input;
17219   u8 is_add = 1;
17220   u8 mac_set = 0;
17221   u8 bd_set = 0;
17222   u8 ip_set = 0;
17223   u8 mac[6] = { 0, };
17224   u32 ip4 = 0, bd = ~0;
17225   int ret;
17226
17227   /* Parse args required to build the message */
17228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17229     {
17230       if (unformat (input, "del"))
17231         is_add = 0;
17232       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17233         mac_set = 1;
17234       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17235         ip_set = 1;
17236       else if (unformat (input, "bd %d", &bd))
17237         bd_set = 1;
17238       else
17239         {
17240           errmsg ("parse error '%U'", format_unformat_error, input);
17241           return -99;
17242         }
17243     }
17244
17245   if (!bd_set || !ip_set || (!mac_set && is_add))
17246     {
17247       errmsg ("Missing BD, IP or MAC!");
17248       return -99;
17249     }
17250
17251   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17252   mp->is_add = is_add;
17253   clib_memcpy (mp->mac, mac, 6);
17254   mp->bd = clib_host_to_net_u32 (bd);
17255   mp->ip4 = ip4;
17256
17257   /* send */
17258   S (mp);
17259
17260   /* wait for reply */
17261   W (ret);
17262   return ret;
17263 }
17264
17265 static int
17266 api_one_ndp_bd_get (vat_main_t * vam)
17267 {
17268   vl_api_one_ndp_bd_get_t *mp;
17269   int ret;
17270
17271   M (ONE_NDP_BD_GET, mp);
17272
17273   /* send */
17274   S (mp);
17275
17276   /* wait for reply */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 static int
17282 api_one_ndp_entries_get (vat_main_t * vam)
17283 {
17284   vl_api_one_ndp_entries_get_t *mp;
17285   unformat_input_t *input = vam->input;
17286   u8 bd_set = 0;
17287   u32 bd = ~0;
17288   int ret;
17289
17290   /* Parse args required to build the message */
17291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17292     {
17293       if (unformat (input, "bd %d", &bd))
17294         bd_set = 1;
17295       else
17296         {
17297           errmsg ("parse error '%U'", format_unformat_error, input);
17298           return -99;
17299         }
17300     }
17301
17302   if (!bd_set)
17303     {
17304       errmsg ("Expected bridge domain!");
17305       return -99;
17306     }
17307
17308   M (ONE_NDP_ENTRIES_GET, mp);
17309   mp->bd = clib_host_to_net_u32 (bd);
17310
17311   /* send */
17312   S (mp);
17313
17314   /* wait for reply */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 static int
17320 api_one_l2_arp_bd_get (vat_main_t * vam)
17321 {
17322   vl_api_one_l2_arp_bd_get_t *mp;
17323   int ret;
17324
17325   M (ONE_L2_ARP_BD_GET, mp);
17326
17327   /* send */
17328   S (mp);
17329
17330   /* wait for reply */
17331   W (ret);
17332   return ret;
17333 }
17334
17335 static int
17336 api_one_l2_arp_entries_get (vat_main_t * vam)
17337 {
17338   vl_api_one_l2_arp_entries_get_t *mp;
17339   unformat_input_t *input = vam->input;
17340   u8 bd_set = 0;
17341   u32 bd = ~0;
17342   int ret;
17343
17344   /* Parse args required to build the message */
17345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17346     {
17347       if (unformat (input, "bd %d", &bd))
17348         bd_set = 1;
17349       else
17350         {
17351           errmsg ("parse error '%U'", format_unformat_error, input);
17352           return -99;
17353         }
17354     }
17355
17356   if (!bd_set)
17357     {
17358       errmsg ("Expected bridge domain!");
17359       return -99;
17360     }
17361
17362   M (ONE_L2_ARP_ENTRIES_GET, mp);
17363   mp->bd = clib_host_to_net_u32 (bd);
17364
17365   /* send */
17366   S (mp);
17367
17368   /* wait for reply */
17369   W (ret);
17370   return ret;
17371 }
17372
17373 static int
17374 api_one_stats_enable_disable (vat_main_t * vam)
17375 {
17376   vl_api_one_stats_enable_disable_t *mp;
17377   unformat_input_t *input = vam->input;
17378   u8 is_set = 0;
17379   u8 is_en = 0;
17380   int ret;
17381
17382   /* Parse args required to build the message */
17383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17384     {
17385       if (unformat (input, "enable"))
17386         {
17387           is_set = 1;
17388           is_en = 1;
17389         }
17390       else if (unformat (input, "disable"))
17391         {
17392           is_set = 1;
17393         }
17394       else
17395         break;
17396     }
17397
17398   if (!is_set)
17399     {
17400       errmsg ("Value not set");
17401       return -99;
17402     }
17403
17404   M (ONE_STATS_ENABLE_DISABLE, mp);
17405   mp->is_en = is_en;
17406
17407   /* send */
17408   S (mp);
17409
17410   /* wait for reply */
17411   W (ret);
17412   return ret;
17413 }
17414
17415 static int
17416 api_show_one_stats_enable_disable (vat_main_t * vam)
17417 {
17418   vl_api_show_one_stats_enable_disable_t *mp;
17419   int ret;
17420
17421   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17422
17423   /* send */
17424   S (mp);
17425
17426   /* wait for reply */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_show_one_map_request_mode (vat_main_t * vam)
17433 {
17434   vl_api_show_one_map_request_mode_t *mp;
17435   int ret;
17436
17437   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17438
17439   /* send */
17440   S (mp);
17441
17442   /* wait for reply */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17448
17449 static int
17450 api_one_map_request_mode (vat_main_t * vam)
17451 {
17452   unformat_input_t *input = vam->input;
17453   vl_api_one_map_request_mode_t *mp;
17454   u8 mode = 0;
17455   int ret;
17456
17457   /* Parse args required to build the message */
17458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17459     {
17460       if (unformat (input, "dst-only"))
17461         mode = 0;
17462       else if (unformat (input, "src-dst"))
17463         mode = 1;
17464       else
17465         {
17466           errmsg ("parse error '%U'", format_unformat_error, input);
17467           return -99;
17468         }
17469     }
17470
17471   M (ONE_MAP_REQUEST_MODE, mp);
17472
17473   mp->mode = mode;
17474
17475   /* send */
17476   S (mp);
17477
17478   /* wait for reply */
17479   W (ret);
17480   return ret;
17481 }
17482
17483 #define api_lisp_map_request_mode api_one_map_request_mode
17484
17485 /**
17486  * Enable/disable ONE proxy ITR.
17487  *
17488  * @param vam vpp API test context
17489  * @return return code
17490  */
17491 static int
17492 api_one_pitr_set_locator_set (vat_main_t * vam)
17493 {
17494   u8 ls_name_set = 0;
17495   unformat_input_t *input = vam->input;
17496   vl_api_one_pitr_set_locator_set_t *mp;
17497   u8 is_add = 1;
17498   u8 *ls_name = 0;
17499   int ret;
17500
17501   /* Parse args required to build the message */
17502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17503     {
17504       if (unformat (input, "del"))
17505         is_add = 0;
17506       else if (unformat (input, "locator-set %s", &ls_name))
17507         ls_name_set = 1;
17508       else
17509         {
17510           errmsg ("parse error '%U'", format_unformat_error, input);
17511           return -99;
17512         }
17513     }
17514
17515   if (!ls_name_set)
17516     {
17517       errmsg ("locator-set name not set!");
17518       return -99;
17519     }
17520
17521   M (ONE_PITR_SET_LOCATOR_SET, mp);
17522
17523   mp->is_add = is_add;
17524   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17525   vec_free (ls_name);
17526
17527   /* send */
17528   S (mp);
17529
17530   /* wait for reply */
17531   W (ret);
17532   return ret;
17533 }
17534
17535 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17536
17537 static int
17538 api_one_nsh_set_locator_set (vat_main_t * vam)
17539 {
17540   u8 ls_name_set = 0;
17541   unformat_input_t *input = vam->input;
17542   vl_api_one_nsh_set_locator_set_t *mp;
17543   u8 is_add = 1;
17544   u8 *ls_name = 0;
17545   int ret;
17546
17547   /* Parse args required to build the message */
17548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17549     {
17550       if (unformat (input, "del"))
17551         is_add = 0;
17552       else if (unformat (input, "ls %s", &ls_name))
17553         ls_name_set = 1;
17554       else
17555         {
17556           errmsg ("parse error '%U'", format_unformat_error, input);
17557           return -99;
17558         }
17559     }
17560
17561   if (!ls_name_set && is_add)
17562     {
17563       errmsg ("locator-set name not set!");
17564       return -99;
17565     }
17566
17567   M (ONE_NSH_SET_LOCATOR_SET, mp);
17568
17569   mp->is_add = is_add;
17570   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17571   vec_free (ls_name);
17572
17573   /* send */
17574   S (mp);
17575
17576   /* wait for reply */
17577   W (ret);
17578   return ret;
17579 }
17580
17581 static int
17582 api_show_one_pitr (vat_main_t * vam)
17583 {
17584   vl_api_show_one_pitr_t *mp;
17585   int ret;
17586
17587   if (!vam->json_output)
17588     {
17589       print (vam->ofp, "%=20s", "lisp status:");
17590     }
17591
17592   M (SHOW_ONE_PITR, mp);
17593   /* send it... */
17594   S (mp);
17595
17596   /* Wait for a reply... */
17597   W (ret);
17598   return ret;
17599 }
17600
17601 #define api_show_lisp_pitr api_show_one_pitr
17602
17603 static int
17604 api_one_use_petr (vat_main_t * vam)
17605 {
17606   unformat_input_t *input = vam->input;
17607   vl_api_one_use_petr_t *mp;
17608   u8 is_add = 0;
17609   ip_address_t ip;
17610   int ret;
17611
17612   memset (&ip, 0, sizeof (ip));
17613
17614   /* Parse args required to build the message */
17615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17616     {
17617       if (unformat (input, "disable"))
17618         is_add = 0;
17619       else
17620         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17621         {
17622           is_add = 1;
17623           ip_addr_version (&ip) = IP4;
17624         }
17625       else
17626         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17627         {
17628           is_add = 1;
17629           ip_addr_version (&ip) = IP6;
17630         }
17631       else
17632         {
17633           errmsg ("parse error '%U'", format_unformat_error, input);
17634           return -99;
17635         }
17636     }
17637
17638   M (ONE_USE_PETR, mp);
17639
17640   mp->is_add = is_add;
17641   if (is_add)
17642     {
17643       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17644       if (mp->is_ip4)
17645         clib_memcpy (mp->address, &ip, 4);
17646       else
17647         clib_memcpy (mp->address, &ip, 16);
17648     }
17649
17650   /* send */
17651   S (mp);
17652
17653   /* wait for reply */
17654   W (ret);
17655   return ret;
17656 }
17657
17658 #define api_lisp_use_petr api_one_use_petr
17659
17660 static int
17661 api_show_one_nsh_mapping (vat_main_t * vam)
17662 {
17663   vl_api_show_one_use_petr_t *mp;
17664   int ret;
17665
17666   if (!vam->json_output)
17667     {
17668       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17669     }
17670
17671   M (SHOW_ONE_NSH_MAPPING, mp);
17672   /* send it... */
17673   S (mp);
17674
17675   /* Wait for a reply... */
17676   W (ret);
17677   return ret;
17678 }
17679
17680 static int
17681 api_show_one_use_petr (vat_main_t * vam)
17682 {
17683   vl_api_show_one_use_petr_t *mp;
17684   int ret;
17685
17686   if (!vam->json_output)
17687     {
17688       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17689     }
17690
17691   M (SHOW_ONE_USE_PETR, mp);
17692   /* send it... */
17693   S (mp);
17694
17695   /* Wait for a reply... */
17696   W (ret);
17697   return ret;
17698 }
17699
17700 #define api_show_lisp_use_petr api_show_one_use_petr
17701
17702 /**
17703  * Add/delete mapping between vni and vrf
17704  */
17705 static int
17706 api_one_eid_table_add_del_map (vat_main_t * vam)
17707 {
17708   unformat_input_t *input = vam->input;
17709   vl_api_one_eid_table_add_del_map_t *mp;
17710   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17711   u32 vni, vrf, bd_index;
17712   int ret;
17713
17714   /* Parse args required to build the message */
17715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17716     {
17717       if (unformat (input, "del"))
17718         is_add = 0;
17719       else if (unformat (input, "vrf %d", &vrf))
17720         vrf_set = 1;
17721       else if (unformat (input, "bd_index %d", &bd_index))
17722         bd_index_set = 1;
17723       else if (unformat (input, "vni %d", &vni))
17724         vni_set = 1;
17725       else
17726         break;
17727     }
17728
17729   if (!vni_set || (!vrf_set && !bd_index_set))
17730     {
17731       errmsg ("missing arguments!");
17732       return -99;
17733     }
17734
17735   if (vrf_set && bd_index_set)
17736     {
17737       errmsg ("error: both vrf and bd entered!");
17738       return -99;
17739     }
17740
17741   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17742
17743   mp->is_add = is_add;
17744   mp->vni = htonl (vni);
17745   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17746   mp->is_l2 = bd_index_set;
17747
17748   /* send */
17749   S (mp);
17750
17751   /* wait for reply */
17752   W (ret);
17753   return ret;
17754 }
17755
17756 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17757
17758 uword
17759 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17760 {
17761   u32 *action = va_arg (*args, u32 *);
17762   u8 *s = 0;
17763
17764   if (unformat (input, "%s", &s))
17765     {
17766       if (!strcmp ((char *) s, "no-action"))
17767         action[0] = 0;
17768       else if (!strcmp ((char *) s, "natively-forward"))
17769         action[0] = 1;
17770       else if (!strcmp ((char *) s, "send-map-request"))
17771         action[0] = 2;
17772       else if (!strcmp ((char *) s, "drop"))
17773         action[0] = 3;
17774       else
17775         {
17776           clib_warning ("invalid action: '%s'", s);
17777           action[0] = 3;
17778         }
17779     }
17780   else
17781     return 0;
17782
17783   vec_free (s);
17784   return 1;
17785 }
17786
17787 /**
17788  * Add/del remote mapping to/from ONE control plane
17789  *
17790  * @param vam vpp API test context
17791  * @return return code
17792  */
17793 static int
17794 api_one_add_del_remote_mapping (vat_main_t * vam)
17795 {
17796   unformat_input_t *input = vam->input;
17797   vl_api_one_add_del_remote_mapping_t *mp;
17798   u32 vni = 0;
17799   lisp_eid_vat_t _eid, *eid = &_eid;
17800   lisp_eid_vat_t _seid, *seid = &_seid;
17801   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17802   u32 action = ~0, p, w, data_len;
17803   ip4_address_t rloc4;
17804   ip6_address_t rloc6;
17805   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17806   int ret;
17807
17808   memset (&rloc, 0, sizeof (rloc));
17809
17810   /* Parse args required to build the message */
17811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17812     {
17813       if (unformat (input, "del-all"))
17814         {
17815           del_all = 1;
17816         }
17817       else if (unformat (input, "del"))
17818         {
17819           is_add = 0;
17820         }
17821       else if (unformat (input, "add"))
17822         {
17823           is_add = 1;
17824         }
17825       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17826         {
17827           eid_set = 1;
17828         }
17829       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17830         {
17831           seid_set = 1;
17832         }
17833       else if (unformat (input, "vni %d", &vni))
17834         {
17835           ;
17836         }
17837       else if (unformat (input, "p %d w %d", &p, &w))
17838         {
17839           if (!curr_rloc)
17840             {
17841               errmsg ("No RLOC configured for setting priority/weight!");
17842               return -99;
17843             }
17844           curr_rloc->priority = p;
17845           curr_rloc->weight = w;
17846         }
17847       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17848         {
17849           rloc.is_ip4 = 1;
17850           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17851           vec_add1 (rlocs, rloc);
17852           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17853         }
17854       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17855         {
17856           rloc.is_ip4 = 0;
17857           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17858           vec_add1 (rlocs, rloc);
17859           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17860         }
17861       else if (unformat (input, "action %U",
17862                          unformat_negative_mapping_action, &action))
17863         {
17864           ;
17865         }
17866       else
17867         {
17868           clib_warning ("parse error '%U'", format_unformat_error, input);
17869           return -99;
17870         }
17871     }
17872
17873   if (0 == eid_set)
17874     {
17875       errmsg ("missing params!");
17876       return -99;
17877     }
17878
17879   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17880     {
17881       errmsg ("no action set for negative map-reply!");
17882       return -99;
17883     }
17884
17885   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17886
17887   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17888   mp->is_add = is_add;
17889   mp->vni = htonl (vni);
17890   mp->action = (u8) action;
17891   mp->is_src_dst = seid_set;
17892   mp->eid_len = eid->len;
17893   mp->seid_len = seid->len;
17894   mp->del_all = del_all;
17895   mp->eid_type = eid->type;
17896   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17897   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17898
17899   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17900   clib_memcpy (mp->rlocs, rlocs, data_len);
17901   vec_free (rlocs);
17902
17903   /* send it... */
17904   S (mp);
17905
17906   /* Wait for a reply... */
17907   W (ret);
17908   return ret;
17909 }
17910
17911 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17912
17913 /**
17914  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17915  * forwarding entries in data-plane accordingly.
17916  *
17917  * @param vam vpp API test context
17918  * @return return code
17919  */
17920 static int
17921 api_one_add_del_adjacency (vat_main_t * vam)
17922 {
17923   unformat_input_t *input = vam->input;
17924   vl_api_one_add_del_adjacency_t *mp;
17925   u32 vni = 0;
17926   ip4_address_t leid4, reid4;
17927   ip6_address_t leid6, reid6;
17928   u8 reid_mac[6] = { 0 };
17929   u8 leid_mac[6] = { 0 };
17930   u8 reid_type, leid_type;
17931   u32 leid_len = 0, reid_len = 0, len;
17932   u8 is_add = 1;
17933   int ret;
17934
17935   leid_type = reid_type = (u8) ~ 0;
17936
17937   /* Parse args required to build the message */
17938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17939     {
17940       if (unformat (input, "del"))
17941         {
17942           is_add = 0;
17943         }
17944       else if (unformat (input, "add"))
17945         {
17946           is_add = 1;
17947         }
17948       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17949                          &reid4, &len))
17950         {
17951           reid_type = 0;        /* ipv4 */
17952           reid_len = len;
17953         }
17954       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17955                          &reid6, &len))
17956         {
17957           reid_type = 1;        /* ipv6 */
17958           reid_len = len;
17959         }
17960       else if (unformat (input, "reid %U", unformat_ethernet_address,
17961                          reid_mac))
17962         {
17963           reid_type = 2;        /* mac */
17964         }
17965       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17966                          &leid4, &len))
17967         {
17968           leid_type = 0;        /* ipv4 */
17969           leid_len = len;
17970         }
17971       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17972                          &leid6, &len))
17973         {
17974           leid_type = 1;        /* ipv6 */
17975           leid_len = len;
17976         }
17977       else if (unformat (input, "leid %U", unformat_ethernet_address,
17978                          leid_mac))
17979         {
17980           leid_type = 2;        /* mac */
17981         }
17982       else if (unformat (input, "vni %d", &vni))
17983         {
17984           ;
17985         }
17986       else
17987         {
17988           errmsg ("parse error '%U'", format_unformat_error, input);
17989           return -99;
17990         }
17991     }
17992
17993   if ((u8) ~ 0 == reid_type)
17994     {
17995       errmsg ("missing params!");
17996       return -99;
17997     }
17998
17999   if (leid_type != reid_type)
18000     {
18001       errmsg ("remote and local EIDs are of different types!");
18002       return -99;
18003     }
18004
18005   M (ONE_ADD_DEL_ADJACENCY, mp);
18006   mp->is_add = is_add;
18007   mp->vni = htonl (vni);
18008   mp->leid_len = leid_len;
18009   mp->reid_len = reid_len;
18010   mp->eid_type = reid_type;
18011
18012   switch (mp->eid_type)
18013     {
18014     case 0:
18015       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18016       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18017       break;
18018     case 1:
18019       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18020       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18021       break;
18022     case 2:
18023       clib_memcpy (mp->leid, leid_mac, 6);
18024       clib_memcpy (mp->reid, reid_mac, 6);
18025       break;
18026     default:
18027       errmsg ("unknown EID type %d!", mp->eid_type);
18028       return 0;
18029     }
18030
18031   /* send it... */
18032   S (mp);
18033
18034   /* Wait for a reply... */
18035   W (ret);
18036   return ret;
18037 }
18038
18039 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18040
18041 uword
18042 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18043 {
18044   u32 *mode = va_arg (*args, u32 *);
18045
18046   if (unformat (input, "lisp"))
18047     *mode = 0;
18048   else if (unformat (input, "vxlan"))
18049     *mode = 1;
18050   else
18051     return 0;
18052
18053   return 1;
18054 }
18055
18056 static int
18057 api_gpe_get_encap_mode (vat_main_t * vam)
18058 {
18059   vl_api_gpe_get_encap_mode_t *mp;
18060   int ret;
18061
18062   /* Construct the API message */
18063   M (GPE_GET_ENCAP_MODE, mp);
18064
18065   /* send it... */
18066   S (mp);
18067
18068   /* Wait for a reply... */
18069   W (ret);
18070   return ret;
18071 }
18072
18073 static int
18074 api_gpe_set_encap_mode (vat_main_t * vam)
18075 {
18076   unformat_input_t *input = vam->input;
18077   vl_api_gpe_set_encap_mode_t *mp;
18078   int ret;
18079   u32 mode = 0;
18080
18081   /* Parse args required to build the message */
18082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18083     {
18084       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18085         ;
18086       else
18087         break;
18088     }
18089
18090   /* Construct the API message */
18091   M (GPE_SET_ENCAP_MODE, mp);
18092
18093   mp->mode = mode;
18094
18095   /* send it... */
18096   S (mp);
18097
18098   /* Wait for a reply... */
18099   W (ret);
18100   return ret;
18101 }
18102
18103 static int
18104 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18105 {
18106   unformat_input_t *input = vam->input;
18107   vl_api_gpe_add_del_iface_t *mp;
18108   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18109   u32 dp_table = 0, vni = 0;
18110   int ret;
18111
18112   /* Parse args required to build the message */
18113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18114     {
18115       if (unformat (input, "up"))
18116         {
18117           action_set = 1;
18118           is_add = 1;
18119         }
18120       else if (unformat (input, "down"))
18121         {
18122           action_set = 1;
18123           is_add = 0;
18124         }
18125       else if (unformat (input, "table_id %d", &dp_table))
18126         {
18127           dp_table_set = 1;
18128         }
18129       else if (unformat (input, "bd_id %d", &dp_table))
18130         {
18131           dp_table_set = 1;
18132           is_l2 = 1;
18133         }
18134       else if (unformat (input, "vni %d", &vni))
18135         {
18136           vni_set = 1;
18137         }
18138       else
18139         break;
18140     }
18141
18142   if (action_set == 0)
18143     {
18144       errmsg ("Action not set");
18145       return -99;
18146     }
18147   if (dp_table_set == 0 || vni_set == 0)
18148     {
18149       errmsg ("vni and dp_table must be set");
18150       return -99;
18151     }
18152
18153   /* Construct the API message */
18154   M (GPE_ADD_DEL_IFACE, mp);
18155
18156   mp->is_add = is_add;
18157   mp->dp_table = clib_host_to_net_u32 (dp_table);
18158   mp->is_l2 = is_l2;
18159   mp->vni = clib_host_to_net_u32 (vni);
18160
18161   /* send it... */
18162   S (mp);
18163
18164   /* Wait for a reply... */
18165   W (ret);
18166   return ret;
18167 }
18168
18169 static int
18170 api_one_map_register_fallback_threshold (vat_main_t * vam)
18171 {
18172   unformat_input_t *input = vam->input;
18173   vl_api_one_map_register_fallback_threshold_t *mp;
18174   u32 value = 0;
18175   u8 is_set = 0;
18176   int ret;
18177
18178   /* Parse args required to build the message */
18179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18180     {
18181       if (unformat (input, "%u", &value))
18182         is_set = 1;
18183       else
18184         {
18185           clib_warning ("parse error '%U'", format_unformat_error, input);
18186           return -99;
18187         }
18188     }
18189
18190   if (!is_set)
18191     {
18192       errmsg ("fallback threshold value is missing!");
18193       return -99;
18194     }
18195
18196   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18197   mp->value = clib_host_to_net_u32 (value);
18198
18199   /* send it... */
18200   S (mp);
18201
18202   /* Wait for a reply... */
18203   W (ret);
18204   return ret;
18205 }
18206
18207 static int
18208 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18209 {
18210   vl_api_show_one_map_register_fallback_threshold_t *mp;
18211   int ret;
18212
18213   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18214
18215   /* send it... */
18216   S (mp);
18217
18218   /* Wait for a reply... */
18219   W (ret);
18220   return ret;
18221 }
18222
18223 uword
18224 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18225 {
18226   u32 *proto = va_arg (*args, u32 *);
18227
18228   if (unformat (input, "udp"))
18229     *proto = 1;
18230   else if (unformat (input, "api"))
18231     *proto = 2;
18232   else
18233     return 0;
18234
18235   return 1;
18236 }
18237
18238 static int
18239 api_one_set_transport_protocol (vat_main_t * vam)
18240 {
18241   unformat_input_t *input = vam->input;
18242   vl_api_one_set_transport_protocol_t *mp;
18243   u8 is_set = 0;
18244   u32 protocol = 0;
18245   int ret;
18246
18247   /* Parse args required to build the message */
18248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18249     {
18250       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18251         is_set = 1;
18252       else
18253         {
18254           clib_warning ("parse error '%U'", format_unformat_error, input);
18255           return -99;
18256         }
18257     }
18258
18259   if (!is_set)
18260     {
18261       errmsg ("Transport protocol missing!");
18262       return -99;
18263     }
18264
18265   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18266   mp->protocol = (u8) protocol;
18267
18268   /* send it... */
18269   S (mp);
18270
18271   /* Wait for a reply... */
18272   W (ret);
18273   return ret;
18274 }
18275
18276 static int
18277 api_one_get_transport_protocol (vat_main_t * vam)
18278 {
18279   vl_api_one_get_transport_protocol_t *mp;
18280   int ret;
18281
18282   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18283
18284   /* send it... */
18285   S (mp);
18286
18287   /* Wait for a reply... */
18288   W (ret);
18289   return ret;
18290 }
18291
18292 static int
18293 api_one_map_register_set_ttl (vat_main_t * vam)
18294 {
18295   unformat_input_t *input = vam->input;
18296   vl_api_one_map_register_set_ttl_t *mp;
18297   u32 ttl = 0;
18298   u8 is_set = 0;
18299   int ret;
18300
18301   /* Parse args required to build the message */
18302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18303     {
18304       if (unformat (input, "%u", &ttl))
18305         is_set = 1;
18306       else
18307         {
18308           clib_warning ("parse error '%U'", format_unformat_error, input);
18309           return -99;
18310         }
18311     }
18312
18313   if (!is_set)
18314     {
18315       errmsg ("TTL value missing!");
18316       return -99;
18317     }
18318
18319   M (ONE_MAP_REGISTER_SET_TTL, mp);
18320   mp->ttl = clib_host_to_net_u32 (ttl);
18321
18322   /* send it... */
18323   S (mp);
18324
18325   /* Wait for a reply... */
18326   W (ret);
18327   return ret;
18328 }
18329
18330 static int
18331 api_show_one_map_register_ttl (vat_main_t * vam)
18332 {
18333   vl_api_show_one_map_register_ttl_t *mp;
18334   int ret;
18335
18336   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18337
18338   /* send it... */
18339   S (mp);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 /**
18347  * Add/del map request itr rlocs from ONE control plane and updates
18348  *
18349  * @param vam vpp API test context
18350  * @return return code
18351  */
18352 static int
18353 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18354 {
18355   unformat_input_t *input = vam->input;
18356   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18357   u8 *locator_set_name = 0;
18358   u8 locator_set_name_set = 0;
18359   u8 is_add = 1;
18360   int ret;
18361
18362   /* Parse args required to build the message */
18363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18364     {
18365       if (unformat (input, "del"))
18366         {
18367           is_add = 0;
18368         }
18369       else if (unformat (input, "%_%v%_", &locator_set_name))
18370         {
18371           locator_set_name_set = 1;
18372         }
18373       else
18374         {
18375           clib_warning ("parse error '%U'", format_unformat_error, input);
18376           return -99;
18377         }
18378     }
18379
18380   if (is_add && !locator_set_name_set)
18381     {
18382       errmsg ("itr-rloc is not set!");
18383       return -99;
18384     }
18385
18386   if (is_add && vec_len (locator_set_name) > 64)
18387     {
18388       errmsg ("itr-rloc locator-set name too long");
18389       vec_free (locator_set_name);
18390       return -99;
18391     }
18392
18393   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18394   mp->is_add = is_add;
18395   if (is_add)
18396     {
18397       clib_memcpy (mp->locator_set_name, locator_set_name,
18398                    vec_len (locator_set_name));
18399     }
18400   else
18401     {
18402       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18403     }
18404   vec_free (locator_set_name);
18405
18406   /* send it... */
18407   S (mp);
18408
18409   /* Wait for a reply... */
18410   W (ret);
18411   return ret;
18412 }
18413
18414 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18415
18416 static int
18417 api_one_locator_dump (vat_main_t * vam)
18418 {
18419   unformat_input_t *input = vam->input;
18420   vl_api_one_locator_dump_t *mp;
18421   vl_api_control_ping_t *mp_ping;
18422   u8 is_index_set = 0, is_name_set = 0;
18423   u8 *ls_name = 0;
18424   u32 ls_index = ~0;
18425   int ret;
18426
18427   /* Parse args required to build the message */
18428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18429     {
18430       if (unformat (input, "ls_name %_%v%_", &ls_name))
18431         {
18432           is_name_set = 1;
18433         }
18434       else if (unformat (input, "ls_index %d", &ls_index))
18435         {
18436           is_index_set = 1;
18437         }
18438       else
18439         {
18440           errmsg ("parse error '%U'", format_unformat_error, input);
18441           return -99;
18442         }
18443     }
18444
18445   if (!is_index_set && !is_name_set)
18446     {
18447       errmsg ("error: expected one of index or name!");
18448       return -99;
18449     }
18450
18451   if (is_index_set && is_name_set)
18452     {
18453       errmsg ("error: only one param expected!");
18454       return -99;
18455     }
18456
18457   if (vec_len (ls_name) > 62)
18458     {
18459       errmsg ("error: locator set name too long!");
18460       return -99;
18461     }
18462
18463   if (!vam->json_output)
18464     {
18465       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18466     }
18467
18468   M (ONE_LOCATOR_DUMP, mp);
18469   mp->is_index_set = is_index_set;
18470
18471   if (is_index_set)
18472     mp->ls_index = clib_host_to_net_u32 (ls_index);
18473   else
18474     {
18475       vec_add1 (ls_name, 0);
18476       strncpy ((char *) mp->ls_name, (char *) ls_name,
18477                sizeof (mp->ls_name) - 1);
18478     }
18479
18480   /* send it... */
18481   S (mp);
18482
18483   /* Use a control ping for synchronization */
18484   MPING (CONTROL_PING, mp_ping);
18485   S (mp_ping);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 #define api_lisp_locator_dump api_one_locator_dump
18493
18494 static int
18495 api_one_locator_set_dump (vat_main_t * vam)
18496 {
18497   vl_api_one_locator_set_dump_t *mp;
18498   vl_api_control_ping_t *mp_ping;
18499   unformat_input_t *input = vam->input;
18500   u8 filter = 0;
18501   int ret;
18502
18503   /* Parse args required to build the message */
18504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18505     {
18506       if (unformat (input, "local"))
18507         {
18508           filter = 1;
18509         }
18510       else if (unformat (input, "remote"))
18511         {
18512           filter = 2;
18513         }
18514       else
18515         {
18516           errmsg ("parse error '%U'", format_unformat_error, input);
18517           return -99;
18518         }
18519     }
18520
18521   if (!vam->json_output)
18522     {
18523       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18524     }
18525
18526   M (ONE_LOCATOR_SET_DUMP, mp);
18527
18528   mp->filter = filter;
18529
18530   /* send it... */
18531   S (mp);
18532
18533   /* Use a control ping for synchronization */
18534   MPING (CONTROL_PING, mp_ping);
18535   S (mp_ping);
18536
18537   /* Wait for a reply... */
18538   W (ret);
18539   return ret;
18540 }
18541
18542 #define api_lisp_locator_set_dump api_one_locator_set_dump
18543
18544 static int
18545 api_one_eid_table_map_dump (vat_main_t * vam)
18546 {
18547   u8 is_l2 = 0;
18548   u8 mode_set = 0;
18549   unformat_input_t *input = vam->input;
18550   vl_api_one_eid_table_map_dump_t *mp;
18551   vl_api_control_ping_t *mp_ping;
18552   int ret;
18553
18554   /* Parse args required to build the message */
18555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18556     {
18557       if (unformat (input, "l2"))
18558         {
18559           is_l2 = 1;
18560           mode_set = 1;
18561         }
18562       else if (unformat (input, "l3"))
18563         {
18564           is_l2 = 0;
18565           mode_set = 1;
18566         }
18567       else
18568         {
18569           errmsg ("parse error '%U'", format_unformat_error, input);
18570           return -99;
18571         }
18572     }
18573
18574   if (!mode_set)
18575     {
18576       errmsg ("expected one of 'l2' or 'l3' parameter!");
18577       return -99;
18578     }
18579
18580   if (!vam->json_output)
18581     {
18582       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18583     }
18584
18585   M (ONE_EID_TABLE_MAP_DUMP, mp);
18586   mp->is_l2 = is_l2;
18587
18588   /* send it... */
18589   S (mp);
18590
18591   /* Use a control ping for synchronization */
18592   MPING (CONTROL_PING, mp_ping);
18593   S (mp_ping);
18594
18595   /* Wait for a reply... */
18596   W (ret);
18597   return ret;
18598 }
18599
18600 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18601
18602 static int
18603 api_one_eid_table_vni_dump (vat_main_t * vam)
18604 {
18605   vl_api_one_eid_table_vni_dump_t *mp;
18606   vl_api_control_ping_t *mp_ping;
18607   int ret;
18608
18609   if (!vam->json_output)
18610     {
18611       print (vam->ofp, "VNI");
18612     }
18613
18614   M (ONE_EID_TABLE_VNI_DUMP, mp);
18615
18616   /* send it... */
18617   S (mp);
18618
18619   /* Use a control ping for synchronization */
18620   MPING (CONTROL_PING, mp_ping);
18621   S (mp_ping);
18622
18623   /* Wait for a reply... */
18624   W (ret);
18625   return ret;
18626 }
18627
18628 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18629
18630 static int
18631 api_one_eid_table_dump (vat_main_t * vam)
18632 {
18633   unformat_input_t *i = vam->input;
18634   vl_api_one_eid_table_dump_t *mp;
18635   vl_api_control_ping_t *mp_ping;
18636   struct in_addr ip4;
18637   struct in6_addr ip6;
18638   u8 mac[6];
18639   u8 eid_type = ~0, eid_set = 0;
18640   u32 prefix_length = ~0, t, vni = 0;
18641   u8 filter = 0;
18642   int ret;
18643   lisp_nsh_api_t nsh;
18644
18645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18646     {
18647       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18648         {
18649           eid_set = 1;
18650           eid_type = 0;
18651           prefix_length = t;
18652         }
18653       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18654         {
18655           eid_set = 1;
18656           eid_type = 1;
18657           prefix_length = t;
18658         }
18659       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18660         {
18661           eid_set = 1;
18662           eid_type = 2;
18663         }
18664       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18665         {
18666           eid_set = 1;
18667           eid_type = 3;
18668         }
18669       else if (unformat (i, "vni %d", &t))
18670         {
18671           vni = t;
18672         }
18673       else if (unformat (i, "local"))
18674         {
18675           filter = 1;
18676         }
18677       else if (unformat (i, "remote"))
18678         {
18679           filter = 2;
18680         }
18681       else
18682         {
18683           errmsg ("parse error '%U'", format_unformat_error, i);
18684           return -99;
18685         }
18686     }
18687
18688   if (!vam->json_output)
18689     {
18690       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18691              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18692     }
18693
18694   M (ONE_EID_TABLE_DUMP, mp);
18695
18696   mp->filter = filter;
18697   if (eid_set)
18698     {
18699       mp->eid_set = 1;
18700       mp->vni = htonl (vni);
18701       mp->eid_type = eid_type;
18702       switch (eid_type)
18703         {
18704         case 0:
18705           mp->prefix_length = prefix_length;
18706           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18707           break;
18708         case 1:
18709           mp->prefix_length = prefix_length;
18710           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18711           break;
18712         case 2:
18713           clib_memcpy (mp->eid, mac, sizeof (mac));
18714           break;
18715         case 3:
18716           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18717           break;
18718         default:
18719           errmsg ("unknown EID type %d!", eid_type);
18720           return -99;
18721         }
18722     }
18723
18724   /* send it... */
18725   S (mp);
18726
18727   /* Use a control ping for synchronization */
18728   MPING (CONTROL_PING, mp_ping);
18729   S (mp_ping);
18730
18731   /* Wait for a reply... */
18732   W (ret);
18733   return ret;
18734 }
18735
18736 #define api_lisp_eid_table_dump api_one_eid_table_dump
18737
18738 static int
18739 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18740 {
18741   unformat_input_t *i = vam->input;
18742   vl_api_gpe_fwd_entries_get_t *mp;
18743   u8 vni_set = 0;
18744   u32 vni = ~0;
18745   int ret;
18746
18747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18748     {
18749       if (unformat (i, "vni %d", &vni))
18750         {
18751           vni_set = 1;
18752         }
18753       else
18754         {
18755           errmsg ("parse error '%U'", format_unformat_error, i);
18756           return -99;
18757         }
18758     }
18759
18760   if (!vni_set)
18761     {
18762       errmsg ("vni not set!");
18763       return -99;
18764     }
18765
18766   if (!vam->json_output)
18767     {
18768       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18769              "leid", "reid");
18770     }
18771
18772   M (GPE_FWD_ENTRIES_GET, mp);
18773   mp->vni = clib_host_to_net_u32 (vni);
18774
18775   /* send it... */
18776   S (mp);
18777
18778   /* Wait for a reply... */
18779   W (ret);
18780   return ret;
18781 }
18782
18783 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18784 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18785 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18786 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18787 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18788 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18789 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18790 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18791
18792 static int
18793 api_one_adjacencies_get (vat_main_t * vam)
18794 {
18795   unformat_input_t *i = vam->input;
18796   vl_api_one_adjacencies_get_t *mp;
18797   u8 vni_set = 0;
18798   u32 vni = ~0;
18799   int ret;
18800
18801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18802     {
18803       if (unformat (i, "vni %d", &vni))
18804         {
18805           vni_set = 1;
18806         }
18807       else
18808         {
18809           errmsg ("parse error '%U'", format_unformat_error, i);
18810           return -99;
18811         }
18812     }
18813
18814   if (!vni_set)
18815     {
18816       errmsg ("vni not set!");
18817       return -99;
18818     }
18819
18820   if (!vam->json_output)
18821     {
18822       print (vam->ofp, "%s %40s", "leid", "reid");
18823     }
18824
18825   M (ONE_ADJACENCIES_GET, mp);
18826   mp->vni = clib_host_to_net_u32 (vni);
18827
18828   /* send it... */
18829   S (mp);
18830
18831   /* Wait for a reply... */
18832   W (ret);
18833   return ret;
18834 }
18835
18836 #define api_lisp_adjacencies_get api_one_adjacencies_get
18837
18838 static int
18839 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18840 {
18841   unformat_input_t *i = vam->input;
18842   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18843   int ret;
18844   u8 ip_family_set = 0, is_ip4 = 1;
18845
18846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18847     {
18848       if (unformat (i, "ip4"))
18849         {
18850           ip_family_set = 1;
18851           is_ip4 = 1;
18852         }
18853       else if (unformat (i, "ip6"))
18854         {
18855           ip_family_set = 1;
18856           is_ip4 = 0;
18857         }
18858       else
18859         {
18860           errmsg ("parse error '%U'", format_unformat_error, i);
18861           return -99;
18862         }
18863     }
18864
18865   if (!ip_family_set)
18866     {
18867       errmsg ("ip family not set!");
18868       return -99;
18869     }
18870
18871   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18872   mp->is_ip4 = is_ip4;
18873
18874   /* send it... */
18875   S (mp);
18876
18877   /* Wait for a reply... */
18878   W (ret);
18879   return ret;
18880 }
18881
18882 static int
18883 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18884 {
18885   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18886   int ret;
18887
18888   if (!vam->json_output)
18889     {
18890       print (vam->ofp, "VNIs");
18891     }
18892
18893   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 static int
18904 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18905 {
18906   unformat_input_t *i = vam->input;
18907   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18908   int ret = 0;
18909   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18910   struct in_addr ip4;
18911   struct in6_addr ip6;
18912   u32 table_id = 0, nh_sw_if_index = ~0;
18913
18914   memset (&ip4, 0, sizeof (ip4));
18915   memset (&ip6, 0, sizeof (ip6));
18916
18917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18918     {
18919       if (unformat (i, "del"))
18920         is_add = 0;
18921       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18922                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18923         {
18924           ip_set = 1;
18925           is_ip4 = 1;
18926         }
18927       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18928                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18929         {
18930           ip_set = 1;
18931           is_ip4 = 0;
18932         }
18933       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18934         {
18935           ip_set = 1;
18936           is_ip4 = 1;
18937           nh_sw_if_index = ~0;
18938         }
18939       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18940         {
18941           ip_set = 1;
18942           is_ip4 = 0;
18943           nh_sw_if_index = ~0;
18944         }
18945       else if (unformat (i, "table %d", &table_id))
18946         ;
18947       else
18948         {
18949           errmsg ("parse error '%U'", format_unformat_error, i);
18950           return -99;
18951         }
18952     }
18953
18954   if (!ip_set)
18955     {
18956       errmsg ("nh addr not set!");
18957       return -99;
18958     }
18959
18960   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18961   mp->is_add = is_add;
18962   mp->table_id = clib_host_to_net_u32 (table_id);
18963   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18964   mp->is_ip4 = is_ip4;
18965   if (is_ip4)
18966     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18967   else
18968     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18969
18970   /* send it... */
18971   S (mp);
18972
18973   /* Wait for a reply... */
18974   W (ret);
18975   return ret;
18976 }
18977
18978 static int
18979 api_one_map_server_dump (vat_main_t * vam)
18980 {
18981   vl_api_one_map_server_dump_t *mp;
18982   vl_api_control_ping_t *mp_ping;
18983   int ret;
18984
18985   if (!vam->json_output)
18986     {
18987       print (vam->ofp, "%=20s", "Map server");
18988     }
18989
18990   M (ONE_MAP_SERVER_DUMP, mp);
18991   /* send it... */
18992   S (mp);
18993
18994   /* Use a control ping for synchronization */
18995   MPING (CONTROL_PING, mp_ping);
18996   S (mp_ping);
18997
18998   /* Wait for a reply... */
18999   W (ret);
19000   return ret;
19001 }
19002
19003 #define api_lisp_map_server_dump api_one_map_server_dump
19004
19005 static int
19006 api_one_map_resolver_dump (vat_main_t * vam)
19007 {
19008   vl_api_one_map_resolver_dump_t *mp;
19009   vl_api_control_ping_t *mp_ping;
19010   int ret;
19011
19012   if (!vam->json_output)
19013     {
19014       print (vam->ofp, "%=20s", "Map resolver");
19015     }
19016
19017   M (ONE_MAP_RESOLVER_DUMP, mp);
19018   /* send it... */
19019   S (mp);
19020
19021   /* Use a control ping for synchronization */
19022   MPING (CONTROL_PING, mp_ping);
19023   S (mp_ping);
19024
19025   /* Wait for a reply... */
19026   W (ret);
19027   return ret;
19028 }
19029
19030 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19031
19032 static int
19033 api_one_stats_flush (vat_main_t * vam)
19034 {
19035   vl_api_one_stats_flush_t *mp;
19036   int ret = 0;
19037
19038   M (ONE_STATS_FLUSH, mp);
19039   S (mp);
19040   W (ret);
19041   return ret;
19042 }
19043
19044 static int
19045 api_one_stats_dump (vat_main_t * vam)
19046 {
19047   vl_api_one_stats_dump_t *mp;
19048   vl_api_control_ping_t *mp_ping;
19049   int ret;
19050
19051   M (ONE_STATS_DUMP, mp);
19052   /* send it... */
19053   S (mp);
19054
19055   /* Use a control ping for synchronization */
19056   MPING (CONTROL_PING, mp_ping);
19057   S (mp_ping);
19058
19059   /* Wait for a reply... */
19060   W (ret);
19061   return ret;
19062 }
19063
19064 static int
19065 api_show_one_status (vat_main_t * vam)
19066 {
19067   vl_api_show_one_status_t *mp;
19068   int ret;
19069
19070   if (!vam->json_output)
19071     {
19072       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19073     }
19074
19075   M (SHOW_ONE_STATUS, mp);
19076   /* send it... */
19077   S (mp);
19078   /* Wait for a reply... */
19079   W (ret);
19080   return ret;
19081 }
19082
19083 #define api_show_lisp_status api_show_one_status
19084
19085 static int
19086 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19087 {
19088   vl_api_gpe_fwd_entry_path_dump_t *mp;
19089   vl_api_control_ping_t *mp_ping;
19090   unformat_input_t *i = vam->input;
19091   u32 fwd_entry_index = ~0;
19092   int ret;
19093
19094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (i, "index %d", &fwd_entry_index))
19097         ;
19098       else
19099         break;
19100     }
19101
19102   if (~0 == fwd_entry_index)
19103     {
19104       errmsg ("no index specified!");
19105       return -99;
19106     }
19107
19108   if (!vam->json_output)
19109     {
19110       print (vam->ofp, "first line");
19111     }
19112
19113   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19114
19115   /* send it... */
19116   S (mp);
19117   /* Use a control ping for synchronization */
19118   MPING (CONTROL_PING, mp_ping);
19119   S (mp_ping);
19120
19121   /* Wait for a reply... */
19122   W (ret);
19123   return ret;
19124 }
19125
19126 static int
19127 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19128 {
19129   vl_api_one_get_map_request_itr_rlocs_t *mp;
19130   int ret;
19131
19132   if (!vam->json_output)
19133     {
19134       print (vam->ofp, "%=20s", "itr-rlocs:");
19135     }
19136
19137   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19138   /* send it... */
19139   S (mp);
19140   /* Wait for a reply... */
19141   W (ret);
19142   return ret;
19143 }
19144
19145 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19146
19147 static int
19148 api_af_packet_create (vat_main_t * vam)
19149 {
19150   unformat_input_t *i = vam->input;
19151   vl_api_af_packet_create_t *mp;
19152   u8 *host_if_name = 0;
19153   u8 hw_addr[6];
19154   u8 random_hw_addr = 1;
19155   int ret;
19156
19157   memset (hw_addr, 0, sizeof (hw_addr));
19158
19159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19160     {
19161       if (unformat (i, "name %s", &host_if_name))
19162         vec_add1 (host_if_name, 0);
19163       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19164         random_hw_addr = 0;
19165       else
19166         break;
19167     }
19168
19169   if (!vec_len (host_if_name))
19170     {
19171       errmsg ("host-interface name must be specified");
19172       return -99;
19173     }
19174
19175   if (vec_len (host_if_name) > 64)
19176     {
19177       errmsg ("host-interface name too long");
19178       return -99;
19179     }
19180
19181   M (AF_PACKET_CREATE, mp);
19182
19183   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19184   clib_memcpy (mp->hw_addr, hw_addr, 6);
19185   mp->use_random_hw_addr = random_hw_addr;
19186   vec_free (host_if_name);
19187
19188   S (mp);
19189
19190   /* *INDENT-OFF* */
19191   W2 (ret,
19192       ({
19193         if (ret == 0)
19194           fprintf (vam->ofp ? vam->ofp : stderr,
19195                    " new sw_if_index = %d\n", vam->sw_if_index);
19196       }));
19197   /* *INDENT-ON* */
19198   return ret;
19199 }
19200
19201 static int
19202 api_af_packet_delete (vat_main_t * vam)
19203 {
19204   unformat_input_t *i = vam->input;
19205   vl_api_af_packet_delete_t *mp;
19206   u8 *host_if_name = 0;
19207   int ret;
19208
19209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19210     {
19211       if (unformat (i, "name %s", &host_if_name))
19212         vec_add1 (host_if_name, 0);
19213       else
19214         break;
19215     }
19216
19217   if (!vec_len (host_if_name))
19218     {
19219       errmsg ("host-interface name must be specified");
19220       return -99;
19221     }
19222
19223   if (vec_len (host_if_name) > 64)
19224     {
19225       errmsg ("host-interface name too long");
19226       return -99;
19227     }
19228
19229   M (AF_PACKET_DELETE, mp);
19230
19231   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19232   vec_free (host_if_name);
19233
19234   S (mp);
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static int
19240 api_policer_add_del (vat_main_t * vam)
19241 {
19242   unformat_input_t *i = vam->input;
19243   vl_api_policer_add_del_t *mp;
19244   u8 is_add = 1;
19245   u8 *name = 0;
19246   u32 cir = 0;
19247   u32 eir = 0;
19248   u64 cb = 0;
19249   u64 eb = 0;
19250   u8 rate_type = 0;
19251   u8 round_type = 0;
19252   u8 type = 0;
19253   u8 color_aware = 0;
19254   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19255   int ret;
19256
19257   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19258   conform_action.dscp = 0;
19259   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19260   exceed_action.dscp = 0;
19261   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19262   violate_action.dscp = 0;
19263
19264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19265     {
19266       if (unformat (i, "del"))
19267         is_add = 0;
19268       else if (unformat (i, "name %s", &name))
19269         vec_add1 (name, 0);
19270       else if (unformat (i, "cir %u", &cir))
19271         ;
19272       else if (unformat (i, "eir %u", &eir))
19273         ;
19274       else if (unformat (i, "cb %u", &cb))
19275         ;
19276       else if (unformat (i, "eb %u", &eb))
19277         ;
19278       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19279                          &rate_type))
19280         ;
19281       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19282                          &round_type))
19283         ;
19284       else if (unformat (i, "type %U", unformat_policer_type, &type))
19285         ;
19286       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19287                          &conform_action))
19288         ;
19289       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19290                          &exceed_action))
19291         ;
19292       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19293                          &violate_action))
19294         ;
19295       else if (unformat (i, "color-aware"))
19296         color_aware = 1;
19297       else
19298         break;
19299     }
19300
19301   if (!vec_len (name))
19302     {
19303       errmsg ("policer name must be specified");
19304       return -99;
19305     }
19306
19307   if (vec_len (name) > 64)
19308     {
19309       errmsg ("policer name too long");
19310       return -99;
19311     }
19312
19313   M (POLICER_ADD_DEL, mp);
19314
19315   clib_memcpy (mp->name, name, vec_len (name));
19316   vec_free (name);
19317   mp->is_add = is_add;
19318   mp->cir = ntohl (cir);
19319   mp->eir = ntohl (eir);
19320   mp->cb = clib_net_to_host_u64 (cb);
19321   mp->eb = clib_net_to_host_u64 (eb);
19322   mp->rate_type = rate_type;
19323   mp->round_type = round_type;
19324   mp->type = type;
19325   mp->conform_action_type = conform_action.action_type;
19326   mp->conform_dscp = conform_action.dscp;
19327   mp->exceed_action_type = exceed_action.action_type;
19328   mp->exceed_dscp = exceed_action.dscp;
19329   mp->violate_action_type = violate_action.action_type;
19330   mp->violate_dscp = violate_action.dscp;
19331   mp->color_aware = color_aware;
19332
19333   S (mp);
19334   W (ret);
19335   return ret;
19336 }
19337
19338 static int
19339 api_policer_dump (vat_main_t * vam)
19340 {
19341   unformat_input_t *i = vam->input;
19342   vl_api_policer_dump_t *mp;
19343   vl_api_control_ping_t *mp_ping;
19344   u8 *match_name = 0;
19345   u8 match_name_valid = 0;
19346   int ret;
19347
19348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19349     {
19350       if (unformat (i, "name %s", &match_name))
19351         {
19352           vec_add1 (match_name, 0);
19353           match_name_valid = 1;
19354         }
19355       else
19356         break;
19357     }
19358
19359   M (POLICER_DUMP, mp);
19360   mp->match_name_valid = match_name_valid;
19361   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19362   vec_free (match_name);
19363   /* send it... */
19364   S (mp);
19365
19366   /* Use a control ping for synchronization */
19367   MPING (CONTROL_PING, mp_ping);
19368   S (mp_ping);
19369
19370   /* Wait for a reply... */
19371   W (ret);
19372   return ret;
19373 }
19374
19375 static int
19376 api_policer_classify_set_interface (vat_main_t * vam)
19377 {
19378   unformat_input_t *i = vam->input;
19379   vl_api_policer_classify_set_interface_t *mp;
19380   u32 sw_if_index;
19381   int sw_if_index_set;
19382   u32 ip4_table_index = ~0;
19383   u32 ip6_table_index = ~0;
19384   u32 l2_table_index = ~0;
19385   u8 is_add = 1;
19386   int ret;
19387
19388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19391         sw_if_index_set = 1;
19392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19393         sw_if_index_set = 1;
19394       else if (unformat (i, "del"))
19395         is_add = 0;
19396       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19397         ;
19398       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19399         ;
19400       else if (unformat (i, "l2-table %d", &l2_table_index))
19401         ;
19402       else
19403         {
19404           clib_warning ("parse error '%U'", format_unformat_error, i);
19405           return -99;
19406         }
19407     }
19408
19409   if (sw_if_index_set == 0)
19410     {
19411       errmsg ("missing interface name or sw_if_index");
19412       return -99;
19413     }
19414
19415   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19416
19417   mp->sw_if_index = ntohl (sw_if_index);
19418   mp->ip4_table_index = ntohl (ip4_table_index);
19419   mp->ip6_table_index = ntohl (ip6_table_index);
19420   mp->l2_table_index = ntohl (l2_table_index);
19421   mp->is_add = is_add;
19422
19423   S (mp);
19424   W (ret);
19425   return ret;
19426 }
19427
19428 static int
19429 api_policer_classify_dump (vat_main_t * vam)
19430 {
19431   unformat_input_t *i = vam->input;
19432   vl_api_policer_classify_dump_t *mp;
19433   vl_api_control_ping_t *mp_ping;
19434   u8 type = POLICER_CLASSIFY_N_TABLES;
19435   int ret;
19436
19437   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19438     ;
19439   else
19440     {
19441       errmsg ("classify table type must be specified");
19442       return -99;
19443     }
19444
19445   if (!vam->json_output)
19446     {
19447       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19448     }
19449
19450   M (POLICER_CLASSIFY_DUMP, mp);
19451   mp->type = type;
19452   /* send it... */
19453   S (mp);
19454
19455   /* Use a control ping for synchronization */
19456   MPING (CONTROL_PING, mp_ping);
19457   S (mp_ping);
19458
19459   /* Wait for a reply... */
19460   W (ret);
19461   return ret;
19462 }
19463
19464 static int
19465 api_netmap_create (vat_main_t * vam)
19466 {
19467   unformat_input_t *i = vam->input;
19468   vl_api_netmap_create_t *mp;
19469   u8 *if_name = 0;
19470   u8 hw_addr[6];
19471   u8 random_hw_addr = 1;
19472   u8 is_pipe = 0;
19473   u8 is_master = 0;
19474   int ret;
19475
19476   memset (hw_addr, 0, sizeof (hw_addr));
19477
19478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19479     {
19480       if (unformat (i, "name %s", &if_name))
19481         vec_add1 (if_name, 0);
19482       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19483         random_hw_addr = 0;
19484       else if (unformat (i, "pipe"))
19485         is_pipe = 1;
19486       else if (unformat (i, "master"))
19487         is_master = 1;
19488       else if (unformat (i, "slave"))
19489         is_master = 0;
19490       else
19491         break;
19492     }
19493
19494   if (!vec_len (if_name))
19495     {
19496       errmsg ("interface name must be specified");
19497       return -99;
19498     }
19499
19500   if (vec_len (if_name) > 64)
19501     {
19502       errmsg ("interface name too long");
19503       return -99;
19504     }
19505
19506   M (NETMAP_CREATE, mp);
19507
19508   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19509   clib_memcpy (mp->hw_addr, hw_addr, 6);
19510   mp->use_random_hw_addr = random_hw_addr;
19511   mp->is_pipe = is_pipe;
19512   mp->is_master = is_master;
19513   vec_free (if_name);
19514
19515   S (mp);
19516   W (ret);
19517   return ret;
19518 }
19519
19520 static int
19521 api_netmap_delete (vat_main_t * vam)
19522 {
19523   unformat_input_t *i = vam->input;
19524   vl_api_netmap_delete_t *mp;
19525   u8 *if_name = 0;
19526   int ret;
19527
19528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19529     {
19530       if (unformat (i, "name %s", &if_name))
19531         vec_add1 (if_name, 0);
19532       else
19533         break;
19534     }
19535
19536   if (!vec_len (if_name))
19537     {
19538       errmsg ("interface name must be specified");
19539       return -99;
19540     }
19541
19542   if (vec_len (if_name) > 64)
19543     {
19544       errmsg ("interface name too long");
19545       return -99;
19546     }
19547
19548   M (NETMAP_DELETE, mp);
19549
19550   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19551   vec_free (if_name);
19552
19553   S (mp);
19554   W (ret);
19555   return ret;
19556 }
19557
19558 static void
19559 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19560 {
19561   if (fp->afi == IP46_TYPE_IP6)
19562     print (vam->ofp,
19563            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19564            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19565            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19566            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19567            format_ip6_address, fp->next_hop);
19568   else if (fp->afi == IP46_TYPE_IP4)
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_ip4_address, fp->next_hop);
19575 }
19576
19577 static void
19578 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19579                                  vl_api_fib_path2_t * fp)
19580 {
19581   struct in_addr ip4;
19582   struct in6_addr ip6;
19583
19584   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19585   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19586   vat_json_object_add_uint (node, "is_local", fp->is_local);
19587   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19588   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19589   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19590   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19591   if (fp->afi == IP46_TYPE_IP4)
19592     {
19593       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19594       vat_json_object_add_ip4 (node, "next_hop", ip4);
19595     }
19596   else if (fp->afi == IP46_TYPE_IP6)
19597     {
19598       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19599       vat_json_object_add_ip6 (node, "next_hop", ip6);
19600     }
19601 }
19602
19603 static void
19604 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19605 {
19606   vat_main_t *vam = &vat_main;
19607   int count = ntohl (mp->mt_count);
19608   vl_api_fib_path2_t *fp;
19609   i32 i;
19610
19611   print (vam->ofp, "[%d]: sw_if_index %d via:",
19612          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19613   fp = mp->mt_paths;
19614   for (i = 0; i < count; i++)
19615     {
19616       vl_api_mpls_fib_path_print (vam, fp);
19617       fp++;
19618     }
19619
19620   print (vam->ofp, "");
19621 }
19622
19623 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19624 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19625
19626 static void
19627 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19628 {
19629   vat_main_t *vam = &vat_main;
19630   vat_json_node_t *node = NULL;
19631   int count = ntohl (mp->mt_count);
19632   vl_api_fib_path2_t *fp;
19633   i32 i;
19634
19635   if (VAT_JSON_ARRAY != vam->json_tree.type)
19636     {
19637       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19638       vat_json_init_array (&vam->json_tree);
19639     }
19640   node = vat_json_array_add (&vam->json_tree);
19641
19642   vat_json_init_object (node);
19643   vat_json_object_add_uint (node, "tunnel_index",
19644                             ntohl (mp->mt_tunnel_index));
19645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19646
19647   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19648
19649   fp = mp->mt_paths;
19650   for (i = 0; i < count; i++)
19651     {
19652       vl_api_mpls_fib_path_json_print (node, fp);
19653       fp++;
19654     }
19655 }
19656
19657 static int
19658 api_mpls_tunnel_dump (vat_main_t * vam)
19659 {
19660   vl_api_mpls_tunnel_dump_t *mp;
19661   vl_api_control_ping_t *mp_ping;
19662   i32 index = -1;
19663   int ret;
19664
19665   /* Parse args required to build the message */
19666   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19667     {
19668       if (!unformat (vam->input, "tunnel_index %d", &index))
19669         {
19670           index = -1;
19671           break;
19672         }
19673     }
19674
19675   print (vam->ofp, "  tunnel_index %d", index);
19676
19677   M (MPLS_TUNNEL_DUMP, mp);
19678   mp->tunnel_index = htonl (index);
19679   S (mp);
19680
19681   /* Use a control ping for synchronization */
19682   MPING (CONTROL_PING, mp_ping);
19683   S (mp_ping);
19684
19685   W (ret);
19686   return ret;
19687 }
19688
19689 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19690 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19691
19692
19693 static void
19694 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19695 {
19696   vat_main_t *vam = &vat_main;
19697   int count = ntohl (mp->count);
19698   vl_api_fib_path2_t *fp;
19699   int i;
19700
19701   print (vam->ofp,
19702          "table-id %d, label %u, ess_bit %u",
19703          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19704   fp = mp->path;
19705   for (i = 0; i < count; i++)
19706     {
19707       vl_api_mpls_fib_path_print (vam, fp);
19708       fp++;
19709     }
19710 }
19711
19712 static void vl_api_mpls_fib_details_t_handler_json
19713   (vl_api_mpls_fib_details_t * mp)
19714 {
19715   vat_main_t *vam = &vat_main;
19716   int count = ntohl (mp->count);
19717   vat_json_node_t *node = NULL;
19718   vl_api_fib_path2_t *fp;
19719   int i;
19720
19721   if (VAT_JSON_ARRAY != vam->json_tree.type)
19722     {
19723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19724       vat_json_init_array (&vam->json_tree);
19725     }
19726   node = vat_json_array_add (&vam->json_tree);
19727
19728   vat_json_init_object (node);
19729   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19730   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19731   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19732   vat_json_object_add_uint (node, "path_count", count);
19733   fp = mp->path;
19734   for (i = 0; i < count; i++)
19735     {
19736       vl_api_mpls_fib_path_json_print (node, fp);
19737       fp++;
19738     }
19739 }
19740
19741 static int
19742 api_mpls_fib_dump (vat_main_t * vam)
19743 {
19744   vl_api_mpls_fib_dump_t *mp;
19745   vl_api_control_ping_t *mp_ping;
19746   int ret;
19747
19748   M (MPLS_FIB_DUMP, mp);
19749   S (mp);
19750
19751   /* Use a control ping for synchronization */
19752   MPING (CONTROL_PING, mp_ping);
19753   S (mp_ping);
19754
19755   W (ret);
19756   return ret;
19757 }
19758
19759 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19760 #define vl_api_ip_fib_details_t_print vl_noop_handler
19761
19762 static void
19763 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19764 {
19765   vat_main_t *vam = &vat_main;
19766   int count = ntohl (mp->count);
19767   vl_api_fib_path_t *fp;
19768   int i;
19769
19770   print (vam->ofp,
19771          "table-id %d, prefix %U/%d",
19772          ntohl (mp->table_id), format_ip4_address, mp->address,
19773          mp->address_length);
19774   fp = mp->path;
19775   for (i = 0; i < count; i++)
19776     {
19777       if (fp->afi == IP46_TYPE_IP6)
19778         print (vam->ofp,
19779                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19780                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19781                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19782                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19783                format_ip6_address, fp->next_hop);
19784       else if (fp->afi == IP46_TYPE_IP4)
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_ip4_address, fp->next_hop);
19791       fp++;
19792     }
19793 }
19794
19795 static void vl_api_ip_fib_details_t_handler_json
19796   (vl_api_ip_fib_details_t * mp)
19797 {
19798   vat_main_t *vam = &vat_main;
19799   int count = ntohl (mp->count);
19800   vat_json_node_t *node = NULL;
19801   struct in_addr ip4;
19802   struct in6_addr ip6;
19803   vl_api_fib_path_t *fp;
19804   int i;
19805
19806   if (VAT_JSON_ARRAY != vam->json_tree.type)
19807     {
19808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19809       vat_json_init_array (&vam->json_tree);
19810     }
19811   node = vat_json_array_add (&vam->json_tree);
19812
19813   vat_json_init_object (node);
19814   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19815   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19816   vat_json_object_add_ip4 (node, "prefix", ip4);
19817   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19818   vat_json_object_add_uint (node, "path_count", count);
19819   fp = mp->path;
19820   for (i = 0; i < count; i++)
19821     {
19822       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19823       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19824       vat_json_object_add_uint (node, "is_local", fp->is_local);
19825       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19826       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19827       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19828       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19829       if (fp->afi == IP46_TYPE_IP4)
19830         {
19831           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19832           vat_json_object_add_ip4 (node, "next_hop", ip4);
19833         }
19834       else if (fp->afi == IP46_TYPE_IP6)
19835         {
19836           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19837           vat_json_object_add_ip6 (node, "next_hop", ip6);
19838         }
19839     }
19840 }
19841
19842 static int
19843 api_ip_fib_dump (vat_main_t * vam)
19844 {
19845   vl_api_ip_fib_dump_t *mp;
19846   vl_api_control_ping_t *mp_ping;
19847   int ret;
19848
19849   M (IP_FIB_DUMP, mp);
19850   S (mp);
19851
19852   /* Use a control ping for synchronization */
19853   MPING (CONTROL_PING, mp_ping);
19854   S (mp_ping);
19855
19856   W (ret);
19857   return ret;
19858 }
19859
19860 static int
19861 api_ip_mfib_dump (vat_main_t * vam)
19862 {
19863   vl_api_ip_mfib_dump_t *mp;
19864   vl_api_control_ping_t *mp_ping;
19865   int ret;
19866
19867   M (IP_MFIB_DUMP, mp);
19868   S (mp);
19869
19870   /* Use a control ping for synchronization */
19871   MPING (CONTROL_PING, mp_ping);
19872   S (mp_ping);
19873
19874   W (ret);
19875   return ret;
19876 }
19877
19878 static void vl_api_ip_neighbor_details_t_handler
19879   (vl_api_ip_neighbor_details_t * mp)
19880 {
19881   vat_main_t *vam = &vat_main;
19882
19883   print (vam->ofp, "%c %U %U",
19884          (mp->is_static) ? 'S' : 'D',
19885          format_ethernet_address, &mp->mac_address,
19886          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19887          &mp->ip_address);
19888 }
19889
19890 static void vl_api_ip_neighbor_details_t_handler_json
19891   (vl_api_ip_neighbor_details_t * mp)
19892 {
19893
19894   vat_main_t *vam = &vat_main;
19895   vat_json_node_t *node;
19896   struct in_addr ip4;
19897   struct in6_addr ip6;
19898
19899   if (VAT_JSON_ARRAY != vam->json_tree.type)
19900     {
19901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19902       vat_json_init_array (&vam->json_tree);
19903     }
19904   node = vat_json_array_add (&vam->json_tree);
19905
19906   vat_json_init_object (node);
19907   vat_json_object_add_string_copy (node, "flag",
19908                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19909                                    "dynamic");
19910
19911   vat_json_object_add_string_copy (node, "link_layer",
19912                                    format (0, "%U", format_ethernet_address,
19913                                            &mp->mac_address));
19914
19915   if (mp->is_ipv6)
19916     {
19917       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19918       vat_json_object_add_ip6 (node, "ip_address", ip6);
19919     }
19920   else
19921     {
19922       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19923       vat_json_object_add_ip4 (node, "ip_address", ip4);
19924     }
19925 }
19926
19927 static int
19928 api_ip_neighbor_dump (vat_main_t * vam)
19929 {
19930   unformat_input_t *i = vam->input;
19931   vl_api_ip_neighbor_dump_t *mp;
19932   vl_api_control_ping_t *mp_ping;
19933   u8 is_ipv6 = 0;
19934   u32 sw_if_index = ~0;
19935   int ret;
19936
19937   /* Parse args required to build the message */
19938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19939     {
19940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19941         ;
19942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19943         ;
19944       else if (unformat (i, "ip6"))
19945         is_ipv6 = 1;
19946       else
19947         break;
19948     }
19949
19950   if (sw_if_index == ~0)
19951     {
19952       errmsg ("missing interface name or sw_if_index");
19953       return -99;
19954     }
19955
19956   M (IP_NEIGHBOR_DUMP, mp);
19957   mp->is_ipv6 = (u8) is_ipv6;
19958   mp->sw_if_index = ntohl (sw_if_index);
19959   S (mp);
19960
19961   /* Use a control ping for synchronization */
19962   MPING (CONTROL_PING, mp_ping);
19963   S (mp_ping);
19964
19965   W (ret);
19966   return ret;
19967 }
19968
19969 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19970 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19971
19972 static void
19973 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19974 {
19975   vat_main_t *vam = &vat_main;
19976   int count = ntohl (mp->count);
19977   vl_api_fib_path_t *fp;
19978   int i;
19979
19980   print (vam->ofp,
19981          "table-id %d, prefix %U/%d",
19982          ntohl (mp->table_id), format_ip6_address, mp->address,
19983          mp->address_length);
19984   fp = mp->path;
19985   for (i = 0; i < count; i++)
19986     {
19987       if (fp->afi == IP46_TYPE_IP6)
19988         print (vam->ofp,
19989                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19990                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19991                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19992                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19993                format_ip6_address, fp->next_hop);
19994       else if (fp->afi == IP46_TYPE_IP4)
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_ip4_address, fp->next_hop);
20001       fp++;
20002     }
20003 }
20004
20005 static void vl_api_ip6_fib_details_t_handler_json
20006   (vl_api_ip6_fib_details_t * mp)
20007 {
20008   vat_main_t *vam = &vat_main;
20009   int count = ntohl (mp->count);
20010   vat_json_node_t *node = NULL;
20011   struct in_addr ip4;
20012   struct in6_addr ip6;
20013   vl_api_fib_path_t *fp;
20014   int i;
20015
20016   if (VAT_JSON_ARRAY != vam->json_tree.type)
20017     {
20018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20019       vat_json_init_array (&vam->json_tree);
20020     }
20021   node = vat_json_array_add (&vam->json_tree);
20022
20023   vat_json_init_object (node);
20024   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20025   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20026   vat_json_object_add_ip6 (node, "prefix", ip6);
20027   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20028   vat_json_object_add_uint (node, "path_count", count);
20029   fp = mp->path;
20030   for (i = 0; i < count; i++)
20031     {
20032       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20033       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20034       vat_json_object_add_uint (node, "is_local", fp->is_local);
20035       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20036       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20037       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20038       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20039       if (fp->afi == IP46_TYPE_IP4)
20040         {
20041           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20042           vat_json_object_add_ip4 (node, "next_hop", ip4);
20043         }
20044       else if (fp->afi == IP46_TYPE_IP6)
20045         {
20046           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20047           vat_json_object_add_ip6 (node, "next_hop", ip6);
20048         }
20049     }
20050 }
20051
20052 static int
20053 api_ip6_fib_dump (vat_main_t * vam)
20054 {
20055   vl_api_ip6_fib_dump_t *mp;
20056   vl_api_control_ping_t *mp_ping;
20057   int ret;
20058
20059   M (IP6_FIB_DUMP, mp);
20060   S (mp);
20061
20062   /* Use a control ping for synchronization */
20063   MPING (CONTROL_PING, mp_ping);
20064   S (mp_ping);
20065
20066   W (ret);
20067   return ret;
20068 }
20069
20070 static int
20071 api_ip6_mfib_dump (vat_main_t * vam)
20072 {
20073   vl_api_ip6_mfib_dump_t *mp;
20074   vl_api_control_ping_t *mp_ping;
20075   int ret;
20076
20077   M (IP6_MFIB_DUMP, mp);
20078   S (mp);
20079
20080   /* Use a control ping for synchronization */
20081   MPING (CONTROL_PING, mp_ping);
20082   S (mp_ping);
20083
20084   W (ret);
20085   return ret;
20086 }
20087
20088 int
20089 api_classify_table_ids (vat_main_t * vam)
20090 {
20091   vl_api_classify_table_ids_t *mp;
20092   int ret;
20093
20094   /* Construct the API message */
20095   M (CLASSIFY_TABLE_IDS, mp);
20096   mp->context = 0;
20097
20098   S (mp);
20099   W (ret);
20100   return ret;
20101 }
20102
20103 int
20104 api_classify_table_by_interface (vat_main_t * vam)
20105 {
20106   unformat_input_t *input = vam->input;
20107   vl_api_classify_table_by_interface_t *mp;
20108
20109   u32 sw_if_index = ~0;
20110   int ret;
20111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20112     {
20113       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20114         ;
20115       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20116         ;
20117       else
20118         break;
20119     }
20120   if (sw_if_index == ~0)
20121     {
20122       errmsg ("missing interface name or sw_if_index");
20123       return -99;
20124     }
20125
20126   /* Construct the API message */
20127   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20128   mp->context = 0;
20129   mp->sw_if_index = ntohl (sw_if_index);
20130
20131   S (mp);
20132   W (ret);
20133   return ret;
20134 }
20135
20136 int
20137 api_classify_table_info (vat_main_t * vam)
20138 {
20139   unformat_input_t *input = vam->input;
20140   vl_api_classify_table_info_t *mp;
20141
20142   u32 table_id = ~0;
20143   int ret;
20144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20145     {
20146       if (unformat (input, "table_id %d", &table_id))
20147         ;
20148       else
20149         break;
20150     }
20151   if (table_id == ~0)
20152     {
20153       errmsg ("missing table id");
20154       return -99;
20155     }
20156
20157   /* Construct the API message */
20158   M (CLASSIFY_TABLE_INFO, mp);
20159   mp->context = 0;
20160   mp->table_id = ntohl (table_id);
20161
20162   S (mp);
20163   W (ret);
20164   return ret;
20165 }
20166
20167 int
20168 api_classify_session_dump (vat_main_t * vam)
20169 {
20170   unformat_input_t *input = vam->input;
20171   vl_api_classify_session_dump_t *mp;
20172   vl_api_control_ping_t *mp_ping;
20173
20174   u32 table_id = ~0;
20175   int ret;
20176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20177     {
20178       if (unformat (input, "table_id %d", &table_id))
20179         ;
20180       else
20181         break;
20182     }
20183   if (table_id == ~0)
20184     {
20185       errmsg ("missing table id");
20186       return -99;
20187     }
20188
20189   /* Construct the API message */
20190   M (CLASSIFY_SESSION_DUMP, mp);
20191   mp->context = 0;
20192   mp->table_id = ntohl (table_id);
20193   S (mp);
20194
20195   /* Use a control ping for synchronization */
20196   MPING (CONTROL_PING, mp_ping);
20197   S (mp_ping);
20198
20199   W (ret);
20200   return ret;
20201 }
20202
20203 static void
20204 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20205 {
20206   vat_main_t *vam = &vat_main;
20207
20208   print (vam->ofp, "collector_address %U, collector_port %d, "
20209          "src_address %U, vrf_id %d, path_mtu %u, "
20210          "template_interval %u, udp_checksum %d",
20211          format_ip4_address, mp->collector_address,
20212          ntohs (mp->collector_port),
20213          format_ip4_address, mp->src_address,
20214          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20215          ntohl (mp->template_interval), mp->udp_checksum);
20216
20217   vam->retval = 0;
20218   vam->result_ready = 1;
20219 }
20220
20221 static void
20222   vl_api_ipfix_exporter_details_t_handler_json
20223   (vl_api_ipfix_exporter_details_t * mp)
20224 {
20225   vat_main_t *vam = &vat_main;
20226   vat_json_node_t node;
20227   struct in_addr collector_address;
20228   struct in_addr src_address;
20229
20230   vat_json_init_object (&node);
20231   clib_memcpy (&collector_address, &mp->collector_address,
20232                sizeof (collector_address));
20233   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20234   vat_json_object_add_uint (&node, "collector_port",
20235                             ntohs (mp->collector_port));
20236   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20237   vat_json_object_add_ip4 (&node, "src_address", src_address);
20238   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20239   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20240   vat_json_object_add_uint (&node, "template_interval",
20241                             ntohl (mp->template_interval));
20242   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20243
20244   vat_json_print (vam->ofp, &node);
20245   vat_json_free (&node);
20246   vam->retval = 0;
20247   vam->result_ready = 1;
20248 }
20249
20250 int
20251 api_ipfix_exporter_dump (vat_main_t * vam)
20252 {
20253   vl_api_ipfix_exporter_dump_t *mp;
20254   int ret;
20255
20256   /* Construct the API message */
20257   M (IPFIX_EXPORTER_DUMP, mp);
20258   mp->context = 0;
20259
20260   S (mp);
20261   W (ret);
20262   return ret;
20263 }
20264
20265 static int
20266 api_ipfix_classify_stream_dump (vat_main_t * vam)
20267 {
20268   vl_api_ipfix_classify_stream_dump_t *mp;
20269   int ret;
20270
20271   /* Construct the API message */
20272   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20273   mp->context = 0;
20274
20275   S (mp);
20276   W (ret);
20277   return ret;
20278   /* NOTREACHED */
20279   return 0;
20280 }
20281
20282 static void
20283   vl_api_ipfix_classify_stream_details_t_handler
20284   (vl_api_ipfix_classify_stream_details_t * mp)
20285 {
20286   vat_main_t *vam = &vat_main;
20287   print (vam->ofp, "domain_id %d, src_port %d",
20288          ntohl (mp->domain_id), ntohs (mp->src_port));
20289   vam->retval = 0;
20290   vam->result_ready = 1;
20291 }
20292
20293 static void
20294   vl_api_ipfix_classify_stream_details_t_handler_json
20295   (vl_api_ipfix_classify_stream_details_t * mp)
20296 {
20297   vat_main_t *vam = &vat_main;
20298   vat_json_node_t node;
20299
20300   vat_json_init_object (&node);
20301   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20302   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20303
20304   vat_json_print (vam->ofp, &node);
20305   vat_json_free (&node);
20306   vam->retval = 0;
20307   vam->result_ready = 1;
20308 }
20309
20310 static int
20311 api_ipfix_classify_table_dump (vat_main_t * vam)
20312 {
20313   vl_api_ipfix_classify_table_dump_t *mp;
20314   vl_api_control_ping_t *mp_ping;
20315   int ret;
20316
20317   if (!vam->json_output)
20318     {
20319       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20320              "transport_protocol");
20321     }
20322
20323   /* Construct the API message */
20324   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20325
20326   /* send it... */
20327   S (mp);
20328
20329   /* Use a control ping for synchronization */
20330   MPING (CONTROL_PING, mp_ping);
20331   S (mp_ping);
20332
20333   W (ret);
20334   return ret;
20335 }
20336
20337 static void
20338   vl_api_ipfix_classify_table_details_t_handler
20339   (vl_api_ipfix_classify_table_details_t * mp)
20340 {
20341   vat_main_t *vam = &vat_main;
20342   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20343          mp->transport_protocol);
20344 }
20345
20346 static void
20347   vl_api_ipfix_classify_table_details_t_handler_json
20348   (vl_api_ipfix_classify_table_details_t * mp)
20349 {
20350   vat_json_node_t *node = NULL;
20351   vat_main_t *vam = &vat_main;
20352
20353   if (VAT_JSON_ARRAY != vam->json_tree.type)
20354     {
20355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20356       vat_json_init_array (&vam->json_tree);
20357     }
20358
20359   node = vat_json_array_add (&vam->json_tree);
20360   vat_json_init_object (node);
20361
20362   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20363   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20364   vat_json_object_add_uint (node, "transport_protocol",
20365                             mp->transport_protocol);
20366 }
20367
20368 static int
20369 api_sw_interface_span_enable_disable (vat_main_t * vam)
20370 {
20371   unformat_input_t *i = vam->input;
20372   vl_api_sw_interface_span_enable_disable_t *mp;
20373   u32 src_sw_if_index = ~0;
20374   u32 dst_sw_if_index = ~0;
20375   u8 state = 3;
20376   int ret;
20377   u8 is_l2 = 0;
20378
20379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20380     {
20381       if (unformat
20382           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20383         ;
20384       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20385         ;
20386       else
20387         if (unformat
20388             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20389         ;
20390       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20391         ;
20392       else if (unformat (i, "disable"))
20393         state = 0;
20394       else if (unformat (i, "rx"))
20395         state = 1;
20396       else if (unformat (i, "tx"))
20397         state = 2;
20398       else if (unformat (i, "both"))
20399         state = 3;
20400       else if (unformat (i, "l2"))
20401         is_l2 = 1;
20402       else
20403         break;
20404     }
20405
20406   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20407
20408   mp->sw_if_index_from = htonl (src_sw_if_index);
20409   mp->sw_if_index_to = htonl (dst_sw_if_index);
20410   mp->state = state;
20411   mp->is_l2 = is_l2;
20412
20413   S (mp);
20414   W (ret);
20415   return ret;
20416 }
20417
20418 static void
20419 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20420                                             * mp)
20421 {
20422   vat_main_t *vam = &vat_main;
20423   u8 *sw_if_from_name = 0;
20424   u8 *sw_if_to_name = 0;
20425   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20426   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20427   char *states[] = { "none", "rx", "tx", "both" };
20428   hash_pair_t *p;
20429
20430   /* *INDENT-OFF* */
20431   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20432   ({
20433     if ((u32) p->value[0] == sw_if_index_from)
20434       {
20435         sw_if_from_name = (u8 *)(p->key);
20436         if (sw_if_to_name)
20437           break;
20438       }
20439     if ((u32) p->value[0] == sw_if_index_to)
20440       {
20441         sw_if_to_name = (u8 *)(p->key);
20442         if (sw_if_from_name)
20443           break;
20444       }
20445   }));
20446   /* *INDENT-ON* */
20447   print (vam->ofp, "%20s => %20s (%s)",
20448          sw_if_from_name, sw_if_to_name, states[mp->state]);
20449 }
20450
20451 static void
20452   vl_api_sw_interface_span_details_t_handler_json
20453   (vl_api_sw_interface_span_details_t * mp)
20454 {
20455   vat_main_t *vam = &vat_main;
20456   vat_json_node_t *node = NULL;
20457   u8 *sw_if_from_name = 0;
20458   u8 *sw_if_to_name = 0;
20459   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20460   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20461   hash_pair_t *p;
20462
20463   /* *INDENT-OFF* */
20464   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20465   ({
20466     if ((u32) p->value[0] == sw_if_index_from)
20467       {
20468         sw_if_from_name = (u8 *)(p->key);
20469         if (sw_if_to_name)
20470           break;
20471       }
20472     if ((u32) p->value[0] == sw_if_index_to)
20473       {
20474         sw_if_to_name = (u8 *)(p->key);
20475         if (sw_if_from_name)
20476           break;
20477       }
20478   }));
20479   /* *INDENT-ON* */
20480
20481   if (VAT_JSON_ARRAY != vam->json_tree.type)
20482     {
20483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20484       vat_json_init_array (&vam->json_tree);
20485     }
20486   node = vat_json_array_add (&vam->json_tree);
20487
20488   vat_json_init_object (node);
20489   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20490   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20491   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20492   if (0 != sw_if_to_name)
20493     {
20494       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20495     }
20496   vat_json_object_add_uint (node, "state", mp->state);
20497 }
20498
20499 static int
20500 api_sw_interface_span_dump (vat_main_t * vam)
20501 {
20502   unformat_input_t *input = vam->input;
20503   vl_api_sw_interface_span_dump_t *mp;
20504   vl_api_control_ping_t *mp_ping;
20505   u8 is_l2 = 0;
20506   int ret;
20507
20508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20509     {
20510       if (unformat (input, "l2"))
20511         is_l2 = 1;
20512       else
20513         break;
20514     }
20515
20516   M (SW_INTERFACE_SPAN_DUMP, mp);
20517   mp->is_l2 = is_l2;
20518   S (mp);
20519
20520   /* Use a control ping for synchronization */
20521   MPING (CONTROL_PING, mp_ping);
20522   S (mp_ping);
20523
20524   W (ret);
20525   return ret;
20526 }
20527
20528 int
20529 api_pg_create_interface (vat_main_t * vam)
20530 {
20531   unformat_input_t *input = vam->input;
20532   vl_api_pg_create_interface_t *mp;
20533
20534   u32 if_id = ~0;
20535   int ret;
20536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20537     {
20538       if (unformat (input, "if_id %d", &if_id))
20539         ;
20540       else
20541         break;
20542     }
20543   if (if_id == ~0)
20544     {
20545       errmsg ("missing pg interface index");
20546       return -99;
20547     }
20548
20549   /* Construct the API message */
20550   M (PG_CREATE_INTERFACE, mp);
20551   mp->context = 0;
20552   mp->interface_id = ntohl (if_id);
20553
20554   S (mp);
20555   W (ret);
20556   return ret;
20557 }
20558
20559 int
20560 api_pg_capture (vat_main_t * vam)
20561 {
20562   unformat_input_t *input = vam->input;
20563   vl_api_pg_capture_t *mp;
20564
20565   u32 if_id = ~0;
20566   u8 enable = 1;
20567   u32 count = 1;
20568   u8 pcap_file_set = 0;
20569   u8 *pcap_file = 0;
20570   int ret;
20571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20572     {
20573       if (unformat (input, "if_id %d", &if_id))
20574         ;
20575       else if (unformat (input, "pcap %s", &pcap_file))
20576         pcap_file_set = 1;
20577       else if (unformat (input, "count %d", &count))
20578         ;
20579       else if (unformat (input, "disable"))
20580         enable = 0;
20581       else
20582         break;
20583     }
20584   if (if_id == ~0)
20585     {
20586       errmsg ("missing pg interface index");
20587       return -99;
20588     }
20589   if (pcap_file_set > 0)
20590     {
20591       if (vec_len (pcap_file) > 255)
20592         {
20593           errmsg ("pcap file name is too long");
20594           return -99;
20595         }
20596     }
20597
20598   u32 name_len = vec_len (pcap_file);
20599   /* Construct the API message */
20600   M (PG_CAPTURE, mp);
20601   mp->context = 0;
20602   mp->interface_id = ntohl (if_id);
20603   mp->is_enabled = enable;
20604   mp->count = ntohl (count);
20605   mp->pcap_name_length = ntohl (name_len);
20606   if (pcap_file_set != 0)
20607     {
20608       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20609     }
20610   vec_free (pcap_file);
20611
20612   S (mp);
20613   W (ret);
20614   return ret;
20615 }
20616
20617 int
20618 api_pg_enable_disable (vat_main_t * vam)
20619 {
20620   unformat_input_t *input = vam->input;
20621   vl_api_pg_enable_disable_t *mp;
20622
20623   u8 enable = 1;
20624   u8 stream_name_set = 0;
20625   u8 *stream_name = 0;
20626   int ret;
20627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20628     {
20629       if (unformat (input, "stream %s", &stream_name))
20630         stream_name_set = 1;
20631       else if (unformat (input, "disable"))
20632         enable = 0;
20633       else
20634         break;
20635     }
20636
20637   if (stream_name_set > 0)
20638     {
20639       if (vec_len (stream_name) > 255)
20640         {
20641           errmsg ("stream name too long");
20642           return -99;
20643         }
20644     }
20645
20646   u32 name_len = vec_len (stream_name);
20647   /* Construct the API message */
20648   M (PG_ENABLE_DISABLE, mp);
20649   mp->context = 0;
20650   mp->is_enabled = enable;
20651   if (stream_name_set != 0)
20652     {
20653       mp->stream_name_length = ntohl (name_len);
20654       clib_memcpy (mp->stream_name, stream_name, name_len);
20655     }
20656   vec_free (stream_name);
20657
20658   S (mp);
20659   W (ret);
20660   return ret;
20661 }
20662
20663 int
20664 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20665 {
20666   unformat_input_t *input = vam->input;
20667   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20668
20669   u16 *low_ports = 0;
20670   u16 *high_ports = 0;
20671   u16 this_low;
20672   u16 this_hi;
20673   ip4_address_t ip4_addr;
20674   ip6_address_t ip6_addr;
20675   u32 length;
20676   u32 tmp, tmp2;
20677   u8 prefix_set = 0;
20678   u32 vrf_id = ~0;
20679   u8 is_add = 1;
20680   u8 is_ipv6 = 0;
20681   int ret;
20682
20683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20684     {
20685       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20686         {
20687           prefix_set = 1;
20688         }
20689       else
20690         if (unformat
20691             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20692         {
20693           prefix_set = 1;
20694           is_ipv6 = 1;
20695         }
20696       else if (unformat (input, "vrf %d", &vrf_id))
20697         ;
20698       else if (unformat (input, "del"))
20699         is_add = 0;
20700       else if (unformat (input, "port %d", &tmp))
20701         {
20702           if (tmp == 0 || tmp > 65535)
20703             {
20704               errmsg ("port %d out of range", tmp);
20705               return -99;
20706             }
20707           this_low = tmp;
20708           this_hi = this_low + 1;
20709           vec_add1 (low_ports, this_low);
20710           vec_add1 (high_ports, this_hi);
20711         }
20712       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20713         {
20714           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20715             {
20716               errmsg ("incorrect range parameters");
20717               return -99;
20718             }
20719           this_low = tmp;
20720           /* Note: in debug CLI +1 is added to high before
20721              passing to real fn that does "the work"
20722              (ip_source_and_port_range_check_add_del).
20723              This fn is a wrapper around the binary API fn a
20724              control plane will call, which expects this increment
20725              to have occurred. Hence letting the binary API control
20726              plane fn do the increment for consistency between VAT
20727              and other control planes.
20728            */
20729           this_hi = tmp2;
20730           vec_add1 (low_ports, this_low);
20731           vec_add1 (high_ports, this_hi);
20732         }
20733       else
20734         break;
20735     }
20736
20737   if (prefix_set == 0)
20738     {
20739       errmsg ("<address>/<mask> not specified");
20740       return -99;
20741     }
20742
20743   if (vrf_id == ~0)
20744     {
20745       errmsg ("VRF ID required, not specified");
20746       return -99;
20747     }
20748
20749   if (vrf_id == 0)
20750     {
20751       errmsg
20752         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20753       return -99;
20754     }
20755
20756   if (vec_len (low_ports) == 0)
20757     {
20758       errmsg ("At least one port or port range required");
20759       return -99;
20760     }
20761
20762   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20763
20764   mp->is_add = is_add;
20765
20766   if (is_ipv6)
20767     {
20768       mp->is_ipv6 = 1;
20769       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20770     }
20771   else
20772     {
20773       mp->is_ipv6 = 0;
20774       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20775     }
20776
20777   mp->mask_length = length;
20778   mp->number_of_ranges = vec_len (low_ports);
20779
20780   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20781   vec_free (low_ports);
20782
20783   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20784   vec_free (high_ports);
20785
20786   mp->vrf_id = ntohl (vrf_id);
20787
20788   S (mp);
20789   W (ret);
20790   return ret;
20791 }
20792
20793 int
20794 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20795 {
20796   unformat_input_t *input = vam->input;
20797   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20798   u32 sw_if_index = ~0;
20799   int vrf_set = 0;
20800   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20801   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20802   u8 is_add = 1;
20803   int ret;
20804
20805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20806     {
20807       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20808         ;
20809       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20810         ;
20811       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20812         vrf_set = 1;
20813       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20814         vrf_set = 1;
20815       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20816         vrf_set = 1;
20817       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20818         vrf_set = 1;
20819       else if (unformat (input, "del"))
20820         is_add = 0;
20821       else
20822         break;
20823     }
20824
20825   if (sw_if_index == ~0)
20826     {
20827       errmsg ("Interface required but not specified");
20828       return -99;
20829     }
20830
20831   if (vrf_set == 0)
20832     {
20833       errmsg ("VRF ID required but not specified");
20834       return -99;
20835     }
20836
20837   if (tcp_out_vrf_id == 0
20838       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20839     {
20840       errmsg
20841         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20842       return -99;
20843     }
20844
20845   /* Construct the API message */
20846   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20847
20848   mp->sw_if_index = ntohl (sw_if_index);
20849   mp->is_add = is_add;
20850   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20851   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20852   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20853   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20854
20855   /* send it... */
20856   S (mp);
20857
20858   /* Wait for a reply... */
20859   W (ret);
20860   return ret;
20861 }
20862
20863 static int
20864 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20865 {
20866   unformat_input_t *i = vam->input;
20867   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20868   u32 local_sa_id = 0;
20869   u32 remote_sa_id = 0;
20870   ip4_address_t src_address;
20871   ip4_address_t dst_address;
20872   u8 is_add = 1;
20873   int ret;
20874
20875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20876     {
20877       if (unformat (i, "local_sa %d", &local_sa_id))
20878         ;
20879       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20880         ;
20881       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20882         ;
20883       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20884         ;
20885       else if (unformat (i, "del"))
20886         is_add = 0;
20887       else
20888         {
20889           clib_warning ("parse error '%U'", format_unformat_error, i);
20890           return -99;
20891         }
20892     }
20893
20894   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20895
20896   mp->local_sa_id = ntohl (local_sa_id);
20897   mp->remote_sa_id = ntohl (remote_sa_id);
20898   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20899   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20900   mp->is_add = is_add;
20901
20902   S (mp);
20903   W (ret);
20904   return ret;
20905 }
20906
20907 static int
20908 api_punt (vat_main_t * vam)
20909 {
20910   unformat_input_t *i = vam->input;
20911   vl_api_punt_t *mp;
20912   u32 ipv = ~0;
20913   u32 protocol = ~0;
20914   u32 port = ~0;
20915   int is_add = 1;
20916   int ret;
20917
20918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20919     {
20920       if (unformat (i, "ip %d", &ipv))
20921         ;
20922       else if (unformat (i, "protocol %d", &protocol))
20923         ;
20924       else if (unformat (i, "port %d", &port))
20925         ;
20926       else if (unformat (i, "del"))
20927         is_add = 0;
20928       else
20929         {
20930           clib_warning ("parse error '%U'", format_unformat_error, i);
20931           return -99;
20932         }
20933     }
20934
20935   M (PUNT, mp);
20936
20937   mp->is_add = (u8) is_add;
20938   mp->ipv = (u8) ipv;
20939   mp->l4_protocol = (u8) protocol;
20940   mp->l4_port = htons ((u16) port);
20941
20942   S (mp);
20943   W (ret);
20944   return ret;
20945 }
20946
20947 static void vl_api_ipsec_gre_tunnel_details_t_handler
20948   (vl_api_ipsec_gre_tunnel_details_t * mp)
20949 {
20950   vat_main_t *vam = &vat_main;
20951
20952   print (vam->ofp, "%11d%15U%15U%14d%14d",
20953          ntohl (mp->sw_if_index),
20954          format_ip4_address, &mp->src_address,
20955          format_ip4_address, &mp->dst_address,
20956          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20957 }
20958
20959 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20960   (vl_api_ipsec_gre_tunnel_details_t * mp)
20961 {
20962   vat_main_t *vam = &vat_main;
20963   vat_json_node_t *node = NULL;
20964   struct in_addr ip4;
20965
20966   if (VAT_JSON_ARRAY != vam->json_tree.type)
20967     {
20968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20969       vat_json_init_array (&vam->json_tree);
20970     }
20971   node = vat_json_array_add (&vam->json_tree);
20972
20973   vat_json_init_object (node);
20974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20975   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20976   vat_json_object_add_ip4 (node, "src_address", ip4);
20977   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20978   vat_json_object_add_ip4 (node, "dst_address", ip4);
20979   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20980   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20981 }
20982
20983 static int
20984 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20985 {
20986   unformat_input_t *i = vam->input;
20987   vl_api_ipsec_gre_tunnel_dump_t *mp;
20988   vl_api_control_ping_t *mp_ping;
20989   u32 sw_if_index;
20990   u8 sw_if_index_set = 0;
20991   int ret;
20992
20993   /* Parse args required to build the message */
20994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (i, "sw_if_index %d", &sw_if_index))
20997         sw_if_index_set = 1;
20998       else
20999         break;
21000     }
21001
21002   if (sw_if_index_set == 0)
21003     {
21004       sw_if_index = ~0;
21005     }
21006
21007   if (!vam->json_output)
21008     {
21009       print (vam->ofp, "%11s%15s%15s%14s%14s",
21010              "sw_if_index", "src_address", "dst_address",
21011              "local_sa_id", "remote_sa_id");
21012     }
21013
21014   /* Get list of gre-tunnel interfaces */
21015   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21016
21017   mp->sw_if_index = htonl (sw_if_index);
21018
21019   S (mp);
21020
21021   /* Use a control ping for synchronization */
21022   MPING (CONTROL_PING, mp_ping);
21023   S (mp_ping);
21024
21025   W (ret);
21026   return ret;
21027 }
21028
21029 static int
21030 api_delete_subif (vat_main_t * vam)
21031 {
21032   unformat_input_t *i = vam->input;
21033   vl_api_delete_subif_t *mp;
21034   u32 sw_if_index = ~0;
21035   int ret;
21036
21037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21038     {
21039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21040         ;
21041       if (unformat (i, "sw_if_index %d", &sw_if_index))
21042         ;
21043       else
21044         break;
21045     }
21046
21047   if (sw_if_index == ~0)
21048     {
21049       errmsg ("missing sw_if_index");
21050       return -99;
21051     }
21052
21053   /* Construct the API message */
21054   M (DELETE_SUBIF, mp);
21055   mp->sw_if_index = ntohl (sw_if_index);
21056
21057   S (mp);
21058   W (ret);
21059   return ret;
21060 }
21061
21062 #define foreach_pbb_vtr_op      \
21063 _("disable",  L2_VTR_DISABLED)  \
21064 _("pop",  L2_VTR_POP_2)         \
21065 _("push",  L2_VTR_PUSH_2)
21066
21067 static int
21068 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21069 {
21070   unformat_input_t *i = vam->input;
21071   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21072   u32 sw_if_index = ~0, vtr_op = ~0;
21073   u16 outer_tag = ~0;
21074   u8 dmac[6], smac[6];
21075   u8 dmac_set = 0, smac_set = 0;
21076   u16 vlanid = 0;
21077   u32 sid = ~0;
21078   u32 tmp;
21079   int ret;
21080
21081   /* Shut up coverity */
21082   memset (dmac, 0, sizeof (dmac));
21083   memset (smac, 0, sizeof (smac));
21084
21085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21086     {
21087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21088         ;
21089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21090         ;
21091       else if (unformat (i, "vtr_op %d", &vtr_op))
21092         ;
21093 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21094       foreach_pbb_vtr_op
21095 #undef _
21096         else if (unformat (i, "translate_pbb_stag"))
21097         {
21098           if (unformat (i, "%d", &tmp))
21099             {
21100               vtr_op = L2_VTR_TRANSLATE_2_1;
21101               outer_tag = tmp;
21102             }
21103           else
21104             {
21105               errmsg
21106                 ("translate_pbb_stag operation requires outer tag definition");
21107               return -99;
21108             }
21109         }
21110       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21111         dmac_set++;
21112       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21113         smac_set++;
21114       else if (unformat (i, "sid %d", &sid))
21115         ;
21116       else if (unformat (i, "vlanid %d", &tmp))
21117         vlanid = tmp;
21118       else
21119         {
21120           clib_warning ("parse error '%U'", format_unformat_error, i);
21121           return -99;
21122         }
21123     }
21124
21125   if ((sw_if_index == ~0) || (vtr_op == ~0))
21126     {
21127       errmsg ("missing sw_if_index or vtr operation");
21128       return -99;
21129     }
21130   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21131       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21132     {
21133       errmsg
21134         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21135       return -99;
21136     }
21137
21138   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21139   mp->sw_if_index = ntohl (sw_if_index);
21140   mp->vtr_op = ntohl (vtr_op);
21141   mp->outer_tag = ntohs (outer_tag);
21142   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21143   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21144   mp->b_vlanid = ntohs (vlanid);
21145   mp->i_sid = ntohl (sid);
21146
21147   S (mp);
21148   W (ret);
21149   return ret;
21150 }
21151
21152 static int
21153 api_flow_classify_set_interface (vat_main_t * vam)
21154 {
21155   unformat_input_t *i = vam->input;
21156   vl_api_flow_classify_set_interface_t *mp;
21157   u32 sw_if_index;
21158   int sw_if_index_set;
21159   u32 ip4_table_index = ~0;
21160   u32 ip6_table_index = ~0;
21161   u8 is_add = 1;
21162   int ret;
21163
21164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21165     {
21166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21167         sw_if_index_set = 1;
21168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21169         sw_if_index_set = 1;
21170       else if (unformat (i, "del"))
21171         is_add = 0;
21172       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21173         ;
21174       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21175         ;
21176       else
21177         {
21178           clib_warning ("parse error '%U'", format_unformat_error, i);
21179           return -99;
21180         }
21181     }
21182
21183   if (sw_if_index_set == 0)
21184     {
21185       errmsg ("missing interface name or sw_if_index");
21186       return -99;
21187     }
21188
21189   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21190
21191   mp->sw_if_index = ntohl (sw_if_index);
21192   mp->ip4_table_index = ntohl (ip4_table_index);
21193   mp->ip6_table_index = ntohl (ip6_table_index);
21194   mp->is_add = is_add;
21195
21196   S (mp);
21197   W (ret);
21198   return ret;
21199 }
21200
21201 static int
21202 api_flow_classify_dump (vat_main_t * vam)
21203 {
21204   unformat_input_t *i = vam->input;
21205   vl_api_flow_classify_dump_t *mp;
21206   vl_api_control_ping_t *mp_ping;
21207   u8 type = FLOW_CLASSIFY_N_TABLES;
21208   int ret;
21209
21210   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21211     ;
21212   else
21213     {
21214       errmsg ("classify table type must be specified");
21215       return -99;
21216     }
21217
21218   if (!vam->json_output)
21219     {
21220       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21221     }
21222
21223   M (FLOW_CLASSIFY_DUMP, mp);
21224   mp->type = type;
21225   /* send it... */
21226   S (mp);
21227
21228   /* Use a control ping for synchronization */
21229   MPING (CONTROL_PING, mp_ping);
21230   S (mp_ping);
21231
21232   /* Wait for a reply... */
21233   W (ret);
21234   return ret;
21235 }
21236
21237 static int
21238 api_feature_enable_disable (vat_main_t * vam)
21239 {
21240   unformat_input_t *i = vam->input;
21241   vl_api_feature_enable_disable_t *mp;
21242   u8 *arc_name = 0;
21243   u8 *feature_name = 0;
21244   u32 sw_if_index = ~0;
21245   u8 enable = 1;
21246   int ret;
21247
21248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21249     {
21250       if (unformat (i, "arc_name %s", &arc_name))
21251         ;
21252       else if (unformat (i, "feature_name %s", &feature_name))
21253         ;
21254       else
21255         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21256         ;
21257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21258         ;
21259       else if (unformat (i, "disable"))
21260         enable = 0;
21261       else
21262         break;
21263     }
21264
21265   if (arc_name == 0)
21266     {
21267       errmsg ("missing arc name");
21268       return -99;
21269     }
21270   if (vec_len (arc_name) > 63)
21271     {
21272       errmsg ("arc name too long");
21273     }
21274
21275   if (feature_name == 0)
21276     {
21277       errmsg ("missing feature name");
21278       return -99;
21279     }
21280   if (vec_len (feature_name) > 63)
21281     {
21282       errmsg ("feature name too long");
21283     }
21284
21285   if (sw_if_index == ~0)
21286     {
21287       errmsg ("missing interface name or sw_if_index");
21288       return -99;
21289     }
21290
21291   /* Construct the API message */
21292   M (FEATURE_ENABLE_DISABLE, mp);
21293   mp->sw_if_index = ntohl (sw_if_index);
21294   mp->enable = enable;
21295   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21296   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21297   vec_free (arc_name);
21298   vec_free (feature_name);
21299
21300   S (mp);
21301   W (ret);
21302   return ret;
21303 }
21304
21305 static int
21306 api_sw_interface_tag_add_del (vat_main_t * vam)
21307 {
21308   unformat_input_t *i = vam->input;
21309   vl_api_sw_interface_tag_add_del_t *mp;
21310   u32 sw_if_index = ~0;
21311   u8 *tag = 0;
21312   u8 enable = 1;
21313   int ret;
21314
21315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21316     {
21317       if (unformat (i, "tag %s", &tag))
21318         ;
21319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21320         ;
21321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21322         ;
21323       else if (unformat (i, "del"))
21324         enable = 0;
21325       else
21326         break;
21327     }
21328
21329   if (sw_if_index == ~0)
21330     {
21331       errmsg ("missing interface name or sw_if_index");
21332       return -99;
21333     }
21334
21335   if (enable && (tag == 0))
21336     {
21337       errmsg ("no tag specified");
21338       return -99;
21339     }
21340
21341   /* Construct the API message */
21342   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21343   mp->sw_if_index = ntohl (sw_if_index);
21344   mp->is_add = enable;
21345   if (enable)
21346     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21347   vec_free (tag);
21348
21349   S (mp);
21350   W (ret);
21351   return ret;
21352 }
21353
21354 static void vl_api_l2_xconnect_details_t_handler
21355   (vl_api_l2_xconnect_details_t * mp)
21356 {
21357   vat_main_t *vam = &vat_main;
21358
21359   print (vam->ofp, "%15d%15d",
21360          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21361 }
21362
21363 static void vl_api_l2_xconnect_details_t_handler_json
21364   (vl_api_l2_xconnect_details_t * mp)
21365 {
21366   vat_main_t *vam = &vat_main;
21367   vat_json_node_t *node = NULL;
21368
21369   if (VAT_JSON_ARRAY != vam->json_tree.type)
21370     {
21371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21372       vat_json_init_array (&vam->json_tree);
21373     }
21374   node = vat_json_array_add (&vam->json_tree);
21375
21376   vat_json_init_object (node);
21377   vat_json_object_add_uint (node, "rx_sw_if_index",
21378                             ntohl (mp->rx_sw_if_index));
21379   vat_json_object_add_uint (node, "tx_sw_if_index",
21380                             ntohl (mp->tx_sw_if_index));
21381 }
21382
21383 static int
21384 api_l2_xconnect_dump (vat_main_t * vam)
21385 {
21386   vl_api_l2_xconnect_dump_t *mp;
21387   vl_api_control_ping_t *mp_ping;
21388   int ret;
21389
21390   if (!vam->json_output)
21391     {
21392       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21393     }
21394
21395   M (L2_XCONNECT_DUMP, mp);
21396
21397   S (mp);
21398
21399   /* Use a control ping for synchronization */
21400   MPING (CONTROL_PING, mp_ping);
21401   S (mp_ping);
21402
21403   W (ret);
21404   return ret;
21405 }
21406
21407 static int
21408 api_sw_interface_set_mtu (vat_main_t * vam)
21409 {
21410   unformat_input_t *i = vam->input;
21411   vl_api_sw_interface_set_mtu_t *mp;
21412   u32 sw_if_index = ~0;
21413   u32 mtu = 0;
21414   int ret;
21415
21416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21417     {
21418       if (unformat (i, "mtu %d", &mtu))
21419         ;
21420       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21421         ;
21422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21423         ;
21424       else
21425         break;
21426     }
21427
21428   if (sw_if_index == ~0)
21429     {
21430       errmsg ("missing interface name or sw_if_index");
21431       return -99;
21432     }
21433
21434   if (mtu == 0)
21435     {
21436       errmsg ("no mtu specified");
21437       return -99;
21438     }
21439
21440   /* Construct the API message */
21441   M (SW_INTERFACE_SET_MTU, mp);
21442   mp->sw_if_index = ntohl (sw_if_index);
21443   mp->mtu = ntohs ((u16) mtu);
21444
21445   S (mp);
21446   W (ret);
21447   return ret;
21448 }
21449
21450 static int
21451 api_p2p_ethernet_add (vat_main_t * vam)
21452 {
21453   unformat_input_t *i = vam->input;
21454   vl_api_p2p_ethernet_add_t *mp;
21455   u32 parent_if_index = ~0;
21456   u32 sub_id = ~0;
21457   u8 remote_mac[6];
21458   u8 mac_set = 0;
21459   int ret;
21460
21461   memset (remote_mac, 0, sizeof (remote_mac));
21462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21463     {
21464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21465         ;
21466       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21467         ;
21468       else
21469         if (unformat
21470             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21471         mac_set++;
21472       else if (unformat (i, "sub_id %d", &sub_id))
21473         ;
21474       else
21475         {
21476           clib_warning ("parse error '%U'", format_unformat_error, i);
21477           return -99;
21478         }
21479     }
21480
21481   if (parent_if_index == ~0)
21482     {
21483       errmsg ("missing interface name or sw_if_index");
21484       return -99;
21485     }
21486   if (mac_set == 0)
21487     {
21488       errmsg ("missing remote mac address");
21489       return -99;
21490     }
21491   if (sub_id == ~0)
21492     {
21493       errmsg ("missing sub-interface id");
21494       return -99;
21495     }
21496
21497   M (P2P_ETHERNET_ADD, mp);
21498   mp->parent_if_index = ntohl (parent_if_index);
21499   mp->subif_id = ntohl (sub_id);
21500   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21501
21502   S (mp);
21503   W (ret);
21504   return ret;
21505 }
21506
21507 static int
21508 api_p2p_ethernet_del (vat_main_t * vam)
21509 {
21510   unformat_input_t *i = vam->input;
21511   vl_api_p2p_ethernet_del_t *mp;
21512   u32 parent_if_index = ~0;
21513   u8 remote_mac[6];
21514   u8 mac_set = 0;
21515   int ret;
21516
21517   memset (remote_mac, 0, sizeof (remote_mac));
21518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21519     {
21520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21521         ;
21522       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21523         ;
21524       else
21525         if (unformat
21526             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21527         mac_set++;
21528       else
21529         {
21530           clib_warning ("parse error '%U'", format_unformat_error, i);
21531           return -99;
21532         }
21533     }
21534
21535   if (parent_if_index == ~0)
21536     {
21537       errmsg ("missing interface name or sw_if_index");
21538       return -99;
21539     }
21540   if (mac_set == 0)
21541     {
21542       errmsg ("missing remote mac address");
21543       return -99;
21544     }
21545
21546   M (P2P_ETHERNET_DEL, mp);
21547   mp->parent_if_index = ntohl (parent_if_index);
21548   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21549
21550   S (mp);
21551   W (ret);
21552   return ret;
21553 }
21554
21555 static int
21556 api_lldp_config (vat_main_t * vam)
21557 {
21558   unformat_input_t *i = vam->input;
21559   vl_api_lldp_config_t *mp;
21560   int tx_hold = 0;
21561   int tx_interval = 0;
21562   u8 *sys_name = NULL;
21563   int ret;
21564
21565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21566     {
21567       if (unformat (i, "system-name %s", &sys_name))
21568         ;
21569       else if (unformat (i, "tx-hold %d", &tx_hold))
21570         ;
21571       else if (unformat (i, "tx-interval %d", &tx_interval))
21572         ;
21573       else
21574         {
21575           clib_warning ("parse error '%U'", format_unformat_error, i);
21576           return -99;
21577         }
21578     }
21579
21580   vec_add1 (sys_name, 0);
21581
21582   M (LLDP_CONFIG, mp);
21583   mp->tx_hold = htonl (tx_hold);
21584   mp->tx_interval = htonl (tx_interval);
21585   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21586   vec_free (sys_name);
21587
21588   S (mp);
21589   W (ret);
21590   return ret;
21591 }
21592
21593 static int
21594 api_sw_interface_set_lldp (vat_main_t * vam)
21595 {
21596   unformat_input_t *i = vam->input;
21597   vl_api_sw_interface_set_lldp_t *mp;
21598   u32 sw_if_index = ~0;
21599   u32 enable = 1;
21600   u8 *port_desc = NULL, *mgmt_oid = NULL;
21601   ip4_address_t ip4_addr;
21602   ip6_address_t ip6_addr;
21603   int ret;
21604
21605   memset (&ip4_addr, 0, sizeof (ip4_addr));
21606   memset (&ip6_addr, 0, sizeof (ip6_addr));
21607
21608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21609     {
21610       if (unformat (i, "disable"))
21611         enable = 0;
21612       else
21613         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21614         ;
21615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21616         ;
21617       else if (unformat (i, "port-desc %s", &port_desc))
21618         ;
21619       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21620         ;
21621       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21622         ;
21623       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21624         ;
21625       else
21626         break;
21627     }
21628
21629   if (sw_if_index == ~0)
21630     {
21631       errmsg ("missing interface name or sw_if_index");
21632       return -99;
21633     }
21634
21635   /* Construct the API message */
21636   vec_add1 (port_desc, 0);
21637   vec_add1 (mgmt_oid, 0);
21638   M (SW_INTERFACE_SET_LLDP, mp);
21639   mp->sw_if_index = ntohl (sw_if_index);
21640   mp->enable = enable;
21641   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21642   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21643   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21644   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21645   vec_free (port_desc);
21646   vec_free (mgmt_oid);
21647
21648   S (mp);
21649   W (ret);
21650   return ret;
21651 }
21652
21653 static int
21654 api_tcp_configure_src_addresses (vat_main_t * vam)
21655 {
21656   vl_api_tcp_configure_src_addresses_t *mp;
21657   unformat_input_t *i = vam->input;
21658   ip4_address_t v4first, v4last;
21659   ip6_address_t v6first, v6last;
21660   u8 range_set = 0;
21661   u32 vrf_id = 0;
21662   int ret;
21663
21664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21665     {
21666       if (unformat (i, "%U - %U",
21667                     unformat_ip4_address, &v4first,
21668                     unformat_ip4_address, &v4last))
21669         {
21670           if (range_set)
21671             {
21672               errmsg ("one range per message (range already set)");
21673               return -99;
21674             }
21675           range_set = 1;
21676         }
21677       else if (unformat (i, "%U - %U",
21678                          unformat_ip6_address, &v6first,
21679                          unformat_ip6_address, &v6last))
21680         {
21681           if (range_set)
21682             {
21683               errmsg ("one range per message (range already set)");
21684               return -99;
21685             }
21686           range_set = 2;
21687         }
21688       else if (unformat (i, "vrf %d", &vrf_id))
21689         ;
21690       else
21691         break;
21692     }
21693
21694   if (range_set == 0)
21695     {
21696       errmsg ("address range not set");
21697       return -99;
21698     }
21699
21700   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21701   mp->vrf_id = ntohl (vrf_id);
21702   /* ipv6? */
21703   if (range_set == 2)
21704     {
21705       mp->is_ipv6 = 1;
21706       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21707       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21708     }
21709   else
21710     {
21711       mp->is_ipv6 = 0;
21712       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21713       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21714     }
21715   S (mp);
21716   W (ret);
21717   return ret;
21718 }
21719
21720 static void vl_api_app_namespace_add_del_reply_t_handler
21721   (vl_api_app_namespace_add_del_reply_t * mp)
21722 {
21723   vat_main_t *vam = &vat_main;
21724   i32 retval = ntohl (mp->retval);
21725   if (vam->async_mode)
21726     {
21727       vam->async_errors += (retval < 0);
21728     }
21729   else
21730     {
21731       vam->retval = retval;
21732       if (retval == 0)
21733         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21734       vam->result_ready = 1;
21735     }
21736 }
21737
21738 static void vl_api_app_namespace_add_del_reply_t_handler_json
21739   (vl_api_app_namespace_add_del_reply_t * mp)
21740 {
21741   vat_main_t *vam = &vat_main;
21742   vat_json_node_t node;
21743
21744   vat_json_init_object (&node);
21745   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21746   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21747
21748   vat_json_print (vam->ofp, &node);
21749   vat_json_free (&node);
21750
21751   vam->retval = ntohl (mp->retval);
21752   vam->result_ready = 1;
21753 }
21754
21755 static int
21756 api_app_namespace_add_del (vat_main_t * vam)
21757 {
21758   vl_api_app_namespace_add_del_t *mp;
21759   unformat_input_t *i = vam->input;
21760   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21761   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21762   u64 secret;
21763   int ret;
21764
21765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21766     {
21767       if (unformat (i, "id %_%v%_", &ns_id))
21768         ;
21769       else if (unformat (i, "secret %lu", &secret))
21770         secret_set = 1;
21771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21772         sw_if_index_set = 1;
21773       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21774         ;
21775       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21776         ;
21777       else
21778         break;
21779     }
21780   if (!ns_id || !secret_set || !sw_if_index_set)
21781     {
21782       errmsg ("namespace id, secret and sw_if_index must be set");
21783       return -99;
21784     }
21785   if (vec_len (ns_id) > 64)
21786     {
21787       errmsg ("namespace id too long");
21788       return -99;
21789     }
21790   M (APP_NAMESPACE_ADD_DEL, mp);
21791
21792   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21793   mp->namespace_id_len = vec_len (ns_id);
21794   mp->secret = clib_host_to_net_u64 (secret);
21795   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21796   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21797   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21798   vec_free (ns_id);
21799   S (mp);
21800   W (ret);
21801   return ret;
21802 }
21803
21804 static int
21805 api_memfd_segment_create (vat_main_t * vam)
21806 {
21807 #if VPP_API_TEST_BUILTIN == 0
21808   unformat_input_t *i = vam->input;
21809   vl_api_memfd_segment_create_t *mp;
21810   u64 size = 64 << 20;
21811   int ret;
21812
21813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21814     {
21815       if (unformat (i, "size %U", unformat_memory_size, &size))
21816         ;
21817       else
21818         break;
21819     }
21820
21821   M (MEMFD_SEGMENT_CREATE, mp);
21822   mp->requested_size = size;
21823   S (mp);
21824   W (ret);
21825   return ret;
21826
21827 #else
21828   errmsg ("memfd_segment_create (builtin) not supported");
21829   return -99;
21830 #endif
21831 }
21832
21833 static int
21834 api_dns_enable_disable (vat_main_t * vam)
21835 {
21836   unformat_input_t *line_input = vam->input;
21837   vl_api_dns_enable_disable_t *mp;
21838   u8 enable_disable = 1;
21839   int ret;
21840
21841   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21842     {
21843       if (unformat (line_input, "disable"))
21844         enable_disable = 0;
21845       if (unformat (line_input, "enable"))
21846         enable_disable = 1;
21847       else
21848         break;
21849     }
21850
21851   /* Construct the API message */
21852   M (DNS_ENABLE_DISABLE, mp);
21853   mp->enable = enable_disable;
21854
21855   /* send it... */
21856   S (mp);
21857   /* Wait for the reply */
21858   W (ret);
21859   return ret;
21860 }
21861
21862 static int
21863 api_dns_resolve_name (vat_main_t * vam)
21864 {
21865   unformat_input_t *line_input = vam->input;
21866   vl_api_dns_resolve_name_t *mp;
21867   u8 *name = 0;
21868   int ret;
21869
21870   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21871     {
21872       if (unformat (line_input, "%s", &name))
21873         ;
21874       else
21875         break;
21876     }
21877
21878   if (vec_len (name) > 127)
21879     {
21880       errmsg ("name too long");
21881       return -99;
21882     }
21883
21884   /* Construct the API message */
21885   M (DNS_RESOLVE_NAME, mp);
21886   memcpy (mp->name, name, vec_len (name));
21887   vec_free (name);
21888
21889   /* send it... */
21890   S (mp);
21891   /* Wait for the reply */
21892   W (ret);
21893   return ret;
21894 }
21895
21896 static int
21897 api_dns_resolve_ip (vat_main_t * vam)
21898 {
21899   unformat_input_t *line_input = vam->input;
21900   vl_api_dns_resolve_ip_t *mp;
21901   int is_ip6 = -1;
21902   ip4_address_t addr4;
21903   ip6_address_t addr6;
21904   int ret;
21905
21906   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21907     {
21908       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21909         is_ip6 = 1;
21910       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21911         is_ip6 = 0;
21912       else
21913         break;
21914     }
21915
21916   if (is_ip6 == -1)
21917     {
21918       errmsg ("missing address");
21919       return -99;
21920     }
21921
21922   /* Construct the API message */
21923   M (DNS_RESOLVE_IP, mp);
21924   mp->is_ip6 = is_ip6;
21925   if (is_ip6)
21926     memcpy (mp->address, &addr6, sizeof (addr6));
21927   else
21928     memcpy (mp->address, &addr4, sizeof (addr4));
21929
21930   /* send it... */
21931   S (mp);
21932   /* Wait for the reply */
21933   W (ret);
21934   return ret;
21935 }
21936
21937 static int
21938 api_dns_name_server_add_del (vat_main_t * vam)
21939 {
21940   unformat_input_t *i = vam->input;
21941   vl_api_dns_name_server_add_del_t *mp;
21942   u8 is_add = 1;
21943   ip6_address_t ip6_server;
21944   ip4_address_t ip4_server;
21945   int ip6_set = 0;
21946   int ip4_set = 0;
21947   int ret = 0;
21948
21949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21950     {
21951       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21952         ip6_set = 1;
21953       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21954         ip4_set = 1;
21955       else if (unformat (i, "del"))
21956         is_add = 0;
21957       else
21958         {
21959           clib_warning ("parse error '%U'", format_unformat_error, i);
21960           return -99;
21961         }
21962     }
21963
21964   if (ip4_set && ip6_set)
21965     {
21966       errmsg ("Only one server address allowed per message");
21967       return -99;
21968     }
21969   if ((ip4_set + ip6_set) == 0)
21970     {
21971       errmsg ("Server address required");
21972       return -99;
21973     }
21974
21975   /* Construct the API message */
21976   M (DNS_NAME_SERVER_ADD_DEL, mp);
21977
21978   if (ip6_set)
21979     {
21980       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21981       mp->is_ip6 = 1;
21982     }
21983   else
21984     {
21985       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21986       mp->is_ip6 = 0;
21987     }
21988
21989   mp->is_add = is_add;
21990
21991   /* send it... */
21992   S (mp);
21993
21994   /* Wait for a reply, return good/bad news  */
21995   W (ret);
21996   return ret;
21997 }
21998
21999 static void
22000 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22001 {
22002   vat_main_t *vam = &vat_main;
22003
22004   if (mp->is_ip4)
22005     {
22006       print (vam->ofp,
22007              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22008              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22009              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22010              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22011              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22012              clib_net_to_host_u32 (mp->action_index), mp->tag);
22013     }
22014   else
22015     {
22016       print (vam->ofp,
22017              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22018              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22019              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22020              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22021              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22022              clib_net_to_host_u32 (mp->action_index), mp->tag);
22023     }
22024 }
22025
22026 static void
22027 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22028                                              mp)
22029 {
22030   vat_main_t *vam = &vat_main;
22031   vat_json_node_t *node = NULL;
22032   struct in6_addr ip6;
22033   struct in_addr ip4;
22034
22035   if (VAT_JSON_ARRAY != vam->json_tree.type)
22036     {
22037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22038       vat_json_init_array (&vam->json_tree);
22039     }
22040   node = vat_json_array_add (&vam->json_tree);
22041   vat_json_init_object (node);
22042
22043   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22044   vat_json_object_add_uint (node, "appns_index",
22045                             clib_net_to_host_u32 (mp->appns_index));
22046   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22047   vat_json_object_add_uint (node, "scope", mp->scope);
22048   vat_json_object_add_uint (node, "action_index",
22049                             clib_net_to_host_u32 (mp->action_index));
22050   vat_json_object_add_uint (node, "lcl_port",
22051                             clib_net_to_host_u16 (mp->lcl_port));
22052   vat_json_object_add_uint (node, "rmt_port",
22053                             clib_net_to_host_u16 (mp->rmt_port));
22054   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22055   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22056   vat_json_object_add_string_copy (node, "tag", mp->tag);
22057   if (mp->is_ip4)
22058     {
22059       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22060       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22061       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22062       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22063     }
22064   else
22065     {
22066       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22067       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22068       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22069       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22070     }
22071 }
22072
22073 static int
22074 api_session_rule_add_del (vat_main_t * vam)
22075 {
22076   vl_api_session_rule_add_del_t *mp;
22077   unformat_input_t *i = vam->input;
22078   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22079   u32 appns_index = 0, scope = 0;
22080   ip4_address_t lcl_ip4, rmt_ip4;
22081   ip6_address_t lcl_ip6, rmt_ip6;
22082   u8 is_ip4 = 1, conn_set = 0;
22083   u8 is_add = 1, *tag = 0;
22084   int ret;
22085
22086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22087     {
22088       if (unformat (i, "del"))
22089         is_add = 0;
22090       else if (unformat (i, "add"))
22091         ;
22092       else if (unformat (i, "proto tcp"))
22093         proto = 0;
22094       else if (unformat (i, "proto udp"))
22095         proto = 1;
22096       else if (unformat (i, "appns %d", &appns_index))
22097         ;
22098       else if (unformat (i, "scope %d", &scope))
22099         ;
22100       else if (unformat (i, "tag %_%v%_", &tag))
22101         ;
22102       else
22103         if (unformat
22104             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22105              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22106              &rmt_port))
22107         {
22108           is_ip4 = 1;
22109           conn_set = 1;
22110         }
22111       else
22112         if (unformat
22113             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22114              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22115              &rmt_port))
22116         {
22117           is_ip4 = 0;
22118           conn_set = 1;
22119         }
22120       else if (unformat (i, "action %d", &action))
22121         ;
22122       else
22123         break;
22124     }
22125   if (proto == ~0 || !conn_set || action == ~0)
22126     {
22127       errmsg ("transport proto, connection and action must be set");
22128       return -99;
22129     }
22130
22131   if (scope > 3)
22132     {
22133       errmsg ("scope should be 0-3");
22134       return -99;
22135     }
22136
22137   M (SESSION_RULE_ADD_DEL, mp);
22138
22139   mp->is_ip4 = is_ip4;
22140   mp->transport_proto = proto;
22141   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22142   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22143   mp->lcl_plen = lcl_plen;
22144   mp->rmt_plen = rmt_plen;
22145   mp->action_index = clib_host_to_net_u32 (action);
22146   mp->appns_index = clib_host_to_net_u32 (appns_index);
22147   mp->scope = scope;
22148   mp->is_add = is_add;
22149   if (is_ip4)
22150     {
22151       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22152       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22153     }
22154   else
22155     {
22156       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22157       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22158     }
22159   if (tag)
22160     {
22161       clib_memcpy (mp->tag, tag, vec_len (tag));
22162       vec_free (tag);
22163     }
22164
22165   S (mp);
22166   W (ret);
22167   return ret;
22168 }
22169
22170 static int
22171 api_session_rules_dump (vat_main_t * vam)
22172 {
22173   vl_api_session_rules_dump_t *mp;
22174   vl_api_control_ping_t *mp_ping;
22175   int ret;
22176
22177   if (!vam->json_output)
22178     {
22179       print (vam->ofp, "%=20s", "Session Rules");
22180     }
22181
22182   M (SESSION_RULES_DUMP, mp);
22183   /* send it... */
22184   S (mp);
22185
22186   /* Use a control ping for synchronization */
22187   MPING (CONTROL_PING, mp_ping);
22188   S (mp_ping);
22189
22190   /* Wait for a reply... */
22191   W (ret);
22192   return ret;
22193 }
22194
22195 static int
22196 api_ip_container_proxy_add_del (vat_main_t * vam)
22197 {
22198   vl_api_ip_container_proxy_add_del_t *mp;
22199   unformat_input_t *i = vam->input;
22200   u32 plen = ~0, sw_if_index = ~0;
22201   ip4_address_t ip4;
22202   ip6_address_t ip6;
22203   u8 is_ip4 = 1;
22204   u8 is_add = 1;
22205   int ret;
22206
22207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22208     {
22209       if (unformat (i, "del"))
22210         is_add = 0;
22211       else if (unformat (i, "add"))
22212         ;
22213       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22214         {
22215           is_ip4 = 1;
22216           plen = 32;
22217         }
22218       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22219         {
22220           is_ip4 = 0;
22221           plen = 128;
22222         }
22223       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22224         ;
22225       else
22226         break;
22227     }
22228   if (sw_if_index == ~0 || plen == ~0)
22229     {
22230       errmsg ("address and sw_if_index must be set");
22231       return -99;
22232     }
22233
22234   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22235
22236   mp->is_ip4 = is_ip4;
22237   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22238   mp->plen = plen;
22239   mp->is_add = is_add;
22240   if (is_ip4)
22241     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22242   else
22243     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22244
22245   S (mp);
22246   W (ret);
22247   return ret;
22248 }
22249
22250 static int
22251 q_or_quit (vat_main_t * vam)
22252 {
22253 #if VPP_API_TEST_BUILTIN == 0
22254   longjmp (vam->jump_buf, 1);
22255 #endif
22256   return 0;                     /* not so much */
22257 }
22258
22259 static int
22260 q (vat_main_t * vam)
22261 {
22262   return q_or_quit (vam);
22263 }
22264
22265 static int
22266 quit (vat_main_t * vam)
22267 {
22268   return q_or_quit (vam);
22269 }
22270
22271 static int
22272 comment (vat_main_t * vam)
22273 {
22274   return 0;
22275 }
22276
22277 static int
22278 cmd_cmp (void *a1, void *a2)
22279 {
22280   u8 **c1 = a1;
22281   u8 **c2 = a2;
22282
22283   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22284 }
22285
22286 static int
22287 help (vat_main_t * vam)
22288 {
22289   u8 **cmds = 0;
22290   u8 *name = 0;
22291   hash_pair_t *p;
22292   unformat_input_t *i = vam->input;
22293   int j;
22294
22295   if (unformat (i, "%s", &name))
22296     {
22297       uword *hs;
22298
22299       vec_add1 (name, 0);
22300
22301       hs = hash_get_mem (vam->help_by_name, name);
22302       if (hs)
22303         print (vam->ofp, "usage: %s %s", name, hs[0]);
22304       else
22305         print (vam->ofp, "No such msg / command '%s'", name);
22306       vec_free (name);
22307       return 0;
22308     }
22309
22310   print (vam->ofp, "Help is available for the following:");
22311
22312     /* *INDENT-OFF* */
22313     hash_foreach_pair (p, vam->function_by_name,
22314     ({
22315       vec_add1 (cmds, (u8 *)(p->key));
22316     }));
22317     /* *INDENT-ON* */
22318
22319   vec_sort_with_function (cmds, cmd_cmp);
22320
22321   for (j = 0; j < vec_len (cmds); j++)
22322     print (vam->ofp, "%s", cmds[j]);
22323
22324   vec_free (cmds);
22325   return 0;
22326 }
22327
22328 static int
22329 set (vat_main_t * vam)
22330 {
22331   u8 *name = 0, *value = 0;
22332   unformat_input_t *i = vam->input;
22333
22334   if (unformat (i, "%s", &name))
22335     {
22336       /* The input buffer is a vector, not a string. */
22337       value = vec_dup (i->buffer);
22338       vec_delete (value, i->index, 0);
22339       /* Almost certainly has a trailing newline */
22340       if (value[vec_len (value) - 1] == '\n')
22341         value[vec_len (value) - 1] = 0;
22342       /* Make sure it's a proper string, one way or the other */
22343       vec_add1 (value, 0);
22344       (void) clib_macro_set_value (&vam->macro_main,
22345                                    (char *) name, (char *) value);
22346     }
22347   else
22348     errmsg ("usage: set <name> <value>");
22349
22350   vec_free (name);
22351   vec_free (value);
22352   return 0;
22353 }
22354
22355 static int
22356 unset (vat_main_t * vam)
22357 {
22358   u8 *name = 0;
22359
22360   if (unformat (vam->input, "%s", &name))
22361     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22362       errmsg ("unset: %s wasn't set", name);
22363   vec_free (name);
22364   return 0;
22365 }
22366
22367 typedef struct
22368 {
22369   u8 *name;
22370   u8 *value;
22371 } macro_sort_t;
22372
22373
22374 static int
22375 macro_sort_cmp (void *a1, void *a2)
22376 {
22377   macro_sort_t *s1 = a1;
22378   macro_sort_t *s2 = a2;
22379
22380   return strcmp ((char *) (s1->name), (char *) (s2->name));
22381 }
22382
22383 static int
22384 dump_macro_table (vat_main_t * vam)
22385 {
22386   macro_sort_t *sort_me = 0, *sm;
22387   int i;
22388   hash_pair_t *p;
22389
22390     /* *INDENT-OFF* */
22391     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22392     ({
22393       vec_add2 (sort_me, sm, 1);
22394       sm->name = (u8 *)(p->key);
22395       sm->value = (u8 *) (p->value[0]);
22396     }));
22397     /* *INDENT-ON* */
22398
22399   vec_sort_with_function (sort_me, macro_sort_cmp);
22400
22401   if (vec_len (sort_me))
22402     print (vam->ofp, "%-15s%s", "Name", "Value");
22403   else
22404     print (vam->ofp, "The macro table is empty...");
22405
22406   for (i = 0; i < vec_len (sort_me); i++)
22407     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22408   return 0;
22409 }
22410
22411 static int
22412 dump_node_table (vat_main_t * vam)
22413 {
22414   int i, j;
22415   vlib_node_t *node, *next_node;
22416
22417   if (vec_len (vam->graph_nodes) == 0)
22418     {
22419       print (vam->ofp, "Node table empty, issue get_node_graph...");
22420       return 0;
22421     }
22422
22423   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22424     {
22425       node = vam->graph_nodes[i];
22426       print (vam->ofp, "[%d] %s", i, node->name);
22427       for (j = 0; j < vec_len (node->next_nodes); j++)
22428         {
22429           if (node->next_nodes[j] != ~0)
22430             {
22431               next_node = vam->graph_nodes[node->next_nodes[j]];
22432               print (vam->ofp, "  [%d] %s", j, next_node->name);
22433             }
22434         }
22435     }
22436   return 0;
22437 }
22438
22439 static int
22440 value_sort_cmp (void *a1, void *a2)
22441 {
22442   name_sort_t *n1 = a1;
22443   name_sort_t *n2 = a2;
22444
22445   if (n1->value < n2->value)
22446     return -1;
22447   if (n1->value > n2->value)
22448     return 1;
22449   return 0;
22450 }
22451
22452
22453 static int
22454 dump_msg_api_table (vat_main_t * vam)
22455 {
22456   api_main_t *am = &api_main;
22457   name_sort_t *nses = 0, *ns;
22458   hash_pair_t *hp;
22459   int i;
22460
22461   /* *INDENT-OFF* */
22462   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22463   ({
22464     vec_add2 (nses, ns, 1);
22465     ns->name = (u8 *)(hp->key);
22466     ns->value = (u32) hp->value[0];
22467   }));
22468   /* *INDENT-ON* */
22469
22470   vec_sort_with_function (nses, value_sort_cmp);
22471
22472   for (i = 0; i < vec_len (nses); i++)
22473     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22474   vec_free (nses);
22475   return 0;
22476 }
22477
22478 static int
22479 get_msg_id (vat_main_t * vam)
22480 {
22481   u8 *name_and_crc;
22482   u32 message_index;
22483
22484   if (unformat (vam->input, "%s", &name_and_crc))
22485     {
22486       message_index = vl_api_get_msg_index (name_and_crc);
22487       if (message_index == ~0)
22488         {
22489           print (vam->ofp, " '%s' not found", name_and_crc);
22490           return 0;
22491         }
22492       print (vam->ofp, " '%s' has message index %d",
22493              name_and_crc, message_index);
22494       return 0;
22495     }
22496   errmsg ("name_and_crc required...");
22497   return 0;
22498 }
22499
22500 static int
22501 search_node_table (vat_main_t * vam)
22502 {
22503   unformat_input_t *line_input = vam->input;
22504   u8 *node_to_find;
22505   int j;
22506   vlib_node_t *node, *next_node;
22507   uword *p;
22508
22509   if (vam->graph_node_index_by_name == 0)
22510     {
22511       print (vam->ofp, "Node table empty, issue get_node_graph...");
22512       return 0;
22513     }
22514
22515   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22516     {
22517       if (unformat (line_input, "%s", &node_to_find))
22518         {
22519           vec_add1 (node_to_find, 0);
22520           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22521           if (p == 0)
22522             {
22523               print (vam->ofp, "%s not found...", node_to_find);
22524               goto out;
22525             }
22526           node = vam->graph_nodes[p[0]];
22527           print (vam->ofp, "[%d] %s", p[0], node->name);
22528           for (j = 0; j < vec_len (node->next_nodes); j++)
22529             {
22530               if (node->next_nodes[j] != ~0)
22531                 {
22532                   next_node = vam->graph_nodes[node->next_nodes[j]];
22533                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22534                 }
22535             }
22536         }
22537
22538       else
22539         {
22540           clib_warning ("parse error '%U'", format_unformat_error,
22541                         line_input);
22542           return -99;
22543         }
22544
22545     out:
22546       vec_free (node_to_find);
22547
22548     }
22549
22550   return 0;
22551 }
22552
22553
22554 static int
22555 script (vat_main_t * vam)
22556 {
22557 #if (VPP_API_TEST_BUILTIN==0)
22558   u8 *s = 0;
22559   char *save_current_file;
22560   unformat_input_t save_input;
22561   jmp_buf save_jump_buf;
22562   u32 save_line_number;
22563
22564   FILE *new_fp, *save_ifp;
22565
22566   if (unformat (vam->input, "%s", &s))
22567     {
22568       new_fp = fopen ((char *) s, "r");
22569       if (new_fp == 0)
22570         {
22571           errmsg ("Couldn't open script file %s", s);
22572           vec_free (s);
22573           return -99;
22574         }
22575     }
22576   else
22577     {
22578       errmsg ("Missing script name");
22579       return -99;
22580     }
22581
22582   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22583   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22584   save_ifp = vam->ifp;
22585   save_line_number = vam->input_line_number;
22586   save_current_file = (char *) vam->current_file;
22587
22588   vam->input_line_number = 0;
22589   vam->ifp = new_fp;
22590   vam->current_file = s;
22591   do_one_file (vam);
22592
22593   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22594   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22595   vam->ifp = save_ifp;
22596   vam->input_line_number = save_line_number;
22597   vam->current_file = (u8 *) save_current_file;
22598   vec_free (s);
22599
22600   return 0;
22601 #else
22602   clib_warning ("use the exec command...");
22603   return -99;
22604 #endif
22605 }
22606
22607 static int
22608 echo (vat_main_t * vam)
22609 {
22610   print (vam->ofp, "%v", vam->input->buffer);
22611   return 0;
22612 }
22613
22614 /* List of API message constructors, CLI names map to api_xxx */
22615 #define foreach_vpe_api_msg                                             \
22616 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22617 _(sw_interface_dump,"")                                                 \
22618 _(sw_interface_set_flags,                                               \
22619   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22620 _(sw_interface_add_del_address,                                         \
22621   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22622 _(sw_interface_set_rx_mode,                                             \
22623   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22624 _(sw_interface_set_table,                                               \
22625   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22626 _(sw_interface_set_mpls_enable,                                         \
22627   "<intfc> | sw_if_index [disable | dis]")                              \
22628 _(sw_interface_set_vpath,                                               \
22629   "<intfc> | sw_if_index <id> enable | disable")                        \
22630 _(sw_interface_set_vxlan_bypass,                                        \
22631   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22632 _(sw_interface_set_geneve_bypass,                                       \
22633   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22634 _(sw_interface_set_l2_xconnect,                                         \
22635   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22636   "enable | disable")                                                   \
22637 _(sw_interface_set_l2_bridge,                                           \
22638   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22639   "[shg <split-horizon-group>] [bvi]\n"                                 \
22640   "enable | disable")                                                   \
22641 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22642 _(bridge_domain_add_del,                                                \
22643   "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") \
22644 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22645 _(l2fib_add_del,                                                        \
22646   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22647 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22648 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22649 _(l2_flags,                                                             \
22650   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22651 _(bridge_flags,                                                         \
22652   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22653 _(tap_connect,                                                          \
22654   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22655 _(tap_modify,                                                           \
22656   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22657 _(tap_delete,                                                           \
22658   "<vpp-if-name> | sw_if_index <id>")                                   \
22659 _(sw_interface_tap_dump, "")                                            \
22660 _(tap_create_v2,                                                        \
22661   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22662 _(tap_delete_v2,                                                        \
22663   "<vpp-if-name> | sw_if_index <id>")                                   \
22664 _(sw_interface_tap_v2_dump, "")                                         \
22665 _(ip_table_add_del,                                                     \
22666   "table-id <n> [ipv6]\n")                                              \
22667 _(ip_add_del_route,                                                     \
22668   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22669   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22670   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22671   "[multipath] [count <n>]")                                            \
22672 _(ip_mroute_add_del,                                                    \
22673   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22674   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22675 _(mpls_table_add_del,                                                   \
22676   "table-id <n>\n")                                                     \
22677 _(mpls_route_add_del,                                                   \
22678   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22679   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22680   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22681   "[multipath] [count <n>]")                                            \
22682 _(mpls_ip_bind_unbind,                                                  \
22683   "<label> <addr/len>")                                                 \
22684 _(mpls_tunnel_add_del,                                                  \
22685   " via <addr> [table-id <n>]\n"                                        \
22686   "sw_if_index <id>] [l2]  [del]")                                      \
22687 _(bier_table_add_del,                                                   \
22688   "<label> <sub-domain> <set> <bsl> [del]")                             \
22689 _(bier_route_add_del,                                                   \
22690   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22691   "[<intfc> | sw_if_index <id>]"                                        \
22692   "[weight <n>] [del] [multipath]")                                     \
22693 _(proxy_arp_add_del,                                                    \
22694   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22695 _(proxy_arp_intfc_enable_disable,                                       \
22696   "<intfc> | sw_if_index <id> enable | disable")                        \
22697 _(sw_interface_set_unnumbered,                                          \
22698   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22699 _(ip_neighbor_add_del,                                                  \
22700   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22701   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22702 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22703 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22704   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22705   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22706   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22707 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22708 _(reset_fib, "vrf <n> [ipv6]")                                          \
22709 _(dhcp_proxy_config,                                                    \
22710   "svr <v46-address> src <v46-address>\n"                               \
22711    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22712 _(dhcp_proxy_set_vss,                                                   \
22713   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22714 _(dhcp_proxy_dump, "ip6")                                               \
22715 _(dhcp_client_config,                                                   \
22716   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22717 _(set_ip_flow_hash,                                                     \
22718   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22719 _(sw_interface_ip6_enable_disable,                                      \
22720   "<intfc> | sw_if_index <id> enable | disable")                        \
22721 _(sw_interface_ip6_set_link_local_address,                              \
22722   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22723 _(ip6nd_proxy_add_del,                                                  \
22724   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22725 _(ip6nd_proxy_dump, "")                                                 \
22726 _(sw_interface_ip6nd_ra_prefix,                                         \
22727   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22728   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22729   "[nolink] [isno]")                                                    \
22730 _(sw_interface_ip6nd_ra_config,                                         \
22731   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22732   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22733   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22734 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22735 _(l2_patch_add_del,                                                     \
22736   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22737   "enable | disable")                                                   \
22738 _(sr_localsid_add_del,                                                  \
22739   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22740   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22741 _(classify_add_del_table,                                               \
22742   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22743   " [del] [del-chain] mask <mask-value>\n"                              \
22744   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22745   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22746 _(classify_add_del_session,                                             \
22747   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22748   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22749   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22750   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22751 _(classify_set_interface_ip_table,                                      \
22752   "<intfc> | sw_if_index <nn> table <nn>")                              \
22753 _(classify_set_interface_l2_tables,                                     \
22754   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22755   "  [other-table <nn>]")                                               \
22756 _(get_node_index, "node <node-name")                                    \
22757 _(add_node_next, "node <node-name> next <next-node-name>")              \
22758 _(l2tpv3_create_tunnel,                                                 \
22759   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22760   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22761   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22762 _(l2tpv3_set_tunnel_cookies,                                            \
22763   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22764   "[new_remote_cookie <nn>]\n")                                         \
22765 _(l2tpv3_interface_enable_disable,                                      \
22766   "<intfc> | sw_if_index <nn> enable | disable")                        \
22767 _(l2tpv3_set_lookup_key,                                                \
22768   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22769 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22770 _(vxlan_add_del_tunnel,                                                 \
22771   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22772   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22773   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22774 _(geneve_add_del_tunnel,                                                \
22775   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22776   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22777   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22778 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22779 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22780 _(gre_add_del_tunnel,                                                   \
22781   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22782 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22783 _(l2_fib_clear_table, "")                                               \
22784 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22785 _(l2_interface_vlan_tag_rewrite,                                        \
22786   "<intfc> | sw_if_index <nn> \n"                                       \
22787   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22788   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22789 _(create_vhost_user_if,                                                 \
22790         "socket <filename> [server] [renumber <dev_instance>] "         \
22791         "[mac <mac_address>]")                                          \
22792 _(modify_vhost_user_if,                                                 \
22793         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22794         "[server] [renumber <dev_instance>]")                           \
22795 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22796 _(sw_interface_vhost_user_dump, "")                                     \
22797 _(show_version, "")                                                     \
22798 _(vxlan_gpe_add_del_tunnel,                                             \
22799   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22800   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22801   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22802   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22803 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22804 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22805 _(interface_name_renumber,                                              \
22806   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22807 _(input_acl_set_interface,                                              \
22808   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22809   "  [l2-table <nn>] [del]")                                            \
22810 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22811 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22812 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22813 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22814 _(ip_dump, "ipv4 | ipv6")                                               \
22815 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22816 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22817   "  spid_id <n> ")                                                     \
22818 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22819   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22820   "  integ_alg <alg> integ_key <hex>")                                  \
22821 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22822   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22823   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22824   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22825 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22826 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22827   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22828   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22829   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22830 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22831 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22832   "  <alg> <hex>\n")                                                    \
22833 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22834 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22835 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22836   "(auth_data 0x<data> | auth_data <data>)")                            \
22837 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22838   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22839 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22840   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22841   "(local|remote)")                                                     \
22842 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22843 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22844 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22845 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22846 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22847 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22848 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22849 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22850 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22851 _(delete_loopback,"sw_if_index <nn>")                                   \
22852 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22853 _(map_add_domain,                                                       \
22854   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22855   "ip6-src <ip6addr> "                                                  \
22856   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22857 _(map_del_domain, "index <n>")                                          \
22858 _(map_add_del_rule,                                                     \
22859   "index <n> psid <n> dst <ip6addr> [del]")                             \
22860 _(map_domain_dump, "")                                                  \
22861 _(map_rule_dump, "index <map-domain>")                                  \
22862 _(want_interface_events,  "enable|disable")                             \
22863 _(want_stats,"enable|disable")                                          \
22864 _(get_first_msg_id, "client <name>")                                    \
22865 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22866 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22867   "fib-id <nn> [ip4][ip6][default]")                                    \
22868 _(get_node_graph, " ")                                                  \
22869 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22870 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22871 _(ioam_disable, "")                                                     \
22872 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22873                             " sw_if_index <sw_if_index> p <priority> "  \
22874                             "w <weight>] [del]")                        \
22875 _(one_add_del_locator, "locator-set <locator_name> "                    \
22876                         "iface <intf> | sw_if_index <sw_if_index> "     \
22877                         "p <priority> w <weight> [del]")                \
22878 _(one_add_del_local_eid,"vni <vni> eid "                                \
22879                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22880                          "locator-set <locator_name> [del]"             \
22881                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22882 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22883 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22884 _(one_enable_disable, "enable|disable")                                 \
22885 _(one_map_register_enable_disable, "enable|disable")                    \
22886 _(one_map_register_fallback_threshold, "<value>")                       \
22887 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22888 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22889                                "[seid <seid>] "                         \
22890                                "rloc <locator> p <prio> "               \
22891                                "w <weight> [rloc <loc> ... ] "          \
22892                                "action <action> [del-all]")             \
22893 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22894                           "<local-eid>")                                \
22895 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22896 _(one_use_petr, "ip-address> | disable")                                \
22897 _(one_map_request_mode, "src-dst|dst-only")                             \
22898 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22899 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22900 _(one_locator_set_dump, "[local | remote]")                             \
22901 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22902 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22903                        "[local] | [remote]")                            \
22904 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22905 _(one_ndp_bd_get, "")                                                   \
22906 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22907 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22908 _(one_l2_arp_bd_get, "")                                                \
22909 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22910 _(one_stats_enable_disable, "enable|disalbe")                           \
22911 _(show_one_stats_enable_disable, "")                                    \
22912 _(one_eid_table_vni_dump, "")                                           \
22913 _(one_eid_table_map_dump, "l2|l3")                                      \
22914 _(one_map_resolver_dump, "")                                            \
22915 _(one_map_server_dump, "")                                              \
22916 _(one_adjacencies_get, "vni <vni>")                                     \
22917 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22918 _(show_one_rloc_probe_state, "")                                        \
22919 _(show_one_map_register_state, "")                                      \
22920 _(show_one_status, "")                                                  \
22921 _(one_stats_dump, "")                                                   \
22922 _(one_stats_flush, "")                                                  \
22923 _(one_get_map_request_itr_rlocs, "")                                    \
22924 _(one_map_register_set_ttl, "<ttl>")                                    \
22925 _(one_set_transport_protocol, "udp|api")                                \
22926 _(one_get_transport_protocol, "")                                       \
22927 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22928 _(one_show_xtr_mode, "")                                                \
22929 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22930 _(one_show_pitr_mode, "")                                               \
22931 _(one_enable_disable_petr_mode, "enable|disable")                       \
22932 _(one_show_petr_mode, "")                                               \
22933 _(show_one_nsh_mapping, "")                                             \
22934 _(show_one_pitr, "")                                                    \
22935 _(show_one_use_petr, "")                                                \
22936 _(show_one_map_request_mode, "")                                        \
22937 _(show_one_map_register_ttl, "")                                        \
22938 _(show_one_map_register_fallback_threshold, "")                         \
22939 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22940                             " sw_if_index <sw_if_index> p <priority> "  \
22941                             "w <weight>] [del]")                        \
22942 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22943                         "iface <intf> | sw_if_index <sw_if_index> "     \
22944                         "p <priority> w <weight> [del]")                \
22945 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22946                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22947                          "locator-set <locator_name> [del]"             \
22948                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22949 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22950 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22951 _(lisp_enable_disable, "enable|disable")                                \
22952 _(lisp_map_register_enable_disable, "enable|disable")                   \
22953 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22954 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22955                                "[seid <seid>] "                         \
22956                                "rloc <locator> p <prio> "               \
22957                                "w <weight> [rloc <loc> ... ] "          \
22958                                "action <action> [del-all]")             \
22959 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22960                           "<local-eid>")                                \
22961 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22962 _(lisp_use_petr, "<ip-address> | disable")                              \
22963 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22964 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22965 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22966 _(lisp_locator_set_dump, "[local | remote]")                            \
22967 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22968 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22969                        "[local] | [remote]")                            \
22970 _(lisp_eid_table_vni_dump, "")                                          \
22971 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22972 _(lisp_map_resolver_dump, "")                                           \
22973 _(lisp_map_server_dump, "")                                             \
22974 _(lisp_adjacencies_get, "vni <vni>")                                    \
22975 _(gpe_fwd_entry_vnis_get, "")                                           \
22976 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22977 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22978                                 "[table <table-id>]")                   \
22979 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22980 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22981 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22982 _(gpe_get_encap_mode, "")                                               \
22983 _(lisp_gpe_add_del_iface, "up|down")                                    \
22984 _(lisp_gpe_enable_disable, "enable|disable")                            \
22985 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22986   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22987 _(show_lisp_rloc_probe_state, "")                                       \
22988 _(show_lisp_map_register_state, "")                                     \
22989 _(show_lisp_status, "")                                                 \
22990 _(lisp_get_map_request_itr_rlocs, "")                                   \
22991 _(show_lisp_pitr, "")                                                   \
22992 _(show_lisp_use_petr, "")                                               \
22993 _(show_lisp_map_request_mode, "")                                       \
22994 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22995 _(af_packet_delete, "name <host interface name>")                       \
22996 _(policer_add_del, "name <policer name> <params> [del]")                \
22997 _(policer_dump, "[name <policer name>]")                                \
22998 _(policer_classify_set_interface,                                       \
22999   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23000   "  [l2-table <nn>] [del]")                                            \
23001 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23002 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23003     "[master|slave]")                                                   \
23004 _(netmap_delete, "name <interface name>")                               \
23005 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23006 _(mpls_fib_dump, "")                                                    \
23007 _(classify_table_ids, "")                                               \
23008 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23009 _(classify_table_info, "table_id <nn>")                                 \
23010 _(classify_session_dump, "table_id <nn>")                               \
23011 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23012     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23013     "[template_interval <nn>] [udp_checksum]")                          \
23014 _(ipfix_exporter_dump, "")                                              \
23015 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23016 _(ipfix_classify_stream_dump, "")                                       \
23017 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23018 _(ipfix_classify_table_dump, "")                                        \
23019 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23020 _(sw_interface_span_dump, "[l2]")                                           \
23021 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23022 _(pg_create_interface, "if_id <nn>")                                    \
23023 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23024 _(pg_enable_disable, "[stream <id>] disable")                           \
23025 _(ip_source_and_port_range_check_add_del,                               \
23026   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23027 _(ip_source_and_port_range_check_interface_add_del,                     \
23028   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23029   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23030 _(ipsec_gre_add_del_tunnel,                                             \
23031   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23032 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23033 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23034 _(l2_interface_pbb_tag_rewrite,                                         \
23035   "<intfc> | sw_if_index <nn> \n"                                       \
23036   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23037   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23038 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23039 _(flow_classify_set_interface,                                          \
23040   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23041 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23042 _(ip_fib_dump, "")                                                      \
23043 _(ip_mfib_dump, "")                                                     \
23044 _(ip6_fib_dump, "")                                                     \
23045 _(ip6_mfib_dump, "")                                                    \
23046 _(feature_enable_disable, "arc_name <arc_name> "                        \
23047   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23048 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23049 "[disable]")                                                            \
23050 _(l2_xconnect_dump, "")                                                 \
23051 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23052 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23053 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23054 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23055 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23056 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23057 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23058   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23059 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23060 _(memfd_segment_create,"size <nnn>")                                    \
23061 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23062 _(dns_enable_disable, "[enable][disable]")                              \
23063 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23064 _(dns_resolve_name, "<hostname>")                                       \
23065 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23066 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23067 _(dns_resolve_name, "<hostname>")                                       \
23068 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23069   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23070 _(session_rules_dump, "")                                               \
23071 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23072
23073 /* List of command functions, CLI names map directly to functions */
23074 #define foreach_cli_function                                    \
23075 _(comment, "usage: comment <ignore-rest-of-line>")              \
23076 _(dump_interface_table, "usage: dump_interface_table")          \
23077 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23078 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23079 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23080 _(dump_stats_table, "usage: dump_stats_table")                  \
23081 _(dump_macro_table, "usage: dump_macro_table ")                 \
23082 _(dump_node_table, "usage: dump_node_table")                    \
23083 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23084 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23085 _(echo, "usage: echo <message>")                                \
23086 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23087 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23088 _(help, "usage: help")                                          \
23089 _(q, "usage: quit")                                             \
23090 _(quit, "usage: quit")                                          \
23091 _(search_node_table, "usage: search_node_table <name>...")      \
23092 _(set, "usage: set <variable-name> <value>")                    \
23093 _(script, "usage: script <file-name>")                          \
23094 _(unset, "usage: unset <variable-name>")
23095 #define _(N,n)                                  \
23096     static void vl_api_##n##_t_handler_uni      \
23097     (vl_api_##n##_t * mp)                       \
23098     {                                           \
23099         vat_main_t * vam = &vat_main;           \
23100         if (vam->json_output) {                 \
23101             vl_api_##n##_t_handler_json(mp);    \
23102         } else {                                \
23103             vl_api_##n##_t_handler(mp);         \
23104         }                                       \
23105     }
23106 foreach_vpe_api_reply_msg;
23107 #if VPP_API_TEST_BUILTIN == 0
23108 foreach_standalone_reply_msg;
23109 #endif
23110 #undef _
23111
23112 void
23113 vat_api_hookup (vat_main_t * vam)
23114 {
23115 #define _(N,n)                                                  \
23116     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23117                            vl_api_##n##_t_handler_uni,          \
23118                            vl_noop_handler,                     \
23119                            vl_api_##n##_t_endian,               \
23120                            vl_api_##n##_t_print,                \
23121                            sizeof(vl_api_##n##_t), 1);
23122   foreach_vpe_api_reply_msg;
23123 #if VPP_API_TEST_BUILTIN == 0
23124   foreach_standalone_reply_msg;
23125 #endif
23126 #undef _
23127
23128 #if (VPP_API_TEST_BUILTIN==0)
23129   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23130
23131   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23132
23133   vam->function_by_name = hash_create_string (0, sizeof (uword));
23134
23135   vam->help_by_name = hash_create_string (0, sizeof (uword));
23136 #endif
23137
23138   /* API messages we can send */
23139 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23140   foreach_vpe_api_msg;
23141 #undef _
23142
23143   /* Help strings */
23144 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23145   foreach_vpe_api_msg;
23146 #undef _
23147
23148   /* CLI functions */
23149 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23150   foreach_cli_function;
23151 #undef _
23152
23153   /* Help strings */
23154 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23155   foreach_cli_function;
23156 #undef _
23157 }
23158
23159 #if VPP_API_TEST_BUILTIN
23160 static clib_error_t *
23161 vat_api_hookup_shim (vlib_main_t * vm)
23162 {
23163   vat_api_hookup (&vat_main);
23164   return 0;
23165 }
23166
23167 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23168 #endif
23169
23170 /*
23171  * fd.io coding-style-patch-verification: ON
23172  *
23173  * Local Variables:
23174  * eval: (c-set-style "gnu")
23175  * End:
23176  */