virtio: fix coverity warnings
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   return vl_socket_client_connect
92     (&vam->socket_client_main, (char *) vam->socket_name,
93      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 void
103 vl_socket_client_read_reply (socket_client_main_t * scm)
104 {
105 };
106 #endif
107
108
109 f64
110 vat_time_now (vat_main_t * vam)
111 {
112 #if VPP_API_TEST_BUILTIN
113   return vlib_time_now (vam->vlib_main);
114 #else
115   return clib_time_now (&vam->clib_time);
116 #endif
117 }
118
119 void
120 errmsg (char *fmt, ...)
121 {
122   vat_main_t *vam = &vat_main;
123   va_list va;
124   u8 *s;
125
126   va_start (va, fmt);
127   s = va_format (0, fmt, &va);
128   va_end (va);
129
130   vec_add1 (s, 0);
131
132 #if VPP_API_TEST_BUILTIN
133   vlib_cli_output (vam->vlib_main, (char *) s);
134 #else
135   {
136     if (vam->ifp != stdin)
137       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
138                vam->input_line_number);
139     fformat (vam->ofp, (char *) s);
140     fflush (vam->ofp);
141   }
142 #endif
143
144   vec_free (s);
145 }
146
147 #if VPP_API_TEST_BUILTIN == 0
148 static uword
149 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
150 {
151   vat_main_t *vam = va_arg (*args, vat_main_t *);
152   u32 *result = va_arg (*args, u32 *);
153   u8 *if_name;
154   uword *p;
155
156   if (!unformat (input, "%s", &if_name))
157     return 0;
158
159   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
160   if (p == 0)
161     return 0;
162   *result = p[0];
163   return 1;
164 }
165
166 /* Parse an IP4 address %d.%d.%d.%d. */
167 uword
168 unformat_ip4_address (unformat_input_t * input, va_list * args)
169 {
170   u8 *result = va_arg (*args, u8 *);
171   unsigned a[4];
172
173   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
174     return 0;
175
176   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
177     return 0;
178
179   result[0] = a[0];
180   result[1] = a[1];
181   result[2] = a[2];
182   result[3] = a[3];
183
184   return 1;
185 }
186
187 uword
188 unformat_ethernet_address (unformat_input_t * input, va_list * args)
189 {
190   u8 *result = va_arg (*args, u8 *);
191   u32 i, a[6];
192
193   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
194                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
195     return 0;
196
197   /* Check range. */
198   for (i = 0; i < 6; i++)
199     if (a[i] >= (1 << 8))
200       return 0;
201
202   for (i = 0; i < 6; i++)
203     result[i] = a[i];
204
205   return 1;
206 }
207
208 /* Returns ethernet type as an int in host byte order. */
209 uword
210 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
211                                         va_list * args)
212 {
213   u16 *result = va_arg (*args, u16 *);
214   int type;
215
216   /* Numeric type. */
217   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
218     {
219       if (type >= (1 << 16))
220         return 0;
221       *result = type;
222       return 1;
223     }
224   return 0;
225 }
226
227 /* Parse an IP6 address. */
228 uword
229 unformat_ip6_address (unformat_input_t * input, va_list * args)
230 {
231   ip6_address_t *result = va_arg (*args, ip6_address_t *);
232   u16 hex_quads[8];
233   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
234   uword c, n_colon, double_colon_index;
235
236   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
237   double_colon_index = ARRAY_LEN (hex_quads);
238   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
239     {
240       hex_digit = 16;
241       if (c >= '0' && c <= '9')
242         hex_digit = c - '0';
243       else if (c >= 'a' && c <= 'f')
244         hex_digit = c + 10 - 'a';
245       else if (c >= 'A' && c <= 'F')
246         hex_digit = c + 10 - 'A';
247       else if (c == ':' && n_colon < 2)
248         n_colon++;
249       else
250         {
251           unformat_put_input (input);
252           break;
253         }
254
255       /* Too many hex quads. */
256       if (n_hex_quads >= ARRAY_LEN (hex_quads))
257         return 0;
258
259       if (hex_digit < 16)
260         {
261           hex_quad = (hex_quad << 4) | hex_digit;
262
263           /* Hex quad must fit in 16 bits. */
264           if (n_hex_digits >= 4)
265             return 0;
266
267           n_colon = 0;
268           n_hex_digits++;
269         }
270
271       /* Save position of :: */
272       if (n_colon == 2)
273         {
274           /* More than one :: ? */
275           if (double_colon_index < ARRAY_LEN (hex_quads))
276             return 0;
277           double_colon_index = n_hex_quads;
278         }
279
280       if (n_colon > 0 && n_hex_digits > 0)
281         {
282           hex_quads[n_hex_quads++] = hex_quad;
283           hex_quad = 0;
284           n_hex_digits = 0;
285         }
286     }
287
288   if (n_hex_digits > 0)
289     hex_quads[n_hex_quads++] = hex_quad;
290
291   {
292     word i;
293
294     /* Expand :: to appropriate number of zero hex quads. */
295     if (double_colon_index < ARRAY_LEN (hex_quads))
296       {
297         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
298
299         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
300           hex_quads[n_zero + i] = hex_quads[i];
301
302         for (i = 0; i < n_zero; i++)
303           hex_quads[double_colon_index + i] = 0;
304
305         n_hex_quads = ARRAY_LEN (hex_quads);
306       }
307
308     /* Too few hex quads given. */
309     if (n_hex_quads < ARRAY_LEN (hex_quads))
310       return 0;
311
312     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
313       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
314
315     return 1;
316   }
317 }
318
319 uword
320 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
321 {
322   u32 *r = va_arg (*args, u32 *);
323
324   if (0);
325 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
326   foreach_ipsec_policy_action
327 #undef _
328     else
329     return 0;
330   return 1;
331 }
332
333 uword
334 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
340   foreach_ipsec_crypto_alg
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 u8 *
348 format_ipsec_crypto_alg (u8 * s, va_list * args)
349 {
350   u32 i = va_arg (*args, u32);
351   u8 *t = 0;
352
353   switch (i)
354     {
355 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
356       foreach_ipsec_crypto_alg
357 #undef _
358     default:
359       return format (s, "unknown");
360     }
361   return format (s, "%s", t);
362 }
363
364 uword
365 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
366 {
367   u32 *r = va_arg (*args, u32 *);
368
369   if (0);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
371   foreach_ipsec_integ_alg
372 #undef _
373     else
374     return 0;
375   return 1;
376 }
377
378 u8 *
379 format_ipsec_integ_alg (u8 * s, va_list * args)
380 {
381   u32 i = va_arg (*args, u32);
382   u8 *t = 0;
383
384   switch (i)
385     {
386 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
387       foreach_ipsec_integ_alg
388 #undef _
389     default:
390       return format (s, "unknown");
391     }
392   return format (s, "%s", t);
393 }
394
395 uword
396 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
397 {
398   u32 *r = va_arg (*args, u32 *);
399
400   if (0);
401 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
402   foreach_ikev2_auth_method
403 #undef _
404     else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
416   foreach_ikev2_id_type
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422 #else /* VPP_API_TEST_BUILTIN == 1 */
423 static uword
424 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
425 {
426   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
427   vnet_main_t *vnm = vnet_get_main ();
428   u32 *result = va_arg (*args, u32 *);
429   u32 sw_if_index;
430
431   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
432     return 0;
433
434   *result = sw_if_index;
435   return 1;
436 }
437 #endif /* VPP_API_TEST_BUILTIN */
438
439 static uword
440 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
441 {
442   u8 *r = va_arg (*args, u8 *);
443
444   if (unformat (input, "kbps"))
445     *r = SSE2_QOS_RATE_KBPS;
446   else if (unformat (input, "pps"))
447     *r = SSE2_QOS_RATE_PPS;
448   else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_round_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "closest"))
459     *r = SSE2_QOS_ROUND_TO_CLOSEST;
460   else if (unformat (input, "up"))
461     *r = SSE2_QOS_ROUND_TO_UP;
462   else if (unformat (input, "down"))
463     *r = SSE2_QOS_ROUND_TO_DOWN;
464   else
465     return 0;
466   return 1;
467 }
468
469 static uword
470 unformat_policer_type (unformat_input_t * input, va_list * args)
471 {
472   u8 *r = va_arg (*args, u8 *);
473
474   if (unformat (input, "1r2c"))
475     *r = SSE2_QOS_POLICER_TYPE_1R2C;
476   else if (unformat (input, "1r3c"))
477     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
478   else if (unformat (input, "2r3c-2698"))
479     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
480   else if (unformat (input, "2r3c-4115"))
481     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
482   else if (unformat (input, "2r3c-mef5cf1"))
483     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_dscp (unformat_input_t * input, va_list * va)
491 {
492   u8 *r = va_arg (*va, u8 *);
493
494   if (0);
495 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
496   foreach_vnet_dscp
497 #undef _
498     else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_action_type (unformat_input_t * input, va_list * va)
505 {
506   sse2_qos_pol_action_params_st *a
507     = va_arg (*va, sse2_qos_pol_action_params_st *);
508
509   if (unformat (input, "drop"))
510     a->action_type = SSE2_QOS_ACTION_DROP;
511   else if (unformat (input, "transmit"))
512     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
513   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
514     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
515   else
516     return 0;
517   return 1;
518 }
519
520 static uword
521 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
522 {
523   u32 *r = va_arg (*va, u32 *);
524   u32 tid;
525
526   if (unformat (input, "ip4"))
527     tid = POLICER_CLASSIFY_TABLE_IP4;
528   else if (unformat (input, "ip6"))
529     tid = POLICER_CLASSIFY_TABLE_IP6;
530   else if (unformat (input, "l2"))
531     tid = POLICER_CLASSIFY_TABLE_L2;
532   else
533     return 0;
534
535   *r = tid;
536   return 1;
537 }
538
539 static uword
540 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = FLOW_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = FLOW_CLASSIFY_TABLE_IP6;
549   else
550     return 0;
551
552   *r = tid;
553   return 1;
554 }
555
556 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
557 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
558 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
559 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
560
561 #if (VPP_API_TEST_BUILTIN==0)
562 uword
563 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
564 {
565   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
566   mfib_itf_attribute_t attr;
567
568   old = *iflags;
569   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
570   {
571     if (unformat (input, mfib_itf_flag_long_names[attr]))
572       *iflags |= (1 << attr);
573   }
574   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
575   {
576     if (unformat (input, mfib_itf_flag_names[attr]))
577       *iflags |= (1 << attr);
578   }
579
580   return (old == *iflags ? 0 : 1);
581 }
582
583 uword
584 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
587   mfib_entry_attribute_t attr;
588
589   old = *eflags;
590   FOR_EACH_MFIB_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_flag_long_names[attr]))
593       *eflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_flag_names[attr]))
598       *eflags |= (1 << attr);
599   }
600
601   return (old == *eflags ? 0 : 1);
602 }
603
604 u8 *
605 format_ip4_address (u8 * s, va_list * args)
606 {
607   u8 *a = va_arg (*args, u8 *);
608   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
609 }
610
611 u8 *
612 format_ip6_address (u8 * s, va_list * args)
613 {
614   ip6_address_t *a = va_arg (*args, ip6_address_t *);
615   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
616
617   i_max_n_zero = ARRAY_LEN (a->as_u16);
618   max_n_zeros = 0;
619   i_first_zero = i_max_n_zero;
620   n_zeros = 0;
621   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
622     {
623       u32 is_zero = a->as_u16[i] == 0;
624       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
625         {
626           i_first_zero = i;
627           n_zeros = 0;
628         }
629       n_zeros += is_zero;
630       if ((!is_zero && n_zeros > max_n_zeros)
631           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
632         {
633           i_max_n_zero = i_first_zero;
634           max_n_zeros = n_zeros;
635           i_first_zero = ARRAY_LEN (a->as_u16);
636           n_zeros = 0;
637         }
638     }
639
640   last_double_colon = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       if (i == i_max_n_zero && max_n_zeros > 1)
644         {
645           s = format (s, "::");
646           i += max_n_zeros - 1;
647           last_double_colon = 1;
648         }
649       else
650         {
651           s = format (s, "%s%x",
652                       (last_double_colon || i == 0) ? "" : ":",
653                       clib_net_to_host_u16 (a->as_u16[i]));
654           last_double_colon = 0;
655         }
656     }
657
658   return s;
659 }
660
661 /* Format an IP46 address. */
662 u8 *
663 format_ip46_address (u8 * s, va_list * args)
664 {
665   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
666   ip46_type_t type = va_arg (*args, ip46_type_t);
667   int is_ip4 = 1;
668
669   switch (type)
670     {
671     case IP46_TYPE_ANY:
672       is_ip4 = ip46_address_is_ip4 (ip46);
673       break;
674     case IP46_TYPE_IP4:
675       is_ip4 = 1;
676       break;
677     case IP46_TYPE_IP6:
678       is_ip4 = 0;
679       break;
680     }
681
682   return is_ip4 ?
683     format (s, "%U", format_ip4_address, &ip46->ip4) :
684     format (s, "%U", format_ip6_address, &ip46->ip6);
685 }
686
687 u8 *
688 format_ethernet_address (u8 * s, va_list * args)
689 {
690   u8 *a = va_arg (*args, u8 *);
691
692   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
693                  a[0], a[1], a[2], a[3], a[4], a[5]);
694 }
695 #endif
696
697 static void
698 increment_v4_address (ip4_address_t * a)
699 {
700   u32 v;
701
702   v = ntohl (a->as_u32) + 1;
703   a->as_u32 = ntohl (v);
704 }
705
706 static void
707 increment_v6_address (ip6_address_t * a)
708 {
709   u64 v0, v1;
710
711   v0 = clib_net_to_host_u64 (a->as_u64[0]);
712   v1 = clib_net_to_host_u64 (a->as_u64[1]);
713
714   v1 += 1;
715   if (v1 == 0)
716     v0 += 1;
717   a->as_u64[0] = clib_net_to_host_u64 (v0);
718   a->as_u64[1] = clib_net_to_host_u64 (v1);
719 }
720
721 static void
722 increment_mac_address (u8 * mac)
723 {
724   u64 tmp = *((u64 *) mac);
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728
729   clib_memcpy (mac, &tmp, 6);
730 }
731
732 static void vl_api_create_loopback_reply_t_handler
733   (vl_api_create_loopback_reply_t * mp)
734 {
735   vat_main_t *vam = &vat_main;
736   i32 retval = ntohl (mp->retval);
737
738   vam->retval = retval;
739   vam->regenerate_interface_table = 1;
740   vam->sw_if_index = ntohl (mp->sw_if_index);
741   vam->result_ready = 1;
742 }
743
744 static void vl_api_create_loopback_reply_t_handler_json
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   vat_json_node_t node;
749
750   vat_json_init_object (&node);
751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
753
754   vat_json_print (vam->ofp, &node);
755   vat_json_free (&node);
756   vam->retval = ntohl (mp->retval);
757   vam->result_ready = 1;
758 }
759
760 static void vl_api_create_loopback_instance_reply_t_handler
761   (vl_api_create_loopback_instance_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler_json
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_af_packet_create_reply_t_handler
789   (vl_api_af_packet_create_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler_json
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812
813   vam->retval = ntohl (mp->retval);
814   vam->result_ready = 1;
815 }
816
817 static void vl_api_create_vlan_subif_reply_t_handler
818   (vl_api_create_vlan_subif_reply_t * mp)
819 {
820   vat_main_t *vam = &vat_main;
821   i32 retval = ntohl (mp->retval);
822
823   vam->retval = retval;
824   vam->regenerate_interface_table = 1;
825   vam->sw_if_index = ntohl (mp->sw_if_index);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler_json
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   vat_json_node_t node;
834
835   vat_json_init_object (&node);
836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
838
839   vat_json_print (vam->ofp, &node);
840   vat_json_free (&node);
841
842   vam->retval = ntohl (mp->retval);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_subif_reply_t_handler
847   (vl_api_create_subif_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   i32 retval = ntohl (mp->retval);
851
852   vam->retval = retval;
853   vam->regenerate_interface_table = 1;
854   vam->sw_if_index = ntohl (mp->sw_if_index);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler_json
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
867
868   vat_json_print (vam->ofp, &node);
869   vat_json_free (&node);
870
871   vam->retval = ntohl (mp->retval);
872   vam->result_ready = 1;
873 }
874
875 static void vl_api_interface_name_renumber_reply_t_handler
876   (vl_api_interface_name_renumber_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->regenerate_interface_table = 1;
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_interface_name_renumber_reply_t_handler_json
887   (vl_api_interface_name_renumber_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894
895   vat_json_print (vam->ofp, &node);
896   vat_json_free (&node);
897
898   vam->retval = ntohl (mp->retval);
899   vam->result_ready = 1;
900 }
901
902 /*
903  * Special-case: build the interface table, maintain
904  * the next loopback sw_if_index vbl.
905  */
906 static void vl_api_sw_interface_details_t_handler
907   (vl_api_sw_interface_details_t * mp)
908 {
909   vat_main_t *vam = &vat_main;
910   u8 *s = format (0, "%s%c", mp->interface_name, 0);
911
912   hash_set_mem (vam->sw_if_index_by_interface_name, s,
913                 ntohl (mp->sw_if_index));
914
915   /* In sub interface case, fill the sub interface table entry */
916   if (mp->sw_if_index != mp->sup_sw_if_index)
917     {
918       sw_interface_subif_t *sub = NULL;
919
920       vec_add2 (vam->sw_if_subif_table, sub, 1);
921
922       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
923       strncpy ((char *) sub->interface_name, (char *) s,
924                vec_len (sub->interface_name));
925       sub->sw_if_index = ntohl (mp->sw_if_index);
926       sub->sub_id = ntohl (mp->sub_id);
927
928       sub->sub_dot1ad = mp->sub_dot1ad;
929       sub->sub_number_of_tags = mp->sub_number_of_tags;
930       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
931       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
932       sub->sub_exact_match = mp->sub_exact_match;
933       sub->sub_default = mp->sub_default;
934       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
935       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
936
937       /* vlan tag rewrite */
938       sub->vtr_op = ntohl (mp->vtr_op);
939       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
940       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
941       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
942     }
943 }
944
945 static void vl_api_sw_interface_details_t_handler_json
946   (vl_api_sw_interface_details_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t *node = NULL;
950
951   if (VAT_JSON_ARRAY != vam->json_tree.type)
952     {
953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
954       vat_json_init_array (&vam->json_tree);
955     }
956   node = vat_json_array_add (&vam->json_tree);
957
958   vat_json_init_object (node);
959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
960   vat_json_object_add_uint (node, "sup_sw_if_index",
961                             ntohl (mp->sup_sw_if_index));
962   vat_json_object_add_uint (node, "l2_address_length",
963                             ntohl (mp->l2_address_length));
964   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
965                              sizeof (mp->l2_address));
966   vat_json_object_add_string_copy (node, "interface_name",
967                                    mp->interface_name);
968   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
969   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
970   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
971   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
972   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
973   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
974   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
975   vat_json_object_add_uint (node, "sub_number_of_tags",
976                             mp->sub_number_of_tags);
977   vat_json_object_add_uint (node, "sub_outer_vlan_id",
978                             ntohs (mp->sub_outer_vlan_id));
979   vat_json_object_add_uint (node, "sub_inner_vlan_id",
980                             ntohs (mp->sub_inner_vlan_id));
981   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
982   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
983   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
984                             mp->sub_outer_vlan_id_any);
985   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
986                             mp->sub_inner_vlan_id_any);
987   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
988   vat_json_object_add_uint (node, "vtr_push_dot1q",
989                             ntohl (mp->vtr_push_dot1q));
990   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
991   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
992   if (mp->sub_dot1ah)
993     {
994       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
995                                        format (0, "%U",
996                                                format_ethernet_address,
997                                                &mp->b_dmac));
998       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
999                                        format (0, "%U",
1000                                                format_ethernet_address,
1001                                                &mp->b_smac));
1002       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1003       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1004     }
1005 }
1006
1007 #if VPP_API_TEST_BUILTIN == 0
1008 static void vl_api_sw_interface_event_t_handler
1009   (vl_api_sw_interface_event_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   if (vam->interface_event_display)
1013     errmsg ("interface flags: sw_if_index %d %s %s",
1014             ntohl (mp->sw_if_index),
1015             mp->admin_up_down ? "admin-up" : "admin-down",
1016             mp->link_up_down ? "link-up" : "link-down");
1017 }
1018 #endif
1019
1020 static void vl_api_sw_interface_event_t_handler_json
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   /* JSON output not supported */
1024 }
1025
1026 static void
1027 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031
1032   vam->retval = retval;
1033   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void
1038 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   vat_json_node_t node;
1042   api_main_t *am = &api_main;
1043   void *oldheap;
1044   u8 *reply;
1045
1046   vat_json_init_object (&node);
1047   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1048   vat_json_object_add_uint (&node, "reply_in_shmem",
1049                             ntohl (mp->reply_in_shmem));
1050   /* Toss the shared-memory original... */
1051   pthread_mutex_lock (&am->vlib_rp->mutex);
1052   oldheap = svm_push_data_heap (am->vlib_rp);
1053
1054   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1055   vec_free (reply);
1056
1057   svm_pop_heap (oldheap);
1058   pthread_mutex_unlock (&am->vlib_rp->mutex);
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void
1068 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   u32 length = ntohl (mp->length);
1073
1074   vec_reset_length (vam->cmd_reply);
1075
1076   vam->retval = retval;
1077   if (retval == 0)
1078     {
1079       vec_validate (vam->cmd_reply, length);
1080       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1081       vam->cmd_reply[length] = 0;
1082     }
1083   vam->result_ready = 1;
1084 }
1085
1086 static void
1087 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   vat_json_node_t node;
1091
1092   vec_reset_length (vam->cmd_reply);
1093
1094   vat_json_init_object (&node);
1095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1096   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void vl_api_classify_add_del_table_reply_t_handler
1106   (vl_api_classify_add_del_table_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   i32 retval = ntohl (mp->retval);
1110   if (vam->async_mode)
1111     {
1112       vam->async_errors += (retval < 0);
1113     }
1114   else
1115     {
1116       vam->retval = retval;
1117       if (retval == 0 &&
1118           ((mp->new_table_index != 0xFFFFFFFF) ||
1119            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1120            (mp->match_n_vectors != 0xFFFFFFFF)))
1121         /*
1122          * Note: this is just barely thread-safe, depends on
1123          * the main thread spinning waiting for an answer...
1124          */
1125         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1126                 ntohl (mp->new_table_index),
1127                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1128       vam->result_ready = 1;
1129     }
1130 }
1131
1132 static void vl_api_classify_add_del_table_reply_t_handler_json
1133   (vl_api_classify_add_del_table_reply_t * mp)
1134 {
1135   vat_main_t *vam = &vat_main;
1136   vat_json_node_t node;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "new_table_index",
1141                             ntohl (mp->new_table_index));
1142   vat_json_object_add_uint (&node, "skip_n_vectors",
1143                             ntohl (mp->skip_n_vectors));
1144   vat_json_object_add_uint (&node, "match_n_vectors",
1145                             ntohl (mp->match_n_vectors));
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_get_node_index_reply_t_handler
1155   (vl_api_get_node_index_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159   if (vam->async_mode)
1160     {
1161       vam->async_errors += (retval < 0);
1162     }
1163   else
1164     {
1165       vam->retval = retval;
1166       if (retval == 0)
1167         errmsg ("node index %d", ntohl (mp->node_index));
1168       vam->result_ready = 1;
1169     }
1170 }
1171
1172 static void vl_api_get_node_index_reply_t_handler_json
1173   (vl_api_get_node_index_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184
1185   vam->retval = ntohl (mp->retval);
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_get_next_index_reply_t_handler
1190   (vl_api_get_next_index_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   i32 retval = ntohl (mp->retval);
1194   if (vam->async_mode)
1195     {
1196       vam->async_errors += (retval < 0);
1197     }
1198   else
1199     {
1200       vam->retval = retval;
1201       if (retval == 0)
1202         errmsg ("next node index %d", ntohl (mp->next_index));
1203       vam->result_ready = 1;
1204     }
1205 }
1206
1207 static void vl_api_get_next_index_reply_t_handler_json
1208   (vl_api_get_next_index_reply_t * mp)
1209 {
1210   vat_main_t *vam = &vat_main;
1211   vat_json_node_t node;
1212
1213   vat_json_init_object (&node);
1214   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1215   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_add_node_next_reply_t_handler
1225   (vl_api_add_node_next_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("next index %d", ntohl (mp->next_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_add_node_next_reply_t_handler_json
1243   (vl_api_add_node_next_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_show_version_reply_t_handler
1260   (vl_api_show_version_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264
1265   if (retval >= 0)
1266     {
1267       errmsg ("        program: %s", mp->program);
1268       errmsg ("        version: %s", mp->version);
1269       errmsg ("     build date: %s", mp->build_date);
1270       errmsg ("build directory: %s", mp->build_directory);
1271     }
1272   vam->retval = retval;
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_show_version_reply_t_handler_json
1277   (vl_api_show_version_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   vat_json_node_t node;
1281
1282   vat_json_init_object (&node);
1283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1284   vat_json_object_add_string_copy (&node, "program", mp->program);
1285   vat_json_object_add_string_copy (&node, "version", mp->version);
1286   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1287   vat_json_object_add_string_copy (&node, "build_directory",
1288                                    mp->build_directory);
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void
1298 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1299 {
1300   u32 sw_if_index = ntohl (mp->sw_if_index);
1301   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1302           mp->mac_ip ? "mac/ip binding" : "address resolution",
1303           ntohl (mp->pid), format_ip4_address, &mp->address,
1304           format_ethernet_address, mp->new_mac, sw_if_index);
1305 }
1306
1307 static void
1308 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1309 {
1310   /* JSON output not supported */
1311 }
1312
1313 static void
1314 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1315 {
1316   u32 sw_if_index = ntohl (mp->sw_if_index);
1317   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1318           mp->mac_ip ? "mac/ip binding" : "address resolution",
1319           ntohl (mp->pid), format_ip6_address, mp->address,
1320           format_ethernet_address, mp->new_mac, sw_if_index);
1321 }
1322
1323 static void
1324 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1325 {
1326   /* JSON output not supported */
1327 }
1328
1329 static void
1330 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1331 {
1332   u32 n_macs = ntohl (mp->n_macs);
1333   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1334           ntohl (mp->pid), mp->client_index, n_macs);
1335   int i;
1336   for (i = 0; i < n_macs; i++)
1337     {
1338       vl_api_mac_entry_t *mac = &mp->mac[i];
1339       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1340               i + 1, ntohl (mac->sw_if_index),
1341               format_ethernet_address, mac->mac_addr, mac->is_del);
1342       if (i == 1000)
1343         break;
1344     }
1345 }
1346
1347 static void
1348 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1349 {
1350   /* JSON output not supported */
1351 }
1352
1353 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1354 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1355
1356 /*
1357  * Special-case: build the bridge domain table, maintain
1358  * the next bd id vbl.
1359  */
1360 static void vl_api_bridge_domain_details_t_handler
1361   (vl_api_bridge_domain_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1365   int i;
1366
1367   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1368          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1369
1370   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1371          ntohl (mp->bd_id), mp->learn, mp->forward,
1372          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1373
1374   if (n_sw_ifs)
1375     {
1376       vl_api_bridge_domain_sw_if_t *sw_ifs;
1377       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1378              "Interface Name");
1379
1380       sw_ifs = mp->sw_if_details;
1381       for (i = 0; i < n_sw_ifs; i++)
1382         {
1383           u8 *sw_if_name = 0;
1384           u32 sw_if_index;
1385           hash_pair_t *p;
1386
1387           sw_if_index = ntohl (sw_ifs->sw_if_index);
1388
1389           /* *INDENT-OFF* */
1390           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1391                              ({
1392                                if ((u32) p->value[0] == sw_if_index)
1393                                  {
1394                                    sw_if_name = (u8 *)(p->key);
1395                                    break;
1396                                  }
1397                              }));
1398           /* *INDENT-ON* */
1399           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1400                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1401                  "sw_if_index not found!");
1402
1403           sw_ifs++;
1404         }
1405     }
1406 }
1407
1408 static void vl_api_bridge_domain_details_t_handler_json
1409   (vl_api_bridge_domain_details_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t *node, *array = NULL;
1413   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1414
1415   if (VAT_JSON_ARRAY != vam->json_tree.type)
1416     {
1417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1418       vat_json_init_array (&vam->json_tree);
1419     }
1420   node = vat_json_array_add (&vam->json_tree);
1421
1422   vat_json_init_object (node);
1423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1424   vat_json_object_add_uint (node, "flood", mp->flood);
1425   vat_json_object_add_uint (node, "forward", mp->forward);
1426   vat_json_object_add_uint (node, "learn", mp->learn);
1427   vat_json_object_add_uint (node, "bvi_sw_if_index",
1428                             ntohl (mp->bvi_sw_if_index));
1429   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1430   array = vat_json_object_add (node, "sw_if");
1431   vat_json_init_array (array);
1432
1433
1434
1435   if (n_sw_ifs)
1436     {
1437       vl_api_bridge_domain_sw_if_t *sw_ifs;
1438       int i;
1439
1440       sw_ifs = mp->sw_if_details;
1441       for (i = 0; i < n_sw_ifs; i++)
1442         {
1443           node = vat_json_array_add (array);
1444           vat_json_init_object (node);
1445           vat_json_object_add_uint (node, "sw_if_index",
1446                                     ntohl (sw_ifs->sw_if_index));
1447           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1448           sw_ifs++;
1449         }
1450     }
1451 }
1452
1453 static void vl_api_control_ping_reply_t_handler
1454   (vl_api_control_ping_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467   vam->socket_client_main.control_pings_outstanding--;
1468 }
1469
1470 static void vl_api_control_ping_reply_t_handler_json
1471   (vl_api_control_ping_reply_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   i32 retval = ntohl (mp->retval);
1475
1476   if (VAT_JSON_NONE != vam->json_tree.type)
1477     {
1478       vat_json_print (vam->ofp, &vam->json_tree);
1479       vat_json_free (&vam->json_tree);
1480       vam->json_tree.type = VAT_JSON_NONE;
1481     }
1482   else
1483     {
1484       /* just print [] */
1485       vat_json_init_array (&vam->json_tree);
1486       vat_json_print (vam->ofp, &vam->json_tree);
1487       vam->json_tree.type = VAT_JSON_NONE;
1488     }
1489
1490   vam->retval = retval;
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495   vl_api_bridge_domain_set_mac_age_reply_t_handler
1496   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1512   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void
1528 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->result_ready = 1;
1540     }
1541 }
1542
1543 static void vl_api_l2_flags_reply_t_handler_json
1544   (vl_api_l2_flags_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t node;
1548
1549   vat_json_init_object (&node);
1550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1551   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1552                             ntohl (mp->resulting_feature_bitmap));
1553
1554   vat_json_print (vam->ofp, &node);
1555   vat_json_free (&node);
1556
1557   vam->retval = ntohl (mp->retval);
1558   vam->result_ready = 1;
1559 }
1560
1561 static void vl_api_bridge_flags_reply_t_handler
1562   (vl_api_bridge_flags_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   i32 retval = ntohl (mp->retval);
1566   if (vam->async_mode)
1567     {
1568       vam->async_errors += (retval < 0);
1569     }
1570   else
1571     {
1572       vam->retval = retval;
1573       vam->result_ready = 1;
1574     }
1575 }
1576
1577 static void vl_api_bridge_flags_reply_t_handler_json
1578   (vl_api_bridge_flags_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   vat_json_node_t node;
1582
1583   vat_json_init_object (&node);
1584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1585   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1586                             ntohl (mp->resulting_feature_bitmap));
1587
1588   vat_json_print (vam->ofp, &node);
1589   vat_json_free (&node);
1590
1591   vam->retval = ntohl (mp->retval);
1592   vam->result_ready = 1;
1593 }
1594
1595 static void vl_api_tap_connect_reply_t_handler
1596   (vl_api_tap_connect_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->sw_if_index = ntohl (mp->sw_if_index);
1608       vam->result_ready = 1;
1609     }
1610
1611 }
1612
1613 static void vl_api_tap_connect_reply_t_handler_json
1614   (vl_api_tap_connect_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1622
1623   vat_json_print (vam->ofp, &node);
1624   vat_json_free (&node);
1625
1626   vam->retval = ntohl (mp->retval);
1627   vam->result_ready = 1;
1628
1629 }
1630
1631 static void
1632 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->sw_if_index = ntohl (mp->sw_if_index);
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_modify_reply_t_handler_json
1649   (vl_api_tap_modify_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_tap_delete_reply_t_handler_json
1682   (vl_api_tap_delete_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void
1698 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->sw_if_index = ntohl (mp->sw_if_index);
1710       vam->result_ready = 1;
1711     }
1712
1713 }
1714
1715 static void vl_api_tap_create_v2_reply_t_handler_json
1716   (vl_api_tap_create_v2_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730
1731 }
1732
1733 static void
1734 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_delete_v2_reply_t_handler_json
1750   (vl_api_tap_delete_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1766   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1782   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1790                             ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1800   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1817   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1834   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1850   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "fwd_entry_index",
1858                             clib_net_to_host_u32 (mp->fwd_entry_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 u8 *
1868 format_lisp_transport_protocol (u8 * s, va_list * args)
1869 {
1870   u32 proto = va_arg (*args, u32);
1871
1872   switch (proto)
1873     {
1874     case 1:
1875       return format (s, "udp");
1876     case 2:
1877       return format (s, "api");
1878     default:
1879       return 0;
1880     }
1881   return 0;
1882 }
1883
1884 static void vl_api_one_get_transport_protocol_reply_t_handler
1885   (vl_api_one_get_transport_protocol_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   i32 retval = ntohl (mp->retval);
1889   if (vam->async_mode)
1890     {
1891       vam->async_errors += (retval < 0);
1892     }
1893   else
1894     {
1895       u32 proto = mp->protocol;
1896       print (vam->ofp, "Transport protocol: %U",
1897              format_lisp_transport_protocol, proto);
1898       vam->retval = retval;
1899       vam->result_ready = 1;
1900     }
1901 }
1902
1903 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1904   (vl_api_one_get_transport_protocol_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   vat_json_node_t node;
1908   u8 *s;
1909
1910   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1911   vec_add1 (s, 0);
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1916
1917   vec_free (s);
1918   vat_json_print (vam->ofp, &node);
1919   vat_json_free (&node);
1920
1921   vam->retval = ntohl (mp->retval);
1922   vam->result_ready = 1;
1923 }
1924
1925 static void vl_api_one_add_del_locator_set_reply_t_handler
1926   (vl_api_one_add_del_locator_set_reply_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   i32 retval = ntohl (mp->retval);
1930   if (vam->async_mode)
1931     {
1932       vam->async_errors += (retval < 0);
1933     }
1934   else
1935     {
1936       vam->retval = retval;
1937       vam->result_ready = 1;
1938     }
1939 }
1940
1941 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1942   (vl_api_one_add_del_locator_set_reply_t * mp)
1943 {
1944   vat_main_t *vam = &vat_main;
1945   vat_json_node_t node;
1946
1947   vat_json_init_object (&node);
1948   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1949   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1950
1951   vat_json_print (vam->ofp, &node);
1952   vat_json_free (&node);
1953
1954   vam->retval = ntohl (mp->retval);
1955   vam->result_ready = 1;
1956 }
1957
1958 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1959   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   i32 retval = ntohl (mp->retval);
1963   if (vam->async_mode)
1964     {
1965       vam->async_errors += (retval < 0);
1966     }
1967   else
1968     {
1969       vam->retval = retval;
1970       vam->sw_if_index = ntohl (mp->sw_if_index);
1971       vam->result_ready = 1;
1972     }
1973 }
1974
1975 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1976   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   vat_json_node_t node;
1980
1981   vat_json_init_object (&node);
1982   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1983   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1984
1985   vat_json_print (vam->ofp, &node);
1986   vat_json_free (&node);
1987
1988   vam->retval = ntohl (mp->retval);
1989   vam->result_ready = 1;
1990 }
1991
1992 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1993   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   i32 retval = ntohl (mp->retval);
1997   if (vam->async_mode)
1998     {
1999       vam->async_errors += (retval < 0);
2000     }
2001   else
2002     {
2003       vam->retval = retval;
2004       vam->sw_if_index = ntohl (mp->sw_if_index);
2005       vam->result_ready = 1;
2006     }
2007 }
2008
2009 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2010   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t node;
2014
2015   vat_json_init_object (&node);
2016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2017   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2018
2019   vat_json_print (vam->ofp, &node);
2020   vat_json_free (&node);
2021
2022   vam->retval = ntohl (mp->retval);
2023   vam->result_ready = 1;
2024 }
2025
2026 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2027   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   i32 retval = ntohl (mp->retval);
2031   if (vam->async_mode)
2032     {
2033       vam->async_errors += (retval < 0);
2034     }
2035   else
2036     {
2037       vam->retval = retval;
2038       vam->sw_if_index = ntohl (mp->sw_if_index);
2039       vam->result_ready = 1;
2040     }
2041 }
2042
2043 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2044   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vat_json_node_t node;
2048
2049   vat_json_init_object (&node);
2050   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2051   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2052
2053   vat_json_print (vam->ofp, &node);
2054   vat_json_free (&node);
2055
2056   vam->retval = ntohl (mp->retval);
2057   vam->result_ready = 1;
2058 }
2059
2060 static void vl_api_gre_add_del_tunnel_reply_t_handler
2061   (vl_api_gre_add_del_tunnel_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->sw_if_index = ntohl (mp->sw_if_index);
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2078   (vl_api_gre_add_del_tunnel_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_create_vhost_user_if_reply_t_handler
2095   (vl_api_create_vhost_user_if_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_create_vhost_user_if_reply_t_handler_json
2112   (vl_api_create_vhost_user_if_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static clib_error_t *
2129 receive_fd_msg (int socket_fd, int *my_fd)
2130 {
2131   char msgbuf[16];
2132   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2133   struct msghdr mh = { 0 };
2134   struct iovec iov[1];
2135   ssize_t size;
2136   struct ucred *cr = 0;
2137   struct cmsghdr *cmsg;
2138   pid_t pid __attribute__ ((unused));
2139   uid_t uid __attribute__ ((unused));
2140   gid_t gid __attribute__ ((unused));
2141
2142   iov[0].iov_base = msgbuf;
2143   iov[0].iov_len = 5;
2144   mh.msg_iov = iov;
2145   mh.msg_iovlen = 1;
2146   mh.msg_control = ctl;
2147   mh.msg_controllen = sizeof (ctl);
2148
2149   memset (ctl, 0, sizeof (ctl));
2150
2151   /* receive the incoming message */
2152   size = recvmsg (socket_fd, &mh, 0);
2153   if (size != 5)
2154     {
2155       return (size == 0) ? clib_error_return (0, "disconnected") :
2156         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2157                                 socket_fd);
2158     }
2159
2160   cmsg = CMSG_FIRSTHDR (&mh);
2161   while (cmsg)
2162     {
2163       if (cmsg->cmsg_level == SOL_SOCKET)
2164         {
2165           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2166             {
2167               cr = (struct ucred *) CMSG_DATA (cmsg);
2168               uid = cr->uid;
2169               gid = cr->gid;
2170               pid = cr->pid;
2171             }
2172           else if (cmsg->cmsg_type == SCM_RIGHTS)
2173             {
2174               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2175             }
2176         }
2177       cmsg = CMSG_NXTHDR (&mh, cmsg);
2178     }
2179   return 0;
2180 }
2181
2182 static void vl_api_memfd_segment_create_reply_t_handler
2183   (vl_api_memfd_segment_create_reply_t * mp)
2184 {
2185   /* Dont bother in the builtin version */
2186 #if VPP_API_TEST_BUILTIN == 0
2187   vat_main_t *vam = &vat_main;
2188   api_main_t *am = &api_main;
2189   socket_client_main_t *scm = &vam->socket_client_main;
2190   int my_fd = -1;
2191   clib_error_t *error;
2192   memfd_private_t memfd;
2193   i32 retval = ntohl (mp->retval);
2194
2195   if (retval == 0)
2196     {
2197       error = receive_fd_msg (scm->socket_fd, &my_fd);
2198       if (error)
2199         {
2200           retval = -99;
2201           goto out;
2202         }
2203
2204       memset (&memfd, 0, sizeof (memfd));
2205       memfd.fd = my_fd;
2206
2207       vam->client_index_invalid = 1;
2208
2209       /* Note: this closes memfd.fd */
2210       retval = memfd_slave_init (&memfd);
2211       if (retval)
2212         clib_warning ("WARNING: segment map returned %d", retval);
2213
2214       /* Pivot to the memory client segment that vpp just created */
2215
2216       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2217
2218       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2219
2220       vl_client_install_client_message_handlers ();
2221
2222       vl_client_connect_to_vlib_no_map ("pvt",
2223                                         "vpp_api_test(p)",
2224                                         32 /* input_queue_length */ );
2225       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2226
2227       vl_socket_client_enable_disable (&vam->socket_client_main,
2228                                        0 /* disable socket */ );
2229     }
2230
2231 out:
2232   if (vam->async_mode)
2233     {
2234       vam->async_errors += (retval < 0);
2235     }
2236   else
2237     {
2238       vam->retval = retval;
2239       vam->result_ready = 1;
2240     }
2241 #endif
2242 }
2243
2244 static void vl_api_memfd_segment_create_reply_t_handler_json
2245   (vl_api_memfd_segment_create_reply_t * mp)
2246 {
2247   clib_warning ("no");
2248 }
2249
2250 static void vl_api_dns_resolve_name_reply_t_handler
2251   (vl_api_dns_resolve_name_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       vam->retval = retval;
2262       vam->result_ready = 1;
2263
2264       if (retval == 0)
2265         {
2266           if (mp->ip4_set)
2267             clib_warning ("ip4 address %U", format_ip4_address,
2268                           (ip4_address_t *) mp->ip4_address);
2269           if (mp->ip6_set)
2270             clib_warning ("ip6 address %U", format_ip6_address,
2271                           (ip6_address_t *) mp->ip6_address);
2272         }
2273       else
2274         clib_warning ("retval %d", retval);
2275     }
2276 }
2277
2278 static void vl_api_dns_resolve_name_reply_t_handler_json
2279   (vl_api_dns_resolve_name_reply_t * mp)
2280 {
2281   clib_warning ("not implemented");
2282 }
2283
2284 static void vl_api_dns_resolve_ip_reply_t_handler
2285   (vl_api_dns_resolve_ip_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   i32 retval = ntohl (mp->retval);
2289   if (vam->async_mode)
2290     {
2291       vam->async_errors += (retval < 0);
2292     }
2293   else
2294     {
2295       vam->retval = retval;
2296       vam->result_ready = 1;
2297
2298       if (retval == 0)
2299         {
2300           clib_warning ("canonical name %s", mp->name);
2301         }
2302       else
2303         clib_warning ("retval %d", retval);
2304     }
2305 }
2306
2307 static void vl_api_dns_resolve_ip_reply_t_handler_json
2308   (vl_api_dns_resolve_ip_reply_t * mp)
2309 {
2310   clib_warning ("not implemented");
2311 }
2312
2313
2314 static void vl_api_ip_address_details_t_handler
2315   (vl_api_ip_address_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   static ip_address_details_t empty_ip_address_details = { {0} };
2319   ip_address_details_t *address = NULL;
2320   ip_details_t *current_ip_details = NULL;
2321   ip_details_t *details = NULL;
2322
2323   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2324
2325   if (!details || vam->current_sw_if_index >= vec_len (details)
2326       || !details[vam->current_sw_if_index].present)
2327     {
2328       errmsg ("ip address details arrived but not stored");
2329       errmsg ("ip_dump should be called first");
2330       return;
2331     }
2332
2333   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2334
2335 #define addresses (current_ip_details->addr)
2336
2337   vec_validate_init_empty (addresses, vec_len (addresses),
2338                            empty_ip_address_details);
2339
2340   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2341
2342   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2343   address->prefix_length = mp->prefix_length;
2344 #undef addresses
2345 }
2346
2347 static void vl_api_ip_address_details_t_handler_json
2348   (vl_api_ip_address_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   vat_json_node_t *node = NULL;
2352   struct in6_addr ip6;
2353   struct in_addr ip4;
2354
2355   if (VAT_JSON_ARRAY != vam->json_tree.type)
2356     {
2357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2358       vat_json_init_array (&vam->json_tree);
2359     }
2360   node = vat_json_array_add (&vam->json_tree);
2361
2362   vat_json_init_object (node);
2363   if (vam->is_ipv6)
2364     {
2365       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2366       vat_json_object_add_ip6 (node, "ip", ip6);
2367     }
2368   else
2369     {
2370       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2371       vat_json_object_add_ip4 (node, "ip", ip4);
2372     }
2373   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2374 }
2375
2376 static void
2377 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   static ip_details_t empty_ip_details = { 0 };
2381   ip_details_t *ip = NULL;
2382   u32 sw_if_index = ~0;
2383
2384   sw_if_index = ntohl (mp->sw_if_index);
2385
2386   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2387                            sw_if_index, empty_ip_details);
2388
2389   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2390                          sw_if_index);
2391
2392   ip->present = 1;
2393 }
2394
2395 static void
2396 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   if (VAT_JSON_ARRAY != vam->json_tree.type)
2401     {
2402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2403       vat_json_init_array (&vam->json_tree);
2404     }
2405   vat_json_array_add_uint (&vam->json_tree,
2406                            clib_net_to_host_u32 (mp->sw_if_index));
2407 }
2408
2409 static void vl_api_map_domain_details_t_handler_json
2410   (vl_api_map_domain_details_t * mp)
2411 {
2412   vat_json_node_t *node = NULL;
2413   vat_main_t *vam = &vat_main;
2414   struct in6_addr ip6;
2415   struct in_addr ip4;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422
2423   node = vat_json_array_add (&vam->json_tree);
2424   vat_json_init_object (node);
2425
2426   vat_json_object_add_uint (node, "domain_index",
2427                             clib_net_to_host_u32 (mp->domain_index));
2428   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2429   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2430   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2431   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2432   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2433   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2434   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2435   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2436   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2437   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2438   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2439   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2440   vat_json_object_add_uint (node, "flags", mp->flags);
2441   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2442   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2443 }
2444
2445 static void vl_api_map_domain_details_t_handler
2446   (vl_api_map_domain_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   if (mp->is_translation)
2451     {
2452       print (vam->ofp,
2453              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2454              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2455              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2456              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2457              clib_net_to_host_u32 (mp->domain_index));
2458     }
2459   else
2460     {
2461       print (vam->ofp,
2462              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2463              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2464              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2465              format_ip6_address, mp->ip6_src,
2466              clib_net_to_host_u32 (mp->domain_index));
2467     }
2468   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2469          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2470          mp->is_translation ? "map-t" : "");
2471 }
2472
2473 static void vl_api_map_rule_details_t_handler_json
2474   (vl_api_map_rule_details_t * mp)
2475 {
2476   struct in6_addr ip6;
2477   vat_json_node_t *node = NULL;
2478   vat_main_t *vam = &vat_main;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485
2486   node = vat_json_array_add (&vam->json_tree);
2487   vat_json_init_object (node);
2488
2489   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2490   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2491   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2492 }
2493
2494 static void
2495 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2499          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2500 }
2501
2502 static void
2503 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2504 {
2505   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2506           "router_addr %U host_mac %U",
2507           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2508           format_ip4_address, &mp->host_address,
2509           format_ip4_address, &mp->router_address,
2510           format_ethernet_address, mp->host_mac);
2511 }
2512
2513 static void vl_api_dhcp_compl_event_t_handler_json
2514   (vl_api_dhcp_compl_event_t * mp)
2515 {
2516   /* JSON output not supported */
2517 }
2518
2519 static void
2520 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2521                               u32 counter)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   static u64 default_counter = 0;
2525
2526   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2527                            NULL);
2528   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2529                            sw_if_index, default_counter);
2530   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2531 }
2532
2533 static void
2534 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2535                                 interface_counter_t counter)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   static interface_counter_t default_counter = { 0, };
2539
2540   vec_validate_init_empty (vam->combined_interface_counters,
2541                            vnet_counter_type, NULL);
2542   vec_validate_init_empty (vam->combined_interface_counters
2543                            [vnet_counter_type], sw_if_index, default_counter);
2544   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2545 }
2546
2547 static void vl_api_vnet_interface_simple_counters_t_handler
2548   (vl_api_vnet_interface_simple_counters_t * mp)
2549 {
2550   /* not supported */
2551 }
2552
2553 static void vl_api_vnet_interface_combined_counters_t_handler
2554   (vl_api_vnet_interface_combined_counters_t * mp)
2555 {
2556   /* not supported */
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler_json
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   u64 *v_packets;
2563   u64 packets;
2564   u32 count;
2565   u32 first_sw_if_index;
2566   int i;
2567
2568   count = ntohl (mp->count);
2569   first_sw_if_index = ntohl (mp->first_sw_if_index);
2570
2571   v_packets = (u64 *) & mp->data;
2572   for (i = 0; i < count; i++)
2573     {
2574       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2575       set_simple_interface_counter (mp->vnet_counter_type,
2576                                     first_sw_if_index + i, packets);
2577       v_packets++;
2578     }
2579 }
2580
2581 static void vl_api_vnet_interface_combined_counters_t_handler_json
2582   (vl_api_vnet_interface_combined_counters_t * mp)
2583 {
2584   interface_counter_t counter;
2585   vlib_counter_t *v;
2586   u32 first_sw_if_index;
2587   int i;
2588   u32 count;
2589
2590   count = ntohl (mp->count);
2591   first_sw_if_index = ntohl (mp->first_sw_if_index);
2592
2593   v = (vlib_counter_t *) & mp->data;
2594   for (i = 0; i < count; i++)
2595     {
2596       counter.packets =
2597         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2598       counter.bytes =
2599         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2600       set_combined_interface_counter (mp->vnet_counter_type,
2601                                       first_sw_if_index + i, counter);
2602       v++;
2603     }
2604 }
2605
2606 static u32
2607 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i;
2611
2612   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2613     {
2614       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2615         {
2616           return i;
2617         }
2618     }
2619   return ~0;
2620 }
2621
2622 static u32
2623 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static void vl_api_vnet_ip4_fib_counters_t_handler
2639   (vl_api_vnet_ip4_fib_counters_t * mp)
2640 {
2641   /* not supported */
2642 }
2643
2644 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2645   (vl_api_vnet_ip4_fib_counters_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vl_api_ip4_fib_counter_t *v;
2649   ip4_fib_counter_t *counter;
2650   struct in_addr ip4;
2651   u32 vrf_id;
2652   u32 vrf_index;
2653   u32 count;
2654   int i;
2655
2656   vrf_id = ntohl (mp->vrf_id);
2657   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2658   if (~0 == vrf_index)
2659     {
2660       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2661       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2662       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2663       vec_validate (vam->ip4_fib_counters, vrf_index);
2664       vam->ip4_fib_counters[vrf_index] = NULL;
2665     }
2666
2667   vec_free (vam->ip4_fib_counters[vrf_index]);
2668   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2669   count = ntohl (mp->count);
2670   for (i = 0; i < count; i++)
2671     {
2672       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2673       counter = &vam->ip4_fib_counters[vrf_index][i];
2674       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2675       counter->address = ip4;
2676       counter->address_length = v->address_length;
2677       counter->packets = clib_net_to_host_u64 (v->packets);
2678       counter->bytes = clib_net_to_host_u64 (v->bytes);
2679       v++;
2680     }
2681 }
2682
2683 static void vl_api_vnet_ip4_nbr_counters_t_handler
2684   (vl_api_vnet_ip4_nbr_counters_t * mp)
2685 {
2686   /* not supported */
2687 }
2688
2689 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2690   (vl_api_vnet_ip4_nbr_counters_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vl_api_ip4_nbr_counter_t *v;
2694   ip4_nbr_counter_t *counter;
2695   u32 sw_if_index;
2696   u32 count;
2697   int i;
2698
2699   sw_if_index = ntohl (mp->sw_if_index);
2700   count = ntohl (mp->count);
2701   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2702
2703   if (mp->begin)
2704     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2705
2706   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2707   for (i = 0; i < count; i++)
2708     {
2709       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2710       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2711       counter->address.s_addr = v->address;
2712       counter->packets = clib_net_to_host_u64 (v->packets);
2713       counter->bytes = clib_net_to_host_u64 (v->bytes);
2714       counter->linkt = v->link_type;
2715       v++;
2716     }
2717 }
2718
2719 static void vl_api_vnet_ip6_fib_counters_t_handler
2720   (vl_api_vnet_ip6_fib_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2726   (vl_api_vnet_ip6_fib_counters_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   vl_api_ip6_fib_counter_t *v;
2730   ip6_fib_counter_t *counter;
2731   struct in6_addr ip6;
2732   u32 vrf_id;
2733   u32 vrf_index;
2734   u32 count;
2735   int i;
2736
2737   vrf_id = ntohl (mp->vrf_id);
2738   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2739   if (~0 == vrf_index)
2740     {
2741       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2742       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2743       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2744       vec_validate (vam->ip6_fib_counters, vrf_index);
2745       vam->ip6_fib_counters[vrf_index] = NULL;
2746     }
2747
2748   vec_free (vam->ip6_fib_counters[vrf_index]);
2749   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2750   count = ntohl (mp->count);
2751   for (i = 0; i < count; i++)
2752     {
2753       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2754       counter = &vam->ip6_fib_counters[vrf_index][i];
2755       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2756       counter->address = ip6;
2757       counter->address_length = v->address_length;
2758       counter->packets = clib_net_to_host_u64 (v->packets);
2759       counter->bytes = clib_net_to_host_u64 (v->bytes);
2760       v++;
2761     }
2762 }
2763
2764 static void vl_api_vnet_ip6_nbr_counters_t_handler
2765   (vl_api_vnet_ip6_nbr_counters_t * mp)
2766 {
2767   /* not supported */
2768 }
2769
2770 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2771   (vl_api_vnet_ip6_nbr_counters_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   vl_api_ip6_nbr_counter_t *v;
2775   ip6_nbr_counter_t *counter;
2776   struct in6_addr ip6;
2777   u32 sw_if_index;
2778   u32 count;
2779   int i;
2780
2781   sw_if_index = ntohl (mp->sw_if_index);
2782   count = ntohl (mp->count);
2783   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2784
2785   if (mp->begin)
2786     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2787
2788   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2789   for (i = 0; i < count; i++)
2790     {
2791       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2792       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2793       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2794       counter->address = ip6;
2795       counter->packets = clib_net_to_host_u64 (v->packets);
2796       counter->bytes = clib_net_to_host_u64 (v->bytes);
2797       v++;
2798     }
2799 }
2800
2801 static void vl_api_get_first_msg_id_reply_t_handler
2802   (vl_api_get_first_msg_id_reply_t * mp)
2803 {
2804   vat_main_t *vam = &vat_main;
2805   i32 retval = ntohl (mp->retval);
2806
2807   if (vam->async_mode)
2808     {
2809       vam->async_errors += (retval < 0);
2810     }
2811   else
2812     {
2813       vam->retval = retval;
2814       vam->result_ready = 1;
2815     }
2816   if (retval >= 0)
2817     {
2818       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2819     }
2820 }
2821
2822 static void vl_api_get_first_msg_id_reply_t_handler_json
2823   (vl_api_get_first_msg_id_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t node;
2827
2828   vat_json_init_object (&node);
2829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2830   vat_json_object_add_uint (&node, "first_msg_id",
2831                             (uint) ntohs (mp->first_msg_id));
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void vl_api_get_node_graph_reply_t_handler
2841   (vl_api_get_node_graph_reply_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   api_main_t *am = &api_main;
2845   i32 retval = ntohl (mp->retval);
2846   u8 *pvt_copy, *reply;
2847   void *oldheap;
2848   vlib_node_t *node;
2849   int i;
2850
2851   if (vam->async_mode)
2852     {
2853       vam->async_errors += (retval < 0);
2854     }
2855   else
2856     {
2857       vam->retval = retval;
2858       vam->result_ready = 1;
2859     }
2860
2861   /* "Should never happen..." */
2862   if (retval != 0)
2863     return;
2864
2865   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2866   pvt_copy = vec_dup (reply);
2867
2868   /* Toss the shared-memory original... */
2869   pthread_mutex_lock (&am->vlib_rp->mutex);
2870   oldheap = svm_push_data_heap (am->vlib_rp);
2871
2872   vec_free (reply);
2873
2874   svm_pop_heap (oldheap);
2875   pthread_mutex_unlock (&am->vlib_rp->mutex);
2876
2877   if (vam->graph_nodes)
2878     {
2879       hash_free (vam->graph_node_index_by_name);
2880
2881       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2882         {
2883           node = vam->graph_nodes[i];
2884           vec_free (node->name);
2885           vec_free (node->next_nodes);
2886           vec_free (node);
2887         }
2888       vec_free (vam->graph_nodes);
2889     }
2890
2891   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2892   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2893   vec_free (pvt_copy);
2894
2895   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2896     {
2897       node = vam->graph_nodes[i];
2898       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2899     }
2900 }
2901
2902 static void vl_api_get_node_graph_reply_t_handler_json
2903   (vl_api_get_node_graph_reply_t * mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   api_main_t *am = &api_main;
2907   void *oldheap;
2908   vat_json_node_t node;
2909   u8 *reply;
2910
2911   /* $$$$ make this real? */
2912   vat_json_init_object (&node);
2913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2914   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2915
2916   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2917
2918   /* Toss the shared-memory original... */
2919   pthread_mutex_lock (&am->vlib_rp->mutex);
2920   oldheap = svm_push_data_heap (am->vlib_rp);
2921
2922   vec_free (reply);
2923
2924   svm_pop_heap (oldheap);
2925   pthread_mutex_unlock (&am->vlib_rp->mutex);
2926
2927   vat_json_print (vam->ofp, &node);
2928   vat_json_free (&node);
2929
2930   vam->retval = ntohl (mp->retval);
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   u8 *s = 0;
2939
2940   if (mp->local)
2941     {
2942       s = format (s, "%=16d%=16d%=16d",
2943                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2944     }
2945   else
2946     {
2947       s = format (s, "%=16U%=16d%=16d",
2948                   mp->is_ipv6 ? format_ip6_address :
2949                   format_ip4_address,
2950                   mp->ip_address, mp->priority, mp->weight);
2951     }
2952
2953   print (vam->ofp, "%v", s);
2954   vec_free (s);
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t *node = NULL;
2962   struct in6_addr ip6;
2963   struct in_addr ip4;
2964
2965   if (VAT_JSON_ARRAY != vam->json_tree.type)
2966     {
2967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2968       vat_json_init_array (&vam->json_tree);
2969     }
2970   node = vat_json_array_add (&vam->json_tree);
2971   vat_json_init_object (node);
2972
2973   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2974   vat_json_object_add_uint (node, "priority", mp->priority);
2975   vat_json_object_add_uint (node, "weight", mp->weight);
2976
2977   if (mp->local)
2978     vat_json_object_add_uint (node, "sw_if_index",
2979                               clib_net_to_host_u32 (mp->sw_if_index));
2980   else
2981     {
2982       if (mp->is_ipv6)
2983         {
2984           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2985           vat_json_object_add_ip6 (node, "address", ip6);
2986         }
2987       else
2988         {
2989           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2990           vat_json_object_add_ip4 (node, "address", ip4);
2991         }
2992     }
2993 }
2994
2995 static void
2996 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2997                                           mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   u8 *ls_name = 0;
3001
3002   ls_name = format (0, "%s", mp->ls_name);
3003
3004   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3005          ls_name);
3006   vec_free (ls_name);
3007 }
3008
3009 static void
3010   vl_api_one_locator_set_details_t_handler_json
3011   (vl_api_one_locator_set_details_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t *node = 0;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018   vec_add1 (ls_name, 0);
3019
3020   if (VAT_JSON_ARRAY != vam->json_tree.type)
3021     {
3022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3023       vat_json_init_array (&vam->json_tree);
3024     }
3025   node = vat_json_array_add (&vam->json_tree);
3026
3027   vat_json_init_object (node);
3028   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3029   vat_json_object_add_uint (node, "ls_index",
3030                             clib_net_to_host_u32 (mp->ls_index));
3031   vec_free (ls_name);
3032 }
3033
3034 typedef struct
3035 {
3036   u32 spi;
3037   u8 si;
3038 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3039
3040 uword
3041 unformat_nsh_address (unformat_input_t * input, va_list * args)
3042 {
3043   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3044   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3045 }
3046
3047 u8 *
3048 format_nsh_address_vat (u8 * s, va_list * args)
3049 {
3050   nsh_t *a = va_arg (*args, nsh_t *);
3051   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3052 }
3053
3054 static u8 *
3055 format_lisp_flat_eid (u8 * s, va_list * args)
3056 {
3057   u32 type = va_arg (*args, u32);
3058   u8 *eid = va_arg (*args, u8 *);
3059   u32 eid_len = va_arg (*args, u32);
3060
3061   switch (type)
3062     {
3063     case 0:
3064       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3065     case 1:
3066       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3067     case 2:
3068       return format (s, "%U", format_ethernet_address, eid);
3069     case 3:
3070       return format (s, "%U", format_nsh_address_vat, eid);
3071     }
3072   return 0;
3073 }
3074
3075 static u8 *
3076 format_lisp_eid_vat (u8 * s, va_list * args)
3077 {
3078   u32 type = va_arg (*args, u32);
3079   u8 *eid = va_arg (*args, u8 *);
3080   u32 eid_len = va_arg (*args, u32);
3081   u8 *seid = va_arg (*args, u8 *);
3082   u32 seid_len = va_arg (*args, u32);
3083   u32 is_src_dst = va_arg (*args, u32);
3084
3085   if (is_src_dst)
3086     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3087
3088   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3089
3090   return s;
3091 }
3092
3093 static void
3094 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   u8 *s = 0, *eid = 0;
3098
3099   if (~0 == mp->locator_set_index)
3100     s = format (0, "action: %d", mp->action);
3101   else
3102     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3103
3104   eid = format (0, "%U", format_lisp_eid_vat,
3105                 mp->eid_type,
3106                 mp->eid,
3107                 mp->eid_prefix_len,
3108                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109   vec_add1 (eid, 0);
3110
3111   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3112          clib_net_to_host_u32 (mp->vni),
3113          eid,
3114          mp->is_local ? "local" : "remote",
3115          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3116          clib_net_to_host_u16 (mp->key_id), mp->key);
3117
3118   vec_free (s);
3119   vec_free (eid);
3120 }
3121
3122 static void
3123 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3124                                              * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = 0;
3128   u8 *eid = 0;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136
3137   vat_json_init_object (node);
3138   if (~0 == mp->locator_set_index)
3139     vat_json_object_add_uint (node, "action", mp->action);
3140   else
3141     vat_json_object_add_uint (node, "locator_set_index",
3142                               clib_net_to_host_u32 (mp->locator_set_index));
3143
3144   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3145   if (mp->eid_type == 3)
3146     {
3147       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3148       vat_json_init_object (nsh_json);
3149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3150       vat_json_object_add_uint (nsh_json, "spi",
3151                                 clib_net_to_host_u32 (nsh->spi));
3152       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3153     }
3154   else
3155     {
3156       eid = format (0, "%U", format_lisp_eid_vat,
3157                     mp->eid_type,
3158                     mp->eid,
3159                     mp->eid_prefix_len,
3160                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3161       vec_add1 (eid, 0);
3162       vat_json_object_add_string_copy (node, "eid", eid);
3163       vec_free (eid);
3164     }
3165   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3166   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3167   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3168
3169   if (mp->key_id)
3170     {
3171       vat_json_object_add_uint (node, "key_id",
3172                                 clib_net_to_host_u16 (mp->key_id));
3173       vat_json_object_add_string_copy (node, "key", mp->key);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   u8 *seid = 0, *deid = 0;
3182   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3183
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   if (mp->is_ip4)
3194     format_ip_address_fcn = format_ip4_address;
3195   else
3196     format_ip_address_fcn = format_ip6_address;
3197
3198
3199   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3200          clib_net_to_host_u32 (mp->vni),
3201          seid, deid,
3202          format_ip_address_fcn, mp->lloc,
3203          format_ip_address_fcn, mp->rloc,
3204          clib_net_to_host_u32 (mp->pkt_count),
3205          clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3213 {
3214   struct in6_addr ip6;
3215   struct in_addr ip4;
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node = 0;
3218   u8 *deid = 0, *seid = 0;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   deid = format (0, "%U", format_lisp_eid_vat,
3229                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3230
3231   seid = format (0, "%U", format_lisp_eid_vat,
3232                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3233
3234   vec_add1 (deid, 0);
3235   vec_add1 (seid, 0);
3236
3237   vat_json_object_add_string_copy (node, "seid", seid);
3238   vat_json_object_add_string_copy (node, "deid", deid);
3239   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3240
3241   if (mp->is_ip4)
3242     {
3243       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3244       vat_json_object_add_ip4 (node, "lloc", ip4);
3245       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "rloc", ip4);
3247     }
3248   else
3249     {
3250       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3251       vat_json_object_add_ip6 (node, "lloc", ip6);
3252       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3253       vat_json_object_add_ip6 (node, "rloc", ip6);
3254     }
3255   vat_json_object_add_uint (node, "pkt_count",
3256                             clib_net_to_host_u32 (mp->pkt_count));
3257   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3258
3259   vec_free (deid);
3260   vec_free (seid);
3261 }
3262
3263 static void
3264   vl_api_one_eid_table_map_details_t_handler
3265   (vl_api_one_eid_table_map_details_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268
3269   u8 *line = format (0, "%=10d%=10d",
3270                      clib_net_to_host_u32 (mp->vni),
3271                      clib_net_to_host_u32 (mp->dp_table));
3272   print (vam->ofp, "%v", line);
3273   vec_free (line);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler_json
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node = NULL;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289   vat_json_init_object (node);
3290   vat_json_object_add_uint (node, "dp_table",
3291                             clib_net_to_host_u32 (mp->dp_table));
3292   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3293 }
3294
3295 static void
3296   vl_api_one_eid_table_vni_details_t_handler
3297   (vl_api_one_eid_table_vni_details_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3302   print (vam->ofp, "%v", line);
3303   vec_free (line);
3304 }
3305
3306 static void
3307   vl_api_one_eid_table_vni_details_t_handler_json
3308   (vl_api_one_eid_table_vni_details_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t *node = NULL;
3312
3313   if (VAT_JSON_ARRAY != vam->json_tree.type)
3314     {
3315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3316       vat_json_init_array (&vam->json_tree);
3317     }
3318   node = vat_json_array_add (&vam->json_tree);
3319   vat_json_init_object (node);
3320   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3325   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3331   print (vam->ofp, "fallback threshold value: %d", mp->value);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3339   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   vat_json_init_object (node);
3347   vat_json_object_add_uint (node, "value", mp->value);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354 }
3355
3356 static void
3357   vl_api_show_one_map_register_state_reply_t_handler
3358   (vl_api_show_one_map_register_state_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   int retval = clib_net_to_host_u32 (mp->retval);
3362
3363   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler_json
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t _node, *node = &_node;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3378
3379   vat_json_init_object (node);
3380   vat_json_object_add_string_copy (node, "state", s);
3381
3382   vat_json_print (vam->ofp, node);
3383   vat_json_free (node);
3384
3385   vam->retval = retval;
3386   vam->result_ready = 1;
3387   vec_free (s);
3388 }
3389
3390 static void
3391   vl_api_show_one_rloc_probe_state_reply_t_handler
3392   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   int retval = clib_net_to_host_u32 (mp->retval);
3396
3397   if (retval)
3398     goto end;
3399
3400   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t _node, *node = &_node;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3415   vat_json_init_object (node);
3416   vat_json_object_add_string_copy (node, "state", s);
3417
3418   vat_json_print (vam->ofp, node);
3419   vat_json_free (node);
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423   vec_free (s);
3424 }
3425
3426 static void
3427   vl_api_show_one_stats_enable_disable_reply_t_handler
3428   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   int retval = clib_net_to_host_u32 (mp->retval);
3432
3433   if (retval)
3434     goto end;
3435
3436   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3437 end:
3438   vam->retval = retval;
3439   vam->result_ready = 1;
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t _node, *node = &_node;
3448   int retval = clib_net_to_host_u32 (mp->retval);
3449
3450   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3451   vat_json_init_object (node);
3452   vat_json_object_add_string_copy (node, "state", s);
3453
3454   vat_json_print (vam->ofp, node);
3455   vat_json_free (node);
3456
3457   vam->retval = retval;
3458   vam->result_ready = 1;
3459   vec_free (s);
3460 }
3461
3462 static void
3463 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3464 {
3465   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3466   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3467   e->vni = clib_net_to_host_u32 (e->vni);
3468 }
3469
3470 static void
3471   gpe_fwd_entries_get_reply_t_net_to_host
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u32 i;
3475
3476   mp->count = clib_net_to_host_u32 (mp->count);
3477   for (i = 0; i < mp->count; i++)
3478     {
3479       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3480     }
3481 }
3482
3483 static u8 *
3484 format_gpe_encap_mode (u8 * s, va_list * args)
3485 {
3486   u32 mode = va_arg (*args, u32);
3487
3488   switch (mode)
3489     {
3490     case 0:
3491       return format (s, "lisp");
3492     case 1:
3493       return format (s, "vxlan");
3494     }
3495   return 0;
3496 }
3497
3498 static void
3499   vl_api_gpe_get_encap_mode_reply_t_handler
3500   (vl_api_gpe_get_encap_mode_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503
3504   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3505   vam->retval = ntohl (mp->retval);
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510   vl_api_gpe_get_encap_mode_reply_t_handler_json
3511   (vl_api_gpe_get_encap_mode_reply_t * mp)
3512 {
3513   vat_main_t *vam = &vat_main;
3514   vat_json_node_t node;
3515
3516   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3517   vec_add1 (encap_mode, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3521
3522   vec_free (encap_mode);
3523   vat_json_print (vam->ofp, &node);
3524   vat_json_free (&node);
3525
3526   vam->retval = ntohl (mp->retval);
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_fwd_entry_path_details_t_handler
3532   (vl_api_gpe_fwd_entry_path_details_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3536
3537   if (mp->lcl_loc.is_ip4)
3538     format_ip_address_fcn = format_ip4_address;
3539   else
3540     format_ip_address_fcn = format_ip6_address;
3541
3542   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3543          format_ip_address_fcn, &mp->lcl_loc,
3544          format_ip_address_fcn, &mp->rmt_loc);
3545 }
3546
3547 static void
3548 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3549 {
3550   struct in6_addr ip6;
3551   struct in_addr ip4;
3552
3553   if (loc->is_ip4)
3554     {
3555       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3556       vat_json_object_add_ip4 (n, "address", ip4);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3561       vat_json_object_add_ip6 (n, "address", ip6);
3562     }
3563   vat_json_object_add_uint (n, "weight", loc->weight);
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entry_path_details_t_handler_json
3568   (vl_api_gpe_fwd_entry_path_details_t * mp)
3569 {
3570   vat_main_t *vam = &vat_main;
3571   vat_json_node_t *node = NULL;
3572   vat_json_node_t *loc_node;
3573
3574   if (VAT_JSON_ARRAY != vam->json_tree.type)
3575     {
3576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3577       vat_json_init_array (&vam->json_tree);
3578     }
3579   node = vat_json_array_add (&vam->json_tree);
3580   vat_json_init_object (node);
3581
3582   loc_node = vat_json_object_add (node, "local_locator");
3583   vat_json_init_object (loc_node);
3584   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3585
3586   loc_node = vat_json_object_add (node, "remote_locator");
3587   vat_json_init_object (loc_node);
3588   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3589 }
3590
3591 static void
3592   vl_api_gpe_fwd_entries_get_reply_t_handler
3593   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   u32 i;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_fwd_entry_t *e;
3599
3600   if (retval)
3601     goto end;
3602
3603   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3604
3605   for (i = 0; i < mp->count; i++)
3606     {
3607       e = &mp->entries[i];
3608       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3609              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3610              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3611     }
3612
3613 end:
3614   vam->retval = retval;
3615   vam->result_ready = 1;
3616 }
3617
3618 static void
3619   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3620   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3621 {
3622   u8 *s = 0;
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t *e = 0, root;
3625   u32 i;
3626   int retval = clib_net_to_host_u32 (mp->retval);
3627   vl_api_gpe_fwd_entry_t *fwd;
3628
3629   if (retval)
3630     goto end;
3631
3632   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < mp->count; i++)
3636     {
3637       e = vat_json_array_add (&root);
3638       fwd = &mp->entries[i];
3639
3640       vat_json_init_object (e);
3641       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3642       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3643       vat_json_object_add_int (e, "vni", fwd->vni);
3644       vat_json_object_add_int (e, "action", fwd->action);
3645
3646       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3647                   fwd->leid_prefix_len);
3648       vec_add1 (s, 0);
3649       vat_json_object_add_string_copy (e, "leid", s);
3650       vec_free (s);
3651
3652       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3653                   fwd->reid_prefix_len);
3654       vec_add1 (s, 0);
3655       vat_json_object_add_string_copy (e, "reid", s);
3656       vec_free (s);
3657     }
3658
3659   vat_json_print (vam->ofp, &root);
3660   vat_json_free (&root);
3661
3662 end:
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3669   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_gpe_native_fwd_rpath_t *r;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680
3681   for (i = 0; i < n; i++)
3682     {
3683       r = &mp->entries[i];
3684       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3685              clib_net_to_host_u32 (r->fib_index),
3686              clib_net_to_host_u32 (r->nh_sw_if_index),
3687              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3688     }
3689
3690 end:
3691   vam->retval = retval;
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3697   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   vat_json_node_t root, *e;
3701   u32 i, n;
3702   int retval = clib_net_to_host_u32 (mp->retval);
3703   vl_api_gpe_native_fwd_rpath_t *r;
3704   u8 *s;
3705
3706   if (retval)
3707     goto end;
3708
3709   n = clib_net_to_host_u32 (mp->count);
3710   vat_json_init_array (&root);
3711
3712   for (i = 0; i < n; i++)
3713     {
3714       e = vat_json_array_add (&root);
3715       vat_json_init_object (e);
3716       r = &mp->entries[i];
3717       s =
3718         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3719                 r->nh_addr);
3720       vec_add1 (s, 0);
3721       vat_json_object_add_string_copy (e, "ip4", s);
3722       vec_free (s);
3723
3724       vat_json_object_add_uint (e, "fib_index",
3725                                 clib_net_to_host_u32 (r->fib_index));
3726       vat_json_object_add_uint (e, "nh_sw_if_index",
3727                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3728     }
3729
3730   vat_json_print (vam->ofp, &root);
3731   vat_json_free (&root);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3740   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743   u32 i, n;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745
3746   if (retval)
3747     goto end;
3748
3749   n = clib_net_to_host_u32 (mp->count);
3750
3751   for (i = 0; i < n; i++)
3752     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3753
3754 end:
3755   vam->retval = retval;
3756   vam->result_ready = 1;
3757 }
3758
3759 static void
3760   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3761   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   vat_json_node_t root;
3765   u32 i, n;
3766   int retval = clib_net_to_host_u32 (mp->retval);
3767
3768   if (retval)
3769     goto end;
3770
3771   n = clib_net_to_host_u32 (mp->count);
3772   vat_json_init_array (&root);
3773
3774   for (i = 0; i < n; i++)
3775     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_one_ndp_entries_get_reply_t_handler
3787   (vl_api_one_ndp_entries_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3800            format_ethernet_address, mp->entries[i].mac);
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_entries_get_reply_t_handler_json
3809   (vl_api_one_ndp_entries_get_reply_t * mp)
3810 {
3811   u8 *s = 0;
3812   vat_main_t *vam = &vat_main;
3813   vat_json_node_t *e = 0, root;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816   vl_api_one_ndp_entry_t *arp_entry;
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822   vat_json_init_array (&root);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       e = vat_json_array_add (&root);
3827       arp_entry = &mp->entries[i];
3828
3829       vat_json_init_object (e);
3830       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3831       vec_add1 (s, 0);
3832
3833       vat_json_object_add_string_copy (e, "mac", s);
3834       vec_free (s);
3835
3836       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip6", s);
3839       vec_free (s);
3840     }
3841
3842   vat_json_print (vam->ofp, &root);
3843   vat_json_free (&root);
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_entries_get_reply_t_handler
3852   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   u32 i, n;
3856   int retval = clib_net_to_host_u32 (mp->retval);
3857
3858   if (retval)
3859     goto end;
3860
3861   n = clib_net_to_host_u32 (mp->count);
3862
3863   for (i = 0; i < n; i++)
3864     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3865            format_ethernet_address, mp->entries[i].mac);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3874   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3875 {
3876   u8 *s = 0;
3877   vat_main_t *vam = &vat_main;
3878   vat_json_node_t *e = 0, root;
3879   u32 i, n;
3880   int retval = clib_net_to_host_u32 (mp->retval);
3881   vl_api_one_l2_arp_entry_t *arp_entry;
3882
3883   if (retval)
3884     goto end;
3885
3886   n = clib_net_to_host_u32 (mp->count);
3887   vat_json_init_array (&root);
3888
3889   for (i = 0; i < n; i++)
3890     {
3891       e = vat_json_array_add (&root);
3892       arp_entry = &mp->entries[i];
3893
3894       vat_json_init_object (e);
3895       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3896       vec_add1 (s, 0);
3897
3898       vat_json_object_add_string_copy (e, "mac", s);
3899       vec_free (s);
3900
3901       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3902       vec_add1 (s, 0);
3903       vat_json_object_add_string_copy (e, "ip4", s);
3904       vec_free (s);
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_ndp_bd_get_reply_t_handler_json
3939   (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_l2_arp_bd_get_reply_t_handler
3968   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973
3974   if (retval)
3975     goto end;
3976
3977   n = clib_net_to_host_u32 (mp->count);
3978
3979   for (i = 0; i < n; i++)
3980     {
3981       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3982     }
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   vat_json_node_t root;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002   vat_json_init_array (&root);
4003
4004   for (i = 0; i < n; i++)
4005     {
4006       vat_json_array_add_uint (&root,
4007                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4008     }
4009
4010   vat_json_print (vam->ofp, &root);
4011   vat_json_free (&root);
4012
4013 end:
4014   vam->retval = retval;
4015   vam->result_ready = 1;
4016 }
4017
4018 static void
4019   vl_api_one_adjacencies_get_reply_t_handler
4020   (vl_api_one_adjacencies_get_reply_t * mp)
4021 {
4022   vat_main_t *vam = &vat_main;
4023   u32 i, n;
4024   int retval = clib_net_to_host_u32 (mp->retval);
4025   vl_api_one_adjacency_t *a;
4026
4027   if (retval)
4028     goto end;
4029
4030   n = clib_net_to_host_u32 (mp->count);
4031
4032   for (i = 0; i < n; i++)
4033     {
4034       a = &mp->adjacencies[i];
4035       print (vam->ofp, "%U %40U",
4036              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4037              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4038     }
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_adjacencies_get_reply_t_handler_json
4047   (vl_api_one_adjacencies_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_adjacency_t *a;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       a = &mp->adjacencies[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4069                   a->leid_prefix_len);
4070       vec_add1 (s, 0);
4071       vat_json_object_add_string_copy (e, "leid", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4075                   a->reid_prefix_len);
4076       vec_add1 (s, 0);
4077       vat_json_object_add_string_copy (e, "reid", s);
4078       vec_free (s);
4079     }
4080
4081   vat_json_print (vam->ofp, &root);
4082   vat_json_free (&root);
4083
4084 end:
4085   vam->retval = retval;
4086   vam->result_ready = 1;
4087 }
4088
4089 static void
4090 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093
4094   print (vam->ofp, "%=20U",
4095          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4096          mp->ip_address);
4097 }
4098
4099 static void
4100   vl_api_one_map_server_details_t_handler_json
4101   (vl_api_one_map_server_details_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105   struct in6_addr ip6;
4106   struct in_addr ip4;
4107
4108   if (VAT_JSON_ARRAY != vam->json_tree.type)
4109     {
4110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4111       vat_json_init_array (&vam->json_tree);
4112     }
4113   node = vat_json_array_add (&vam->json_tree);
4114
4115   vat_json_init_object (node);
4116   if (mp->is_ipv6)
4117     {
4118       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4119       vat_json_object_add_ip6 (node, "map-server", ip6);
4120     }
4121   else
4122     {
4123       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4124       vat_json_object_add_ip4 (node, "map-server", ip4);
4125     }
4126 }
4127
4128 static void
4129 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4130                                            * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133
4134   print (vam->ofp, "%=20U",
4135          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4136          mp->ip_address);
4137 }
4138
4139 static void
4140   vl_api_one_map_resolver_details_t_handler_json
4141   (vl_api_one_map_resolver_details_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t *node = NULL;
4145   struct in6_addr ip6;
4146   struct in_addr ip4;
4147
4148   if (VAT_JSON_ARRAY != vam->json_tree.type)
4149     {
4150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4151       vat_json_init_array (&vam->json_tree);
4152     }
4153   node = vat_json_array_add (&vam->json_tree);
4154
4155   vat_json_init_object (node);
4156   if (mp->is_ipv6)
4157     {
4158       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4159       vat_json_object_add_ip6 (node, "map resolver", ip6);
4160     }
4161   else
4162     {
4163       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4164       vat_json_object_add_ip4 (node, "map resolver", ip4);
4165     }
4166 }
4167
4168 static void
4169 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4170 {
4171   vat_main_t *vam = &vat_main;
4172   i32 retval = ntohl (mp->retval);
4173
4174   if (0 <= retval)
4175     {
4176       print (vam->ofp, "feature: %s\ngpe: %s",
4177              mp->feature_status ? "enabled" : "disabled",
4178              mp->gpe_status ? "enabled" : "disabled");
4179     }
4180
4181   vam->retval = retval;
4182   vam->result_ready = 1;
4183 }
4184
4185 static void
4186   vl_api_show_one_status_reply_t_handler_json
4187   (vl_api_show_one_status_reply_t * mp)
4188 {
4189   vat_main_t *vam = &vat_main;
4190   vat_json_node_t node;
4191   u8 *gpe_status = NULL;
4192   u8 *feature_status = NULL;
4193
4194   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4195   feature_status = format (0, "%s",
4196                            mp->feature_status ? "enabled" : "disabled");
4197   vec_add1 (gpe_status, 0);
4198   vec_add1 (feature_status, 0);
4199
4200   vat_json_init_object (&node);
4201   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4202   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4203
4204   vec_free (gpe_status);
4205   vec_free (feature_status);
4206
4207   vat_json_print (vam->ofp, &node);
4208   vat_json_free (&node);
4209
4210   vam->retval = ntohl (mp->retval);
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4216   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   i32 retval = ntohl (mp->retval);
4220
4221   if (retval >= 0)
4222     {
4223       print (vam->ofp, "%=20s", mp->locator_set_name);
4224     }
4225
4226   vam->retval = retval;
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   vat_json_node_t *node = NULL;
4236
4237   if (VAT_JSON_ARRAY != vam->json_tree.type)
4238     {
4239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4240       vat_json_init_array (&vam->json_tree);
4241     }
4242   node = vat_json_array_add (&vam->json_tree);
4243
4244   vat_json_init_object (node);
4245   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4246
4247   vat_json_print (vam->ofp, node);
4248   vat_json_free (node);
4249
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static u8 *
4255 format_lisp_map_request_mode (u8 * s, va_list * args)
4256 {
4257   u32 mode = va_arg (*args, u32);
4258
4259   switch (mode)
4260     {
4261     case 0:
4262       return format (0, "dst-only");
4263     case 1:
4264       return format (0, "src-dst");
4265     }
4266   return 0;
4267 }
4268
4269 static void
4270   vl_api_show_one_map_request_mode_reply_t_handler
4271   (vl_api_show_one_map_request_mode_reply_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274   i32 retval = ntohl (mp->retval);
4275
4276   if (0 <= retval)
4277     {
4278       u32 mode = mp->mode;
4279       print (vam->ofp, "map_request_mode: %U",
4280              format_lisp_map_request_mode, mode);
4281     }
4282
4283   vam->retval = retval;
4284   vam->result_ready = 1;
4285 }
4286
4287 static void
4288   vl_api_show_one_map_request_mode_reply_t_handler_json
4289   (vl_api_show_one_map_request_mode_reply_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t node;
4293   u8 *s = 0;
4294   u32 mode;
4295
4296   mode = mp->mode;
4297   s = format (0, "%U", format_lisp_map_request_mode, mode);
4298   vec_add1 (s, 0);
4299
4300   vat_json_init_object (&node);
4301   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vec_free (s);
4306   vam->retval = ntohl (mp->retval);
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_one_show_xtr_mode_reply_t_handler
4312   (vl_api_one_show_xtr_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316
4317   if (0 <= retval)
4318     {
4319       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4320     }
4321
4322   vam->retval = retval;
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler_json
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   vat_json_node_t node;
4332   u8 *status = 0;
4333
4334   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4335   vec_add1 (status, 0);
4336
4337   vat_json_init_object (&node);
4338   vat_json_object_add_string_copy (&node, "status", status);
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_pitr_mode_reply_t_handler
4351   (vl_api_one_show_pitr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler_json
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371   u8 *status = 0;
4372
4373   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4374   vec_add1 (status, 0);
4375
4376   vat_json_init_object (&node);
4377   vat_json_object_add_string_copy (&node, "status", status);
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_petr_mode_reply_t_handler
4390   (vl_api_one_show_petr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   if (0 <= retval)
4396     {
4397       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler_json
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *status = 0;
4411
4412   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4413   vec_add1 (status, 0);
4414
4415   vat_json_init_object (&node);
4416   vat_json_object_add_string_copy (&node, "status", status);
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_show_one_use_petr_reply_t_handler
4429   (vl_api_show_one_use_petr_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4437       if (mp->status)
4438         {
4439           print (vam->ofp, "Proxy-ETR address; %U",
4440                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4441                  mp->address);
4442         }
4443     }
4444
4445   vam->retval = retval;
4446   vam->result_ready = 1;
4447 }
4448
4449 static void
4450   vl_api_show_one_use_petr_reply_t_handler_json
4451   (vl_api_show_one_use_petr_reply_t * mp)
4452 {
4453   vat_main_t *vam = &vat_main;
4454   vat_json_node_t node;
4455   u8 *status = 0;
4456   struct in_addr ip4;
4457   struct in6_addr ip6;
4458
4459   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4460   vec_add1 (status, 0);
4461
4462   vat_json_init_object (&node);
4463   vat_json_object_add_string_copy (&node, "status", status);
4464   if (mp->status)
4465     {
4466       if (mp->is_ip4)
4467         {
4468           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4469           vat_json_object_add_ip6 (&node, "address", ip6);
4470         }
4471       else
4472         {
4473           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4474           vat_json_object_add_ip4 (&node, "address", ip4);
4475         }
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_nsh_mapping_reply_t_handler
4489   (vl_api_show_one_nsh_mapping_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   if (0 <= retval)
4495     {
4496       print (vam->ofp, "%-20s%-16s",
4497              mp->is_set ? "set" : "not-set",
4498              mp->is_set ? (char *) mp->locator_set_name : "");
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_nsh_mapping_reply_t_handler_json
4507   (vl_api_show_one_nsh_mapping_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511   u8 *status = 0;
4512
4513   status = format (0, "%s", mp->is_set ? "yes" : "no");
4514   vec_add1 (status, 0);
4515
4516   vat_json_init_object (&node);
4517   vat_json_object_add_string_copy (&node, "is_set", status);
4518   if (mp->is_set)
4519     {
4520       vat_json_object_add_string_copy (&node, "locator_set",
4521                                        mp->locator_set_name);
4522     }
4523
4524   vec_free (status);
4525
4526   vat_json_print (vam->ofp, &node);
4527   vat_json_free (&node);
4528
4529   vam->retval = ntohl (mp->retval);
4530   vam->result_ready = 1;
4531 }
4532
4533 static void
4534   vl_api_show_one_map_register_ttl_reply_t_handler
4535   (vl_api_show_one_map_register_ttl_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   i32 retval = ntohl (mp->retval);
4539
4540   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4541
4542   if (0 <= retval)
4543     {
4544       print (vam->ofp, "ttl: %u", mp->ttl);
4545     }
4546
4547   vam->retval = retval;
4548   vam->result_ready = 1;
4549 }
4550
4551 static void
4552   vl_api_show_one_map_register_ttl_reply_t_handler_json
4553   (vl_api_show_one_map_register_ttl_reply_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   vat_json_node_t node;
4557
4558   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4559   vat_json_init_object (&node);
4560   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   i32 retval = ntohl (mp->retval);
4574
4575   if (0 <= retval)
4576     {
4577       print (vam->ofp, "%-20s%-16s",
4578              mp->status ? "enabled" : "disabled",
4579              mp->status ? (char *) mp->locator_set_name : "");
4580     }
4581
4582   vam->retval = retval;
4583   vam->result_ready = 1;
4584 }
4585
4586 static void
4587 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4588 {
4589   vat_main_t *vam = &vat_main;
4590   vat_json_node_t node;
4591   u8 *status = 0;
4592
4593   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4594   vec_add1 (status, 0);
4595
4596   vat_json_init_object (&node);
4597   vat_json_object_add_string_copy (&node, "status", status);
4598   if (mp->status)
4599     {
4600       vat_json_object_add_string_copy (&node, "locator_set",
4601                                        mp->locator_set_name);
4602     }
4603
4604   vec_free (status);
4605
4606   vat_json_print (vam->ofp, &node);
4607   vat_json_free (&node);
4608
4609   vam->retval = ntohl (mp->retval);
4610   vam->result_ready = 1;
4611 }
4612
4613 static u8 *
4614 format_policer_type (u8 * s, va_list * va)
4615 {
4616   u32 i = va_arg (*va, u32);
4617
4618   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4619     s = format (s, "1r2c");
4620   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4621     s = format (s, "1r3c");
4622   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4623     s = format (s, "2r3c-2698");
4624   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4625     s = format (s, "2r3c-4115");
4626   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4627     s = format (s, "2r3c-mef5cf1");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_policer_rate_type (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637
4638   if (i == SSE2_QOS_RATE_KBPS)
4639     s = format (s, "kbps");
4640   else if (i == SSE2_QOS_RATE_PPS)
4641     s = format (s, "pps");
4642   else
4643     s = format (s, "ILLEGAL");
4644   return s;
4645 }
4646
4647 static u8 *
4648 format_policer_round_type (u8 * s, va_list * va)
4649 {
4650   u32 i = va_arg (*va, u32);
4651
4652   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4653     s = format (s, "closest");
4654   else if (i == SSE2_QOS_ROUND_TO_UP)
4655     s = format (s, "up");
4656   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4657     s = format (s, "down");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_action_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ACTION_DROP)
4669     s = format (s, "drop");
4670   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4671     s = format (s, "transmit");
4672   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4673     s = format (s, "mark-and-transmit");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_dscp (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683   char *t = 0;
4684
4685   switch (i)
4686     {
4687 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4688       foreach_vnet_dscp
4689 #undef _
4690     default:
4691       return format (s, "ILLEGAL");
4692     }
4693   s = format (s, "%s", t);
4694   return s;
4695 }
4696
4697 static void
4698 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4702
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705   else
4706     conform_dscp_str = format (0, "");
4707
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4710   else
4711     exceed_dscp_str = format (0, "");
4712
4713   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4714     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4715   else
4716     violate_dscp_str = format (0, "");
4717
4718   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4719          "rate type %U, round type %U, %s rate, %s color-aware, "
4720          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4721          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4722          "conform action %U%s, exceed action %U%s, violate action %U%s",
4723          mp->name,
4724          format_policer_type, mp->type,
4725          ntohl (mp->cir),
4726          ntohl (mp->eir),
4727          clib_net_to_host_u64 (mp->cb),
4728          clib_net_to_host_u64 (mp->eb),
4729          format_policer_rate_type, mp->rate_type,
4730          format_policer_round_type, mp->round_type,
4731          mp->single_rate ? "single" : "dual",
4732          mp->color_aware ? "is" : "not",
4733          ntohl (mp->cir_tokens_per_period),
4734          ntohl (mp->pir_tokens_per_period),
4735          ntohl (mp->scale),
4736          ntohl (mp->current_limit),
4737          ntohl (mp->current_bucket),
4738          ntohl (mp->extended_limit),
4739          ntohl (mp->extended_bucket),
4740          clib_net_to_host_u64 (mp->last_update_time),
4741          format_policer_action_type, mp->conform_action_type,
4742          conform_dscp_str,
4743          format_policer_action_type, mp->exceed_action_type,
4744          exceed_dscp_str,
4745          format_policer_action_type, mp->violate_action_type,
4746          violate_dscp_str);
4747
4748   vec_free (conform_dscp_str);
4749   vec_free (exceed_dscp_str);
4750   vec_free (violate_dscp_str);
4751 }
4752
4753 static void vl_api_policer_details_t_handler_json
4754   (vl_api_policer_details_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t *node;
4758   u8 *rate_type_str, *round_type_str, *type_str;
4759   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4760
4761   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4762   round_type_str =
4763     format (0, "%U", format_policer_round_type, mp->round_type);
4764   type_str = format (0, "%U", format_policer_type, mp->type);
4765   conform_action_str = format (0, "%U", format_policer_action_type,
4766                                mp->conform_action_type);
4767   exceed_action_str = format (0, "%U", format_policer_action_type,
4768                               mp->exceed_action_type);
4769   violate_action_str = format (0, "%U", format_policer_action_type,
4770                                mp->violate_action_type);
4771
4772   if (VAT_JSON_ARRAY != vam->json_tree.type)
4773     {
4774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4775       vat_json_init_array (&vam->json_tree);
4776     }
4777   node = vat_json_array_add (&vam->json_tree);
4778
4779   vat_json_init_object (node);
4780   vat_json_object_add_string_copy (node, "name", mp->name);
4781   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4782   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4783   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4784   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4785   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4786   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4787   vat_json_object_add_string_copy (node, "type", type_str);
4788   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4789   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4790   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4791   vat_json_object_add_uint (node, "cir_tokens_per_period",
4792                             ntohl (mp->cir_tokens_per_period));
4793   vat_json_object_add_uint (node, "eir_tokens_per_period",
4794                             ntohl (mp->pir_tokens_per_period));
4795   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4796   vat_json_object_add_uint (node, "current_bucket",
4797                             ntohl (mp->current_bucket));
4798   vat_json_object_add_uint (node, "extended_limit",
4799                             ntohl (mp->extended_limit));
4800   vat_json_object_add_uint (node, "extended_bucket",
4801                             ntohl (mp->extended_bucket));
4802   vat_json_object_add_uint (node, "last_update_time",
4803                             ntohl (mp->last_update_time));
4804   vat_json_object_add_string_copy (node, "conform_action",
4805                                    conform_action_str);
4806   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4807     {
4808       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4809       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4810       vec_free (dscp_str);
4811     }
4812   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4813   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4814     {
4815       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4816       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4817       vec_free (dscp_str);
4818     }
4819   vat_json_object_add_string_copy (node, "violate_action",
4820                                    violate_action_str);
4821   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4824       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827
4828   vec_free (rate_type_str);
4829   vec_free (round_type_str);
4830   vec_free (type_str);
4831   vec_free (conform_action_str);
4832   vec_free (exceed_action_str);
4833   vec_free (violate_action_str);
4834 }
4835
4836 static void
4837 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4838                                            mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   int i, count = ntohl (mp->count);
4842
4843   if (count > 0)
4844     print (vam->ofp, "classify table ids (%d) : ", count);
4845   for (i = 0; i < count; i++)
4846     {
4847       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4848       print (vam->ofp, (i < count - 1) ? "," : "");
4849     }
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855   vl_api_classify_table_ids_reply_t_handler_json
4856   (vl_api_classify_table_ids_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   int i, count = ntohl (mp->count);
4860
4861   if (count > 0)
4862     {
4863       vat_json_node_t node;
4864
4865       vat_json_init_object (&node);
4866       for (i = 0; i < count; i++)
4867         {
4868           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4869         }
4870       vat_json_print (vam->ofp, &node);
4871       vat_json_free (&node);
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_by_interface_reply_t_handler
4879   (vl_api_classify_table_by_interface_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   u32 table_id;
4883
4884   table_id = ntohl (mp->l2_table_id);
4885   if (table_id != ~0)
4886     print (vam->ofp, "l2 table id : %d", table_id);
4887   else
4888     print (vam->ofp, "l2 table id : No input ACL tables configured");
4889   table_id = ntohl (mp->ip4_table_id);
4890   if (table_id != ~0)
4891     print (vam->ofp, "ip4 table id : %d", table_id);
4892   else
4893     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4894   table_id = ntohl (mp->ip6_table_id);
4895   if (table_id != ~0)
4896     print (vam->ofp, "ip6 table id : %d", table_id);
4897   else
4898     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4899   vam->retval = ntohl (mp->retval);
4900   vam->result_ready = 1;
4901 }
4902
4903 static void
4904   vl_api_classify_table_by_interface_reply_t_handler_json
4905   (vl_api_classify_table_by_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   vat_json_init_object (&node);
4911
4912   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4913   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4914   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_policer_add_del_reply_t_handler
4924   (vl_api_policer_add_del_reply_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (vam->async_mode)
4929     {
4930       vam->async_errors += (retval < 0);
4931     }
4932   else
4933     {
4934       vam->retval = retval;
4935       vam->result_ready = 1;
4936       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4937         /*
4938          * Note: this is just barely thread-safe, depends on
4939          * the main thread spinning waiting for an answer...
4940          */
4941         errmsg ("policer index %d", ntohl (mp->policer_index));
4942     }
4943 }
4944
4945 static void vl_api_policer_add_del_reply_t_handler_json
4946   (vl_api_policer_add_del_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   vat_json_init_object (&node);
4952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4953   vat_json_object_add_uint (&node, "policer_index",
4954                             ntohl (mp->policer_index));
4955
4956   vat_json_print (vam->ofp, &node);
4957   vat_json_free (&node);
4958
4959   vam->retval = ntohl (mp->retval);
4960   vam->result_ready = 1;
4961 }
4962
4963 /* Format hex dump. */
4964 u8 *
4965 format_hex_bytes (u8 * s, va_list * va)
4966 {
4967   u8 *bytes = va_arg (*va, u8 *);
4968   int n_bytes = va_arg (*va, int);
4969   uword i;
4970
4971   /* Print short or long form depending on byte count. */
4972   uword short_form = n_bytes <= 32;
4973   u32 indent = format_get_indent (s);
4974
4975   if (n_bytes == 0)
4976     return s;
4977
4978   for (i = 0; i < n_bytes; i++)
4979     {
4980       if (!short_form && (i % 32) == 0)
4981         s = format (s, "%08x: ", i);
4982       s = format (s, "%02x", bytes[i]);
4983       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4984         s = format (s, "\n%U", format_white_space, indent);
4985     }
4986
4987   return s;
4988 }
4989
4990 static void
4991 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4992                                             * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   i32 retval = ntohl (mp->retval);
4996   if (retval == 0)
4997     {
4998       print (vam->ofp, "classify table info :");
4999       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5000              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5001              ntohl (mp->miss_next_index));
5002       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5003              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5004              ntohl (mp->match_n_vectors));
5005       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5006              ntohl (mp->mask_length));
5007     }
5008   vam->retval = retval;
5009   vam->result_ready = 1;
5010 }
5011
5012 static void
5013   vl_api_classify_table_info_reply_t_handler_json
5014   (vl_api_classify_table_info_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017   vat_json_node_t node;
5018
5019   i32 retval = ntohl (mp->retval);
5020   if (retval == 0)
5021     {
5022       vat_json_init_object (&node);
5023
5024       vat_json_object_add_int (&node, "sessions",
5025                                ntohl (mp->active_sessions));
5026       vat_json_object_add_int (&node, "nexttbl",
5027                                ntohl (mp->next_table_index));
5028       vat_json_object_add_int (&node, "nextnode",
5029                                ntohl (mp->miss_next_index));
5030       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5031       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5032       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5033       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5034                       ntohl (mp->mask_length), 0);
5035       vat_json_object_add_string_copy (&node, "mask", s);
5036
5037       vat_json_print (vam->ofp, &node);
5038       vat_json_free (&node);
5039     }
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void
5045 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5046                                            mp)
5047 {
5048   vat_main_t *vam = &vat_main;
5049
5050   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5051          ntohl (mp->hit_next_index), ntohl (mp->advance),
5052          ntohl (mp->opaque_index));
5053   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5054          ntohl (mp->match_length));
5055 }
5056
5057 static void
5058   vl_api_classify_session_details_t_handler_json
5059   (vl_api_classify_session_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   vat_json_node_t *node = NULL;
5063
5064   if (VAT_JSON_ARRAY != vam->json_tree.type)
5065     {
5066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5067       vat_json_init_array (&vam->json_tree);
5068     }
5069   node = vat_json_array_add (&vam->json_tree);
5070
5071   vat_json_init_object (node);
5072   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5073   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5074   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5075   u8 *s =
5076     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5077             0);
5078   vat_json_object_add_string_copy (node, "match", s);
5079 }
5080
5081 static void vl_api_pg_create_interface_reply_t_handler
5082   (vl_api_pg_create_interface_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085
5086   vam->retval = ntohl (mp->retval);
5087   vam->result_ready = 1;
5088 }
5089
5090 static void vl_api_pg_create_interface_reply_t_handler_json
5091   (vl_api_pg_create_interface_reply_t * mp)
5092 {
5093   vat_main_t *vam = &vat_main;
5094   vat_json_node_t node;
5095
5096   i32 retval = ntohl (mp->retval);
5097   if (retval == 0)
5098     {
5099       vat_json_init_object (&node);
5100
5101       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5102
5103       vat_json_print (vam->ofp, &node);
5104       vat_json_free (&node);
5105     }
5106   vam->retval = ntohl (mp->retval);
5107   vam->result_ready = 1;
5108 }
5109
5110 static void vl_api_policer_classify_details_t_handler
5111   (vl_api_policer_classify_details_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114
5115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5116          ntohl (mp->table_index));
5117 }
5118
5119 static void vl_api_policer_classify_details_t_handler_json
5120   (vl_api_policer_classify_details_t * mp)
5121 {
5122   vat_main_t *vam = &vat_main;
5123   vat_json_node_t *node;
5124
5125   if (VAT_JSON_ARRAY != vam->json_tree.type)
5126     {
5127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5128       vat_json_init_array (&vam->json_tree);
5129     }
5130   node = vat_json_array_add (&vam->json_tree);
5131
5132   vat_json_init_object (node);
5133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5138   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   i32 retval = ntohl (mp->retval);
5142   if (vam->async_mode)
5143     {
5144       vam->async_errors += (retval < 0);
5145     }
5146   else
5147     {
5148       vam->retval = retval;
5149       vam->sw_if_index = ntohl (mp->sw_if_index);
5150       vam->result_ready = 1;
5151     }
5152 }
5153
5154 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5155   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5156 {
5157   vat_main_t *vam = &vat_main;
5158   vat_json_node_t node;
5159
5160   vat_json_init_object (&node);
5161   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5162   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5163
5164   vat_json_print (vam->ofp, &node);
5165   vat_json_free (&node);
5166
5167   vam->retval = ntohl (mp->retval);
5168   vam->result_ready = 1;
5169 }
5170
5171 static void vl_api_flow_classify_details_t_handler
5172   (vl_api_flow_classify_details_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175
5176   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5177          ntohl (mp->table_index));
5178 }
5179
5180 static void vl_api_flow_classify_details_t_handler_json
5181   (vl_api_flow_classify_details_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t *node;
5185
5186   if (VAT_JSON_ARRAY != vam->json_tree.type)
5187     {
5188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5189       vat_json_init_array (&vam->json_tree);
5190     }
5191   node = vat_json_array_add (&vam->json_tree);
5192
5193   vat_json_init_object (node);
5194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5195   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5196 }
5197
5198 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5199 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5200 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5201 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5202 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5203 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5204 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5205 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5206 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5207 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5208 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5209 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5210 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5211 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5212 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5213 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5214 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5215 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5216 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5217 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5218 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5219 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5220
5221 /*
5222  * Generate boilerplate reply handlers, which
5223  * dig the return value out of the xxx_reply_t API message,
5224  * stick it into vam->retval, and set vam->result_ready
5225  *
5226  * Could also do this by pointing N message decode slots at
5227  * a single function, but that could break in subtle ways.
5228  */
5229
5230 #define foreach_standard_reply_retval_handler           \
5231 _(sw_interface_set_flags_reply)                         \
5232 _(sw_interface_add_del_address_reply)                   \
5233 _(sw_interface_set_rx_mode_reply)                       \
5234 _(sw_interface_set_table_reply)                         \
5235 _(sw_interface_set_mpls_enable_reply)                   \
5236 _(sw_interface_set_vpath_reply)                         \
5237 _(sw_interface_set_vxlan_bypass_reply)                  \
5238 _(sw_interface_set_geneve_bypass_reply)                 \
5239 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5240 _(sw_interface_set_l2_bridge_reply)                     \
5241 _(bridge_domain_add_del_reply)                          \
5242 _(sw_interface_set_l2_xconnect_reply)                   \
5243 _(l2fib_add_del_reply)                                  \
5244 _(l2fib_flush_int_reply)                                \
5245 _(l2fib_flush_bd_reply)                                 \
5246 _(ip_add_del_route_reply)                               \
5247 _(ip_table_add_del_reply)                               \
5248 _(ip_mroute_add_del_reply)                              \
5249 _(mpls_route_add_del_reply)                             \
5250 _(mpls_table_add_del_reply)                             \
5251 _(mpls_ip_bind_unbind_reply)                            \
5252 _(bier_route_add_del_reply)                             \
5253 _(bier_table_add_del_reply)                             \
5254 _(proxy_arp_add_del_reply)                              \
5255 _(proxy_arp_intfc_enable_disable_reply)                 \
5256 _(sw_interface_set_unnumbered_reply)                    \
5257 _(ip_neighbor_add_del_reply)                            \
5258 _(oam_add_del_reply)                                    \
5259 _(reset_fib_reply)                                      \
5260 _(dhcp_proxy_config_reply)                              \
5261 _(dhcp_proxy_set_vss_reply)                             \
5262 _(dhcp_client_config_reply)                             \
5263 _(set_ip_flow_hash_reply)                               \
5264 _(sw_interface_ip6_enable_disable_reply)                \
5265 _(sw_interface_ip6_set_link_local_address_reply)        \
5266 _(ip6nd_proxy_add_del_reply)                            \
5267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5268 _(sw_interface_ip6nd_ra_config_reply)                   \
5269 _(set_arp_neighbor_limit_reply)                         \
5270 _(l2_patch_add_del_reply)                               \
5271 _(sr_policy_add_reply)                                  \
5272 _(sr_policy_mod_reply)                                  \
5273 _(sr_policy_del_reply)                                  \
5274 _(sr_localsid_add_del_reply)                            \
5275 _(sr_steering_add_del_reply)                            \
5276 _(classify_add_del_session_reply)                       \
5277 _(classify_set_interface_ip_table_reply)                \
5278 _(classify_set_interface_l2_tables_reply)               \
5279 _(l2tpv3_set_tunnel_cookies_reply)                      \
5280 _(l2tpv3_interface_enable_disable_reply)                \
5281 _(l2tpv3_set_lookup_key_reply)                          \
5282 _(l2_fib_clear_table_reply)                             \
5283 _(l2_interface_efp_filter_reply)                        \
5284 _(l2_interface_vlan_tag_rewrite_reply)                  \
5285 _(modify_vhost_user_if_reply)                           \
5286 _(delete_vhost_user_if_reply)                           \
5287 _(want_ip4_arp_events_reply)                            \
5288 _(want_ip6_nd_events_reply)                             \
5289 _(want_l2_macs_events_reply)                            \
5290 _(input_acl_set_interface_reply)                        \
5291 _(ipsec_spd_add_del_reply)                              \
5292 _(ipsec_interface_add_del_spd_reply)                    \
5293 _(ipsec_spd_add_del_entry_reply)                        \
5294 _(ipsec_sad_add_del_entry_reply)                        \
5295 _(ipsec_sa_set_key_reply)                               \
5296 _(ipsec_tunnel_if_add_del_reply)                        \
5297 _(ipsec_tunnel_if_set_key_reply)                        \
5298 _(ipsec_tunnel_if_set_sa_reply)                         \
5299 _(ikev2_profile_add_del_reply)                          \
5300 _(ikev2_profile_set_auth_reply)                         \
5301 _(ikev2_profile_set_id_reply)                           \
5302 _(ikev2_profile_set_ts_reply)                           \
5303 _(ikev2_set_local_key_reply)                            \
5304 _(ikev2_set_responder_reply)                            \
5305 _(ikev2_set_ike_transforms_reply)                       \
5306 _(ikev2_set_esp_transforms_reply)                       \
5307 _(ikev2_set_sa_lifetime_reply)                          \
5308 _(ikev2_initiate_sa_init_reply)                         \
5309 _(ikev2_initiate_del_ike_sa_reply)                      \
5310 _(ikev2_initiate_del_child_sa_reply)                    \
5311 _(ikev2_initiate_rekey_child_sa_reply)                  \
5312 _(delete_loopback_reply)                                \
5313 _(bd_ip_mac_add_del_reply)                              \
5314 _(map_del_domain_reply)                                 \
5315 _(map_add_del_rule_reply)                               \
5316 _(want_interface_events_reply)                          \
5317 _(want_stats_reply)                                     \
5318 _(cop_interface_enable_disable_reply)                   \
5319 _(cop_whitelist_enable_disable_reply)                   \
5320 _(sw_interface_clear_stats_reply)                       \
5321 _(ioam_enable_reply)                                    \
5322 _(ioam_disable_reply)                                   \
5323 _(one_add_del_locator_reply)                            \
5324 _(one_add_del_local_eid_reply)                          \
5325 _(one_add_del_remote_mapping_reply)                     \
5326 _(one_add_del_adjacency_reply)                          \
5327 _(one_add_del_map_resolver_reply)                       \
5328 _(one_add_del_map_server_reply)                         \
5329 _(one_enable_disable_reply)                             \
5330 _(one_rloc_probe_enable_disable_reply)                  \
5331 _(one_map_register_enable_disable_reply)                \
5332 _(one_map_register_set_ttl_reply)                       \
5333 _(one_set_transport_protocol_reply)                     \
5334 _(one_map_register_fallback_threshold_reply)            \
5335 _(one_pitr_set_locator_set_reply)                       \
5336 _(one_map_request_mode_reply)                           \
5337 _(one_add_del_map_request_itr_rlocs_reply)              \
5338 _(one_eid_table_add_del_map_reply)                      \
5339 _(one_use_petr_reply)                                   \
5340 _(one_stats_enable_disable_reply)                       \
5341 _(one_add_del_l2_arp_entry_reply)                       \
5342 _(one_add_del_ndp_entry_reply)                          \
5343 _(one_stats_flush_reply)                                \
5344 _(one_enable_disable_xtr_mode_reply)                    \
5345 _(one_enable_disable_pitr_mode_reply)                   \
5346 _(one_enable_disable_petr_mode_reply)                   \
5347 _(gpe_enable_disable_reply)                             \
5348 _(gpe_set_encap_mode_reply)                             \
5349 _(gpe_add_del_iface_reply)                              \
5350 _(gpe_add_del_native_fwd_rpath_reply)                   \
5351 _(af_packet_delete_reply)                               \
5352 _(policer_classify_set_interface_reply)                 \
5353 _(netmap_create_reply)                                  \
5354 _(netmap_delete_reply)                                  \
5355 _(set_ipfix_exporter_reply)                             \
5356 _(set_ipfix_classify_stream_reply)                      \
5357 _(ipfix_classify_table_add_del_reply)                   \
5358 _(flow_classify_set_interface_reply)                    \
5359 _(sw_interface_span_enable_disable_reply)               \
5360 _(pg_capture_reply)                                     \
5361 _(pg_enable_disable_reply)                              \
5362 _(ip_source_and_port_range_check_add_del_reply)         \
5363 _(ip_source_and_port_range_check_interface_add_del_reply)\
5364 _(delete_subif_reply)                                   \
5365 _(l2_interface_pbb_tag_rewrite_reply)                   \
5366 _(punt_reply)                                           \
5367 _(feature_enable_disable_reply)                         \
5368 _(sw_interface_tag_add_del_reply)                       \
5369 _(sw_interface_set_mtu_reply)                           \
5370 _(p2p_ethernet_add_reply)                               \
5371 _(p2p_ethernet_del_reply)                               \
5372 _(lldp_config_reply)                                    \
5373 _(sw_interface_set_lldp_reply)                          \
5374 _(tcp_configure_src_addresses_reply)                    \
5375 _(dns_enable_disable_reply)                             \
5376 _(dns_name_server_add_del_reply)                        \
5377 _(session_rule_add_del_reply)                           \
5378 _(ip_container_proxy_add_del_reply)
5379
5380 #define _(n)                                    \
5381     static void vl_api_##n##_t_handler          \
5382     (vl_api_##n##_t * mp)                       \
5383     {                                           \
5384         vat_main_t * vam = &vat_main;           \
5385         i32 retval = ntohl(mp->retval);         \
5386         if (vam->async_mode) {                  \
5387             vam->async_errors += (retval < 0);  \
5388         } else {                                \
5389             vam->retval = retval;               \
5390             vam->result_ready = 1;              \
5391         }                                       \
5392     }
5393 foreach_standard_reply_retval_handler;
5394 #undef _
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler_json     \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         vat_json_node_t node;                   \
5402         vat_json_init_object(&node);            \
5403         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5404         vat_json_print(vam->ofp, &node);        \
5405         vam->retval = ntohl(mp->retval);        \
5406         vam->result_ready = 1;                  \
5407     }
5408 foreach_standard_reply_retval_handler;
5409 #undef _
5410
5411 /*
5412  * Table of message reply handlers, must include boilerplate handlers
5413  * we just generated
5414  */
5415
5416 #define foreach_vpe_api_reply_msg                                       \
5417 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5418 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5419 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5420 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5421 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5422 _(CLI_REPLY, cli_reply)                                                 \
5423 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5424 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5425   sw_interface_add_del_address_reply)                                   \
5426 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5427 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5428 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5429 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5430 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5431 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5432 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5433 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5434   sw_interface_set_l2_xconnect_reply)                                   \
5435 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5436   sw_interface_set_l2_bridge_reply)                                     \
5437 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5438 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5439 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5440 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5441 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5442 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5443 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5444 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5445 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5446 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5447 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5448 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5449 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5450 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5451 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5453 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5454 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5455 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5456 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5457 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5458 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5459 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5460 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5461 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5462   proxy_arp_intfc_enable_disable_reply)                                 \
5463 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5465   sw_interface_set_unnumbered_reply)                                    \
5466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5472 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5473 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5477   sw_interface_ip6_enable_disable_reply)                                \
5478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5479   sw_interface_ip6_set_link_local_address_reply)                        \
5480 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5481 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5483   sw_interface_ip6nd_ra_prefix_reply)                                   \
5484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5485   sw_interface_ip6nd_ra_config_reply)                                   \
5486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5488 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5489 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5490 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5491 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5492 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5493 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5494 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5495 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5496 classify_set_interface_ip_table_reply)                                  \
5497 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5498   classify_set_interface_l2_tables_reply)                               \
5499 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5500 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5501 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5502 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5503 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5504   l2tpv3_interface_enable_disable_reply)                                \
5505 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5506 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5507 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5508 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5509 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5510 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5511 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5512 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5513 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5514 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5515 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5516 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5517 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5518 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5519 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5520 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5521 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5522 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5523 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5524 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5525 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5526 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5527 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5528 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5529 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5530 _(L2_MACS_EVENT, l2_macs_event)                                         \
5531 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5532 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5533 _(IP_DETAILS, ip_details)                                               \
5534 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5535 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5536 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5537 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5538 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5539 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5540 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5541 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5542 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5543 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5544 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5545 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5546 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5547 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5548 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5549 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5550 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5551 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5552 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5553 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5554 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5555 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5556 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5557 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5558 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5571 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5572 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5573 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5574 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5575 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5576 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5577 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5578 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5579 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5580 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5581 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5582   one_map_register_enable_disable_reply)                                \
5583 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5584 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5585 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5586 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5587   one_map_register_fallback_threshold_reply)                            \
5588 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5589   one_rloc_probe_enable_disable_reply)                                  \
5590 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5591 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5592 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5593 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5594 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5595 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5596 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5597 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5598 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5599 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5600 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5601 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5602 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5603 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5604 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5605 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5606   show_one_stats_enable_disable_reply)                                  \
5607 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5608 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5609 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5610 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5611 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5612 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5613 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5614 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5615   one_enable_disable_pitr_mode_reply)                                   \
5616 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5617   one_enable_disable_petr_mode_reply)                                   \
5618 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5619 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5620 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5621 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5622 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5623 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5624 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5625 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5626 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5627 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5628 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5629 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5630   gpe_add_del_native_fwd_rpath_reply)                                   \
5631 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5632   gpe_fwd_entry_path_details)                                           \
5633 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5634 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5635   one_add_del_map_request_itr_rlocs_reply)                              \
5636 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5637   one_get_map_request_itr_rlocs_reply)                                  \
5638 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5639 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5640 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5641 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5642 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5643 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5644   show_one_map_register_state_reply)                                    \
5645 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5646 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5647   show_one_map_register_fallback_threshold_reply)                       \
5648 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5649 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5650 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5651 _(POLICER_DETAILS, policer_details)                                     \
5652 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5653 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5654 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5655 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5656 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5657 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5658 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5659 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5660 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5661 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5662 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5663 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5664 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5665 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5666 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5667 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5668 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5669 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5670 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5671 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5672 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5673 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5674 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5675 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5676 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5677  ip_source_and_port_range_check_add_del_reply)                          \
5678 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5679  ip_source_and_port_range_check_interface_add_del_reply)                \
5680 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5681 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5682 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5683 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5684 _(PUNT_REPLY, punt_reply)                                               \
5685 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5686 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5687 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5688 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5689 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5690 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5691 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5692 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5693 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5694 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5695 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5696 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5697 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5698 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5699 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5700 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5701 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5702 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5703 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5704 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5705 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5706
5707 #define foreach_standalone_reply_msg                                    \
5708 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5709 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5710 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5713 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5714 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5715 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5716
5717 typedef struct
5718 {
5719   u8 *name;
5720   u32 value;
5721 } name_sort_t;
5722
5723
5724 #define STR_VTR_OP_CASE(op)     \
5725     case L2_VTR_ ## op:         \
5726         return "" # op;
5727
5728 static const char *
5729 str_vtr_op (u32 vtr_op)
5730 {
5731   switch (vtr_op)
5732     {
5733       STR_VTR_OP_CASE (DISABLED);
5734       STR_VTR_OP_CASE (PUSH_1);
5735       STR_VTR_OP_CASE (PUSH_2);
5736       STR_VTR_OP_CASE (POP_1);
5737       STR_VTR_OP_CASE (POP_2);
5738       STR_VTR_OP_CASE (TRANSLATE_1_1);
5739       STR_VTR_OP_CASE (TRANSLATE_1_2);
5740       STR_VTR_OP_CASE (TRANSLATE_2_1);
5741       STR_VTR_OP_CASE (TRANSLATE_2_2);
5742     }
5743
5744   return "UNKNOWN";
5745 }
5746
5747 static int
5748 dump_sub_interface_table (vat_main_t * vam)
5749 {
5750   const sw_interface_subif_t *sub = NULL;
5751
5752   if (vam->json_output)
5753     {
5754       clib_warning
5755         ("JSON output supported only for VPE API calls and dump_stats_table");
5756       return -99;
5757     }
5758
5759   print (vam->ofp,
5760          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5761          "Interface", "sw_if_index",
5762          "sub id", "dot1ad", "tags", "outer id",
5763          "inner id", "exact", "default", "outer any", "inner any");
5764
5765   vec_foreach (sub, vam->sw_if_subif_table)
5766   {
5767     print (vam->ofp,
5768            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5769            sub->interface_name,
5770            sub->sw_if_index,
5771            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5772            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5773            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5774            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5775     if (sub->vtr_op != L2_VTR_DISABLED)
5776       {
5777         print (vam->ofp,
5778                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5779                "tag1: %d tag2: %d ]",
5780                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5781                sub->vtr_tag1, sub->vtr_tag2);
5782       }
5783   }
5784
5785   return 0;
5786 }
5787
5788 static int
5789 name_sort_cmp (void *a1, void *a2)
5790 {
5791   name_sort_t *n1 = a1;
5792   name_sort_t *n2 = a2;
5793
5794   return strcmp ((char *) n1->name, (char *) n2->name);
5795 }
5796
5797 static int
5798 dump_interface_table (vat_main_t * vam)
5799 {
5800   hash_pair_t *p;
5801   name_sort_t *nses = 0, *ns;
5802
5803   if (vam->json_output)
5804     {
5805       clib_warning
5806         ("JSON output supported only for VPE API calls and dump_stats_table");
5807       return -99;
5808     }
5809
5810   /* *INDENT-OFF* */
5811   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5812   ({
5813     vec_add2 (nses, ns, 1);
5814     ns->name = (u8 *)(p->key);
5815     ns->value = (u32) p->value[0];
5816   }));
5817   /* *INDENT-ON* */
5818
5819   vec_sort_with_function (nses, name_sort_cmp);
5820
5821   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5822   vec_foreach (ns, nses)
5823   {
5824     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5825   }
5826   vec_free (nses);
5827   return 0;
5828 }
5829
5830 static int
5831 dump_ip_table (vat_main_t * vam, int is_ipv6)
5832 {
5833   const ip_details_t *det = NULL;
5834   const ip_address_details_t *address = NULL;
5835   u32 i = ~0;
5836
5837   print (vam->ofp, "%-12s", "sw_if_index");
5838
5839   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5840   {
5841     i++;
5842     if (!det->present)
5843       {
5844         continue;
5845       }
5846     print (vam->ofp, "%-12d", i);
5847     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5848     if (!det->addr)
5849       {
5850         continue;
5851       }
5852     vec_foreach (address, det->addr)
5853     {
5854       print (vam->ofp,
5855              "            %-30U%-13d",
5856              is_ipv6 ? format_ip6_address : format_ip4_address,
5857              address->ip, address->prefix_length);
5858     }
5859   }
5860
5861   return 0;
5862 }
5863
5864 static int
5865 dump_ipv4_table (vat_main_t * vam)
5866 {
5867   if (vam->json_output)
5868     {
5869       clib_warning
5870         ("JSON output supported only for VPE API calls and dump_stats_table");
5871       return -99;
5872     }
5873
5874   return dump_ip_table (vam, 0);
5875 }
5876
5877 static int
5878 dump_ipv6_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 1);
5888 }
5889
5890 static char *
5891 counter_type_to_str (u8 counter_type, u8 is_combined)
5892 {
5893   if (!is_combined)
5894     {
5895       switch (counter_type)
5896         {
5897         case VNET_INTERFACE_COUNTER_DROP:
5898           return "drop";
5899         case VNET_INTERFACE_COUNTER_PUNT:
5900           return "punt";
5901         case VNET_INTERFACE_COUNTER_IP4:
5902           return "ip4";
5903         case VNET_INTERFACE_COUNTER_IP6:
5904           return "ip6";
5905         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5906           return "rx-no-buf";
5907         case VNET_INTERFACE_COUNTER_RX_MISS:
5908           return "rx-miss";
5909         case VNET_INTERFACE_COUNTER_RX_ERROR:
5910           return "rx-error";
5911         case VNET_INTERFACE_COUNTER_TX_ERROR:
5912           return "tx-error";
5913         default:
5914           return "INVALID-COUNTER-TYPE";
5915         }
5916     }
5917   else
5918     {
5919       switch (counter_type)
5920         {
5921         case VNET_INTERFACE_COUNTER_RX:
5922           return "rx";
5923         case VNET_INTERFACE_COUNTER_TX:
5924           return "tx";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929 }
5930
5931 static int
5932 dump_stats_table (vat_main_t * vam)
5933 {
5934   vat_json_node_t node;
5935   vat_json_node_t *msg_array;
5936   vat_json_node_t *msg;
5937   vat_json_node_t *counter_array;
5938   vat_json_node_t *counter;
5939   interface_counter_t c;
5940   u64 packets;
5941   ip4_fib_counter_t *c4;
5942   ip6_fib_counter_t *c6;
5943   ip4_nbr_counter_t *n4;
5944   ip6_nbr_counter_t *n6;
5945   int i, j;
5946
5947   if (!vam->json_output)
5948     {
5949       clib_warning ("dump_stats_table supported only in JSON format");
5950       return -99;
5951     }
5952
5953   vat_json_init_object (&node);
5954
5955   /* interface counters */
5956   msg_array = vat_json_object_add (&node, "interface_counters");
5957   vat_json_init_array (msg_array);
5958   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5959     {
5960       msg = vat_json_array_add (msg_array);
5961       vat_json_init_object (msg);
5962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5963                                        (u8 *) counter_type_to_str (i, 0));
5964       vat_json_object_add_int (msg, "is_combined", 0);
5965       counter_array = vat_json_object_add (msg, "data");
5966       vat_json_init_array (counter_array);
5967       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5968         {
5969           packets = vam->simple_interface_counters[i][j];
5970           vat_json_array_add_uint (counter_array, packets);
5971         }
5972     }
5973   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5978                                        (u8 *) counter_type_to_str (i, 1));
5979       vat_json_object_add_int (msg, "is_combined", 1);
5980       counter_array = vat_json_object_add (msg, "data");
5981       vat_json_init_array (counter_array);
5982       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5983         {
5984           c = vam->combined_interface_counters[i][j];
5985           counter = vat_json_array_add (counter_array);
5986           vat_json_init_object (counter);
5987           vat_json_object_add_uint (counter, "packets", c.packets);
5988           vat_json_object_add_uint (counter, "bytes", c.bytes);
5989         }
5990     }
5991
5992   /* ip4 fib counters */
5993   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "vrf_id",
6000                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6001       counter_array = vat_json_object_add (msg, "c");
6002       vat_json_init_array (counter_array);
6003       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6004         {
6005           counter = vat_json_array_add (counter_array);
6006           vat_json_init_object (counter);
6007           c4 = &vam->ip4_fib_counters[i][j];
6008           vat_json_object_add_ip4 (counter, "address", c4->address);
6009           vat_json_object_add_uint (counter, "address_length",
6010                                     c4->address_length);
6011           vat_json_object_add_uint (counter, "packets", c4->packets);
6012           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6013         }
6014     }
6015
6016   /* ip6 fib counters */
6017   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6018   vat_json_init_array (msg_array);
6019   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6020     {
6021       msg = vat_json_array_add (msg_array);
6022       vat_json_init_object (msg);
6023       vat_json_object_add_uint (msg, "vrf_id",
6024                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6025       counter_array = vat_json_object_add (msg, "c");
6026       vat_json_init_array (counter_array);
6027       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6028         {
6029           counter = vat_json_array_add (counter_array);
6030           vat_json_init_object (counter);
6031           c6 = &vam->ip6_fib_counters[i][j];
6032           vat_json_object_add_ip6 (counter, "address", c6->address);
6033           vat_json_object_add_uint (counter, "address_length",
6034                                     c6->address_length);
6035           vat_json_object_add_uint (counter, "packets", c6->packets);
6036           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6037         }
6038     }
6039
6040   /* ip4 nbr counters */
6041   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6042   vat_json_init_array (msg_array);
6043   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6044     {
6045       msg = vat_json_array_add (msg_array);
6046       vat_json_init_object (msg);
6047       vat_json_object_add_uint (msg, "sw_if_index", i);
6048       counter_array = vat_json_object_add (msg, "c");
6049       vat_json_init_array (counter_array);
6050       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6051         {
6052           counter = vat_json_array_add (counter_array);
6053           vat_json_init_object (counter);
6054           n4 = &vam->ip4_nbr_counters[i][j];
6055           vat_json_object_add_ip4 (counter, "address", n4->address);
6056           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6057           vat_json_object_add_uint (counter, "packets", n4->packets);
6058           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6059         }
6060     }
6061
6062   /* ip6 nbr counters */
6063   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6064   vat_json_init_array (msg_array);
6065   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6066     {
6067       msg = vat_json_array_add (msg_array);
6068       vat_json_init_object (msg);
6069       vat_json_object_add_uint (msg, "sw_if_index", i);
6070       counter_array = vat_json_object_add (msg, "c");
6071       vat_json_init_array (counter_array);
6072       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6073         {
6074           counter = vat_json_array_add (counter_array);
6075           vat_json_init_object (counter);
6076           n6 = &vam->ip6_nbr_counters[i][j];
6077           vat_json_object_add_ip6 (counter, "address", n6->address);
6078           vat_json_object_add_uint (counter, "packets", n6->packets);
6079           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6080         }
6081     }
6082
6083   vat_json_print (vam->ofp, &node);
6084   vat_json_free (&node);
6085
6086   return 0;
6087 }
6088
6089 /*
6090  * Pass CLI buffers directly in the CLI_INBAND API message,
6091  * instead of an additional shared memory area.
6092  */
6093 static int
6094 exec_inband (vat_main_t * vam)
6095 {
6096   vl_api_cli_inband_t *mp;
6097   unformat_input_t *i = vam->input;
6098   int ret;
6099
6100   if (vec_len (i->buffer) == 0)
6101     return -1;
6102
6103   if (vam->exec_mode == 0 && unformat (i, "mode"))
6104     {
6105       vam->exec_mode = 1;
6106       return 0;
6107     }
6108   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6109     {
6110       vam->exec_mode = 0;
6111       return 0;
6112     }
6113
6114   /*
6115    * In order for the CLI command to work, it
6116    * must be a vector ending in \n, not a C-string ending
6117    * in \n\0.
6118    */
6119   u32 len = vec_len (vam->input->buffer);
6120   M2 (CLI_INBAND, mp, len);
6121   clib_memcpy (mp->cmd, vam->input->buffer, len);
6122   mp->length = htonl (len);
6123
6124   S (mp);
6125   W (ret);
6126   /* json responses may or may not include a useful reply... */
6127   if (vec_len (vam->cmd_reply))
6128     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6129   return ret;
6130 }
6131
6132 int
6133 exec (vat_main_t * vam)
6134 {
6135   return exec_inband (vam);
6136 }
6137
6138 static int
6139 api_create_loopback (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_create_loopback_t *mp;
6143   vl_api_create_loopback_instance_t *mp_lbi;
6144   u8 mac_address[6];
6145   u8 mac_set = 0;
6146   u8 is_specified = 0;
6147   u32 user_instance = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6155         mac_set = 1;
6156       if (unformat (i, "instance %d", &user_instance))
6157         is_specified = 1;
6158       else
6159         break;
6160     }
6161
6162   if (is_specified)
6163     {
6164       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6165       mp_lbi->is_specified = is_specified;
6166       if (is_specified)
6167         mp_lbi->user_instance = htonl (user_instance);
6168       if (mac_set)
6169         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6170       S (mp_lbi);
6171     }
6172   else
6173     {
6174       /* Construct the API message */
6175       M (CREATE_LOOPBACK, mp);
6176       if (mac_set)
6177         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6178       S (mp);
6179     }
6180
6181   W (ret);
6182   return ret;
6183 }
6184
6185 static int
6186 api_delete_loopback (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_delete_loopback_t *mp;
6190   u32 sw_if_index = ~0;
6191   int ret;
6192
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         ;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index == ~0)
6202     {
6203       errmsg ("missing sw_if_index");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (DELETE_LOOPBACK, mp);
6209   mp->sw_if_index = ntohl (sw_if_index);
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_want_stats (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_want_stats_t *mp;
6221   int enable = -1;
6222   int ret;
6223
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (enable == -1)
6235     {
6236       errmsg ("missing enable|disable");
6237       return -99;
6238     }
6239
6240   M (WANT_STATS, mp);
6241   mp->enable_disable = enable;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_want_interface_events (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_want_interface_events_t *mp;
6253   int enable = -1;
6254   int ret;
6255
6256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6257     {
6258       if (unformat (i, "enable"))
6259         enable = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (enable == -1)
6267     {
6268       errmsg ("missing enable|disable");
6269       return -99;
6270     }
6271
6272   M (WANT_INTERFACE_EVENTS, mp);
6273   mp->enable_disable = enable;
6274
6275   vam->interface_event_display = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282
6283 /* Note: non-static, called once to set up the initial intfc table */
6284 int
6285 api_sw_interface_dump (vat_main_t * vam)
6286 {
6287   vl_api_sw_interface_dump_t *mp;
6288   vl_api_control_ping_t *mp_ping;
6289   hash_pair_t *p;
6290   name_sort_t *nses = 0, *ns;
6291   sw_interface_subif_t *sub = NULL;
6292   int ret;
6293
6294   /* Toss the old name table */
6295   /* *INDENT-OFF* */
6296   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6297   ({
6298     vec_add2 (nses, ns, 1);
6299     ns->name = (u8 *)(p->key);
6300     ns->value = (u32) p->value[0];
6301   }));
6302   /* *INDENT-ON* */
6303
6304   hash_free (vam->sw_if_index_by_interface_name);
6305
6306   vec_foreach (ns, nses) vec_free (ns->name);
6307
6308   vec_free (nses);
6309
6310   vec_foreach (sub, vam->sw_if_subif_table)
6311   {
6312     vec_free (sub->interface_name);
6313   }
6314   vec_free (vam->sw_if_subif_table);
6315
6316   /* recreate the interface name hash table */
6317   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6318
6319   /* Get list of ethernets */
6320   M (SW_INTERFACE_DUMP, mp);
6321   mp->name_filter_valid = 1;
6322   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6323   S (mp);
6324
6325   /* and local / loopback interfaces */
6326   M (SW_INTERFACE_DUMP, mp);
6327   mp->name_filter_valid = 1;
6328   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6329   S (mp);
6330
6331   /* and packet-generator interfaces */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and vxlan-gpe tunnel interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6341            sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and vxlan tunnel interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and geneve tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and host (af_packet) interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and l2tpv3 tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6366            sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and GRE tunnel interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and LISP-GPE interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "lisp_gpe",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and IPSEC tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* Use a control ping for synchronization */
6389   MPING (CONTROL_PING, mp_ping);
6390   S (mp_ping);
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_flags (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_flags_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   u8 admin_up = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "admin-up"))
6410         admin_up = 1;
6411       else if (unformat (i, "admin-down"))
6412         admin_up = 0;
6413       else
6414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6417         sw_if_index_set = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_FLAGS, mp);
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->admin_up_down = admin_up;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply, return the good/bad news... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_rx_mode (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_rx_mode_t *mp;
6446   u32 sw_if_index;
6447   u8 sw_if_index_set = 0;
6448   int ret;
6449   u8 queue_id_valid = 0;
6450   u32 queue_id;
6451   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "queue %d", &queue_id))
6457         queue_id_valid = 1;
6458       else if (unformat (i, "polling"))
6459         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6460       else if (unformat (i, "interrupt"))
6461         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6462       else if (unformat (i, "adaptive"))
6463         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6464       else
6465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6479     {
6480       errmsg ("missing rx-mode");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (SW_INTERFACE_SET_RX_MODE, mp);
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->mode = mode;
6488   mp->queue_id_valid = queue_id_valid;
6489   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6490
6491   /* send it... */
6492   S (mp);
6493
6494   /* Wait for a reply, return the good/bad news... */
6495   W (ret);
6496   return ret;
6497 }
6498
6499 static int
6500 api_sw_interface_clear_stats (vat_main_t * vam)
6501 {
6502   unformat_input_t *i = vam->input;
6503   vl_api_sw_interface_clear_stats_t *mp;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else
6516         break;
6517     }
6518
6519   /* Construct the API message */
6520   M (SW_INTERFACE_CLEAR_STATS, mp);
6521
6522   if (sw_if_index_set == 1)
6523     mp->sw_if_index = ntohl (sw_if_index);
6524   else
6525     mp->sw_if_index = ~0;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply, return the good/bad news... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_add_del_address (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_add_del_address_t *mp;
6540   u32 sw_if_index;
6541   u8 sw_if_index_set = 0;
6542   u8 is_add = 1, del_all = 0;
6543   u32 address_length = 0;
6544   u8 v4_address_set = 0;
6545   u8 v6_address_set = 0;
6546   ip4_address_t v4address;
6547   ip6_address_t v6address;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "del-all"))
6554         del_all = 1;
6555       else if (unformat (i, "del"))
6556         is_add = 0;
6557       else
6558         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "%U/%d",
6563                          unformat_ip4_address, &v4address, &address_length))
6564         v4_address_set = 1;
6565       else if (unformat (i, "%U/%d",
6566                          unformat_ip6_address, &v6address, &address_length))
6567         v6_address_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577   if (v4_address_set && v6_address_set)
6578     {
6579       errmsg ("both v4 and v6 addresses set");
6580       return -99;
6581     }
6582   if (!v4_address_set && !v6_address_set && !del_all)
6583     {
6584       errmsg ("no addresses set");
6585       return -99;
6586     }
6587
6588   /* Construct the API message */
6589   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6590
6591   mp->sw_if_index = ntohl (sw_if_index);
6592   mp->is_add = is_add;
6593   mp->del_all = del_all;
6594   if (v6_address_set)
6595     {
6596       mp->is_ipv6 = 1;
6597       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6598     }
6599   else
6600     {
6601       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6602     }
6603   mp->address_length = address_length;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return good/bad news  */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_mpls_enable_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "disable"))
6631         enable = 0;
6632       else if (unformat (i, "dis"))
6633         enable = 0;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->enable = enable;
6649
6650   /* send it... */
6651   S (mp);
6652
6653   /* Wait for a reply... */
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_sw_interface_set_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_set_table_t *mp;
6663   u32 sw_if_index, vrf_id = 0;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set = 1;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set = 1;
6675       else if (unformat (i, "vrf %d", &vrf_id))
6676         ;
6677       else if (unformat (i, "ipv6"))
6678         is_ipv6 = 1;
6679       else
6680         break;
6681     }
6682
6683   if (sw_if_index_set == 0)
6684     {
6685       errmsg ("missing interface name or sw_if_index");
6686       return -99;
6687     }
6688
6689   /* Construct the API message */
6690   M (SW_INTERFACE_SET_TABLE, mp);
6691
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694   mp->vrf_id = ntohl (vrf_id);
6695
6696   /* send it... */
6697   S (mp);
6698
6699   /* Wait for a reply... */
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static void vl_api_sw_interface_get_table_reply_t_handler
6705   (vl_api_sw_interface_get_table_reply_t * mp)
6706 {
6707   vat_main_t *vam = &vat_main;
6708
6709   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6710
6711   vam->retval = ntohl (mp->retval);
6712   vam->result_ready = 1;
6713
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler_json
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720   vat_json_node_t node;
6721
6722   vat_json_init_object (&node);
6723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6724   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6725
6726   vat_json_print (vam->ofp, &node);
6727   vat_json_free (&node);
6728
6729   vam->retval = ntohl (mp->retval);
6730   vam->result_ready = 1;
6731 }
6732
6733 static int
6734 api_sw_interface_get_table (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_get_table_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 is_ipv6 = 0;
6741   int ret;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "ipv6"))
6750         is_ipv6 = 1;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   M (SW_INTERFACE_GET_TABLE, mp);
6762   mp->sw_if_index = htonl (sw_if_index);
6763   mp->is_ipv6 = is_ipv6;
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vpath (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vpath_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "enable"))
6788         is_enable = 1;
6789       else if (unformat (i, "disable"))
6790         is_enable = 0;
6791       else
6792         break;
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (SW_INTERFACE_SET_VPATH, mp);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->enable = is_enable;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply... */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6820   u32 sw_if_index = 0;
6821   u8 sw_if_index_set = 0;
6822   u8 is_enable = 1;
6823   u8 is_ipv6 = 0;
6824   int ret;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "enable"))
6834         is_enable = 1;
6835       else if (unformat (i, "disable"))
6836         is_enable = 0;
6837       else if (unformat (i, "ip4"))
6838         is_ipv6 = 0;
6839       else if (unformat (i, "ip6"))
6840         is_ipv6 = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855   mp->enable = is_enable;
6856   mp->is_ipv6 = is_ipv6;
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863   return ret;
6864 }
6865
6866 static int
6867 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_geneve_bypass_t *mp;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_enable = 1;
6874   u8 is_ipv6 = 0;
6875   int ret;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "enable"))
6885         is_enable = 1;
6886       else if (unformat (i, "disable"))
6887         is_enable = 0;
6888       else if (unformat (i, "ip4"))
6889         is_ipv6 = 0;
6890       else if (unformat (i, "ip6"))
6891         is_ipv6 = 1;
6892       else
6893         break;
6894     }
6895
6896   if (sw_if_index_set == 0)
6897     {
6898       errmsg ("missing interface name or sw_if_index");
6899       return -99;
6900     }
6901
6902   /* Construct the API message */
6903   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6904
6905   mp->sw_if_index = ntohl (sw_if_index);
6906   mp->enable = is_enable;
6907   mp->is_ipv6 = is_ipv6;
6908
6909   /* send it... */
6910   S (mp);
6911
6912   /* Wait for a reply... */
6913   W (ret);
6914   return ret;
6915 }
6916
6917 static int
6918 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6919 {
6920   unformat_input_t *i = vam->input;
6921   vl_api_sw_interface_set_l2_xconnect_t *mp;
6922   u32 rx_sw_if_index;
6923   u8 rx_sw_if_index_set = 0;
6924   u32 tx_sw_if_index;
6925   u8 tx_sw_if_index_set = 0;
6926   u8 enable = 1;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6933         rx_sw_if_index_set = 1;
6934       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6935         tx_sw_if_index_set = 1;
6936       else if (unformat (i, "rx"))
6937         {
6938           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939             {
6940               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6941                             &rx_sw_if_index))
6942                 rx_sw_if_index_set = 1;
6943             }
6944           else
6945             break;
6946         }
6947       else if (unformat (i, "tx"))
6948         {
6949           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950             {
6951               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6952                             &tx_sw_if_index))
6953                 tx_sw_if_index_set = 1;
6954             }
6955           else
6956             break;
6957         }
6958       else if (unformat (i, "enable"))
6959         enable = 1;
6960       else if (unformat (i, "disable"))
6961         enable = 0;
6962       else
6963         break;
6964     }
6965
6966   if (rx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing rx interface name or rx_sw_if_index");
6969       return -99;
6970     }
6971
6972   if (enable && (tx_sw_if_index_set == 0))
6973     {
6974       errmsg ("missing tx interface name or tx_sw_if_index");
6975       return -99;
6976     }
6977
6978   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6979
6980   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6981   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6982   mp->enable = enable;
6983
6984   S (mp);
6985   W (ret);
6986   return ret;
6987 }
6988
6989 static int
6990 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_sw_interface_set_l2_bridge_t *mp;
6994   u32 rx_sw_if_index;
6995   u8 rx_sw_if_index_set = 0;
6996   u32 bd_id;
6997   u8 bd_id_set = 0;
6998   u8 bvi = 0;
6999   u32 shg = 0;
7000   u8 enable = 1;
7001   int ret;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7007         rx_sw_if_index_set = 1;
7008       else if (unformat (i, "bd_id %d", &bd_id))
7009         bd_id_set = 1;
7010       else
7011         if (unformat
7012             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7013         rx_sw_if_index_set = 1;
7014       else if (unformat (i, "shg %d", &shg))
7015         ;
7016       else if (unformat (i, "bvi"))
7017         bvi = 1;
7018       else if (unformat (i, "enable"))
7019         enable = 1;
7020       else if (unformat (i, "disable"))
7021         enable = 0;
7022       else
7023         break;
7024     }
7025
7026   if (rx_sw_if_index_set == 0)
7027     {
7028       errmsg ("missing rx interface name or sw_if_index");
7029       return -99;
7030     }
7031
7032   if (enable && (bd_id_set == 0))
7033     {
7034       errmsg ("missing bridge domain");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7039
7040   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7041   mp->bd_id = ntohl (bd_id);
7042   mp->shg = (u8) shg;
7043   mp->bvi = bvi;
7044   mp->enable = enable;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_bridge_domain_dump (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_bridge_domain_dump_t *mp;
7056   vl_api_control_ping_t *mp_ping;
7057   u32 bd_id = ~0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "bd_id %d", &bd_id))
7064         ;
7065       else
7066         break;
7067     }
7068
7069   M (BRIDGE_DOMAIN_DUMP, mp);
7070   mp->bd_id = ntohl (bd_id);
7071   S (mp);
7072
7073   /* Use a control ping for synchronization */
7074   MPING (CONTROL_PING, mp_ping);
7075   S (mp_ping);
7076
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_bridge_domain_add_del (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_bridge_domain_add_del_t *mp;
7086   u32 bd_id = ~0;
7087   u8 is_add = 1;
7088   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7089   u8 *bd_tag = NULL;
7090   u32 mac_age = 0;
7091   int ret;
7092
7093   /* Parse args required to build the message */
7094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7095     {
7096       if (unformat (i, "bd_id %d", &bd_id))
7097         ;
7098       else if (unformat (i, "flood %d", &flood))
7099         ;
7100       else if (unformat (i, "uu-flood %d", &uu_flood))
7101         ;
7102       else if (unformat (i, "forward %d", &forward))
7103         ;
7104       else if (unformat (i, "learn %d", &learn))
7105         ;
7106       else if (unformat (i, "arp-term %d", &arp_term))
7107         ;
7108       else if (unformat (i, "mac-age %d", &mac_age))
7109         ;
7110       else if (unformat (i, "bd-tag %s", &bd_tag))
7111         ;
7112       else if (unformat (i, "del"))
7113         {
7114           is_add = 0;
7115           flood = uu_flood = forward = learn = 0;
7116         }
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       ret = -99;
7125       goto done;
7126     }
7127
7128   if (mac_age > 255)
7129     {
7130       errmsg ("mac age must be less than 256 ");
7131       ret = -99;
7132       goto done;
7133     }
7134
7135   if ((bd_tag) && (vec_len (bd_tag) > 63))
7136     {
7137       errmsg ("bd-tag cannot be longer than 63");
7138       ret = -99;
7139       goto done;
7140     }
7141
7142   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7143
7144   mp->bd_id = ntohl (bd_id);
7145   mp->flood = flood;
7146   mp->uu_flood = uu_flood;
7147   mp->forward = forward;
7148   mp->learn = learn;
7149   mp->arp_term = arp_term;
7150   mp->is_add = is_add;
7151   mp->mac_age = (u8) mac_age;
7152   if (bd_tag)
7153     {
7154       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7155       mp->bd_tag[vec_len (bd_tag)] = 0;
7156     }
7157   S (mp);
7158   W (ret);
7159
7160 done:
7161   vec_free (bd_tag);
7162   return ret;
7163 }
7164
7165 static int
7166 api_l2fib_flush_bd (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_l2fib_flush_bd_t *mp;
7170   u32 bd_id = ~0;
7171   int ret;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id));
7177       else
7178         break;
7179     }
7180
7181   if (bd_id == ~0)
7182     {
7183       errmsg ("missing bridge domain");
7184       return -99;
7185     }
7186
7187   M (L2FIB_FLUSH_BD, mp);
7188
7189   mp->bd_id = htonl (bd_id);
7190
7191   S (mp);
7192   W (ret);
7193   return ret;
7194 }
7195
7196 static int
7197 api_l2fib_flush_int (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_l2fib_flush_int_t *mp;
7201   u32 sw_if_index = ~0;
7202   int ret;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "sw_if_index %d", &sw_if_index));
7208       else
7209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7210       else
7211         break;
7212     }
7213
7214   if (sw_if_index == ~0)
7215     {
7216       errmsg ("missing interface name or sw_if_index");
7217       return -99;
7218     }
7219
7220   M (L2FIB_FLUSH_INT, mp);
7221
7222   mp->sw_if_index = ntohl (sw_if_index);
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_l2fib_add_del (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_l2fib_add_del_t *mp;
7234   f64 timeout;
7235   u8 mac[6] = { 0 };
7236   u8 mac_set = 0;
7237   u32 bd_id;
7238   u8 bd_id_set = 0;
7239   u32 sw_if_index = ~0;
7240   u8 sw_if_index_set = 0;
7241   u8 is_add = 1;
7242   u8 static_mac = 0;
7243   u8 filter_mac = 0;
7244   u8 bvi_mac = 0;
7245   int count = 1;
7246   f64 before = 0;
7247   int j;
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7253         mac_set = 1;
7254       else if (unformat (i, "bd_id %d", &bd_id))
7255         bd_id_set = 1;
7256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7257         sw_if_index_set = 1;
7258       else if (unformat (i, "sw_if"))
7259         {
7260           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261             {
7262               if (unformat
7263                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7264                 sw_if_index_set = 1;
7265             }
7266           else
7267             break;
7268         }
7269       else if (unformat (i, "static"))
7270         static_mac = 1;
7271       else if (unformat (i, "filter"))
7272         {
7273           filter_mac = 1;
7274           static_mac = 1;
7275         }
7276       else if (unformat (i, "bvi"))
7277         {
7278           bvi_mac = 1;
7279           static_mac = 1;
7280         }
7281       else if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "count %d", &count))
7284         ;
7285       else
7286         break;
7287     }
7288
7289   if (mac_set == 0)
7290     {
7291       errmsg ("missing mac address");
7292       return -99;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7302     {
7303       errmsg ("missing interface name or sw_if_index");
7304       return -99;
7305     }
7306
7307   if (count > 1)
7308     {
7309       /* Turn on async mode */
7310       vam->async_mode = 1;
7311       vam->async_errors = 0;
7312       before = vat_time_now (vam);
7313     }
7314
7315   for (j = 0; j < count; j++)
7316     {
7317       M (L2FIB_ADD_DEL, mp);
7318
7319       clib_memcpy (mp->mac, mac, 6);
7320       mp->bd_id = ntohl (bd_id);
7321       mp->is_add = is_add;
7322
7323       if (is_add)
7324         {
7325           mp->sw_if_index = ntohl (sw_if_index);
7326           mp->static_mac = static_mac;
7327           mp->filter_mac = filter_mac;
7328           mp->bvi_mac = bvi_mac;
7329         }
7330       increment_mac_address (mac);
7331       /* send it... */
7332       S (mp);
7333     }
7334
7335   if (count > 1)
7336     {
7337       vl_api_control_ping_t *mp_ping;
7338       f64 after;
7339
7340       /* Shut off async mode */
7341       vam->async_mode = 0;
7342
7343       MPING (CONTROL_PING, mp_ping);
7344       S (mp_ping);
7345
7346       timeout = vat_time_now (vam) + 1.0;
7347       while (vat_time_now (vam) < timeout)
7348         if (vam->result_ready == 1)
7349           goto out;
7350       vam->retval = -99;
7351
7352     out:
7353       if (vam->retval == -99)
7354         errmsg ("timeout");
7355
7356       if (vam->async_errors > 0)
7357         {
7358           errmsg ("%d asynchronous errors", vam->async_errors);
7359           vam->retval = -98;
7360         }
7361       vam->async_errors = 0;
7362       after = vat_time_now (vam);
7363
7364       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7365              count, after - before, count / (after - before));
7366     }
7367   else
7368     {
7369       int ret;
7370
7371       /* Wait for a reply... */
7372       W (ret);
7373       return ret;
7374     }
7375   /* Return the good/bad news */
7376   return (vam->retval);
7377 }
7378
7379 static int
7380 api_bridge_domain_set_mac_age (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_bridge_domain_set_mac_age_t *mp;
7384   u32 bd_id = ~0;
7385   u32 mac_age = 0;
7386   int ret;
7387
7388   /* Parse args required to build the message */
7389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7390     {
7391       if (unformat (i, "bd_id %d", &bd_id));
7392       else if (unformat (i, "mac-age %d", &mac_age));
7393       else
7394         break;
7395     }
7396
7397   if (bd_id == ~0)
7398     {
7399       errmsg ("missing bridge domain");
7400       return -99;
7401     }
7402
7403   if (mac_age > 255)
7404     {
7405       errmsg ("mac age must be less than 256 ");
7406       return -99;
7407     }
7408
7409   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7410
7411   mp->bd_id = htonl (bd_id);
7412   mp->mac_age = (u8) mac_age;
7413
7414   S (mp);
7415   W (ret);
7416   return ret;
7417 }
7418
7419 static int
7420 api_l2_flags (vat_main_t * vam)
7421 {
7422   unformat_input_t *i = vam->input;
7423   vl_api_l2_flags_t *mp;
7424   u32 sw_if_index;
7425   u32 flags = 0;
7426   u8 sw_if_index_set = 0;
7427   u8 is_set = 0;
7428   int ret;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "sw_if_index %d", &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if"))
7436         {
7437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438             {
7439               if (unformat
7440                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7441                 sw_if_index_set = 1;
7442             }
7443           else
7444             break;
7445         }
7446       else if (unformat (i, "learn"))
7447         flags |= L2_LEARN;
7448       else if (unformat (i, "forward"))
7449         flags |= L2_FWD;
7450       else if (unformat (i, "flood"))
7451         flags |= L2_FLOOD;
7452       else if (unformat (i, "uu-flood"))
7453         flags |= L2_UU_FLOOD;
7454       else if (unformat (i, "arp-term"))
7455         flags |= L2_ARP_TERM;
7456       else if (unformat (i, "off"))
7457         is_set = 0;
7458       else if (unformat (i, "disable"))
7459         is_set = 0;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing interface name or sw_if_index");
7467       return -99;
7468     }
7469
7470   M (L2_FLAGS, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473   mp->feature_bitmap = ntohl (flags);
7474   mp->is_set = is_set;
7475
7476   S (mp);
7477   W (ret);
7478   return ret;
7479 }
7480
7481 static int
7482 api_bridge_flags (vat_main_t * vam)
7483 {
7484   unformat_input_t *i = vam->input;
7485   vl_api_bridge_flags_t *mp;
7486   u32 bd_id;
7487   u8 bd_id_set = 0;
7488   u8 is_set = 1;
7489   u32 flags = 0;
7490   int ret;
7491
7492   /* Parse args required to build the message */
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "bd_id %d", &bd_id))
7496         bd_id_set = 1;
7497       else if (unformat (i, "learn"))
7498         flags |= L2_LEARN;
7499       else if (unformat (i, "forward"))
7500         flags |= L2_FWD;
7501       else if (unformat (i, "flood"))
7502         flags |= L2_FLOOD;
7503       else if (unformat (i, "uu-flood"))
7504         flags |= L2_UU_FLOOD;
7505       else if (unformat (i, "arp-term"))
7506         flags |= L2_ARP_TERM;
7507       else if (unformat (i, "off"))
7508         is_set = 0;
7509       else if (unformat (i, "disable"))
7510         is_set = 0;
7511       else
7512         break;
7513     }
7514
7515   if (bd_id_set == 0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   M (BRIDGE_FLAGS, mp);
7522
7523   mp->bd_id = ntohl (bd_id);
7524   mp->feature_bitmap = ntohl (flags);
7525   mp->is_set = is_set;
7526
7527   S (mp);
7528   W (ret);
7529   return ret;
7530 }
7531
7532 static int
7533 api_bd_ip_mac_add_del (vat_main_t * vam)
7534 {
7535   unformat_input_t *i = vam->input;
7536   vl_api_bd_ip_mac_add_del_t *mp;
7537   u32 bd_id;
7538   u8 is_ipv6 = 0;
7539   u8 is_add = 1;
7540   u8 bd_id_set = 0;
7541   u8 ip_set = 0;
7542   u8 mac_set = 0;
7543   ip4_address_t v4addr;
7544   ip6_address_t v6addr;
7545   u8 macaddr[6];
7546   int ret;
7547
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "bd_id %d", &bd_id))
7553         {
7554           bd_id_set++;
7555         }
7556       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7557         {
7558           ip_set++;
7559         }
7560       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7561         {
7562           ip_set++;
7563           is_ipv6++;
7564         }
7565       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7566         {
7567           mac_set++;
7568         }
7569       else if (unformat (i, "del"))
7570         is_add = 0;
7571       else
7572         break;
7573     }
7574
7575   if (bd_id_set == 0)
7576     {
7577       errmsg ("missing bridge domain");
7578       return -99;
7579     }
7580   else if (ip_set == 0)
7581     {
7582       errmsg ("missing IP address");
7583       return -99;
7584     }
7585   else if (mac_set == 0)
7586     {
7587       errmsg ("missing MAC address");
7588       return -99;
7589     }
7590
7591   M (BD_IP_MAC_ADD_DEL, mp);
7592
7593   mp->bd_id = ntohl (bd_id);
7594   mp->is_ipv6 = is_ipv6;
7595   mp->is_add = is_add;
7596   if (is_ipv6)
7597     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7598   else
7599     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7600   clib_memcpy (mp->mac_address, macaddr, 6);
7601   S (mp);
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_connect (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_connect_t *mp;
7611   u8 mac_address[6];
7612   u8 random_mac = 1;
7613   u8 name_set = 0;
7614   u8 *tap_name;
7615   u8 *tag = 0;
7616   ip4_address_t ip4_address;
7617   u32 ip4_mask_width;
7618   int ip4_address_set = 0;
7619   ip6_address_t ip6_address;
7620   u32 ip6_mask_width;
7621   int ip6_address_set = 0;
7622   int ret;
7623
7624   memset (mac_address, 0, sizeof (mac_address));
7625
7626   /* Parse args required to build the message */
7627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7630         {
7631           random_mac = 0;
7632         }
7633       else if (unformat (i, "random-mac"))
7634         random_mac = 1;
7635       else if (unformat (i, "tapname %s", &tap_name))
7636         name_set = 1;
7637       else if (unformat (i, "tag %s", &tag))
7638         ;
7639       else if (unformat (i, "address %U/%d",
7640                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7641         ip4_address_set = 1;
7642       else if (unformat (i, "address %U/%d",
7643                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7644         ip6_address_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (name_set == 0)
7650     {
7651       errmsg ("missing tap name");
7652       return -99;
7653     }
7654   if (vec_len (tap_name) > 63)
7655     {
7656       errmsg ("tap name too long");
7657       return -99;
7658     }
7659   vec_add1 (tap_name, 0);
7660
7661   if (vec_len (tag) > 63)
7662     {
7663       errmsg ("tag too long");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (TAP_CONNECT, mp);
7669
7670   mp->use_random_mac = random_mac;
7671   clib_memcpy (mp->mac_address, mac_address, 6);
7672   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7673   if (tag)
7674     clib_memcpy (mp->tag, tag, vec_len (tag));
7675
7676   if (ip4_address_set)
7677     {
7678       mp->ip4_address_set = 1;
7679       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7680       mp->ip4_mask_width = ip4_mask_width;
7681     }
7682   if (ip6_address_set)
7683     {
7684       mp->ip6_address_set = 1;
7685       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7686       mp->ip6_mask_width = ip6_mask_width;
7687     }
7688
7689   vec_free (tap_name);
7690   vec_free (tag);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_tap_modify (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_tap_modify_t *mp;
7705   u8 mac_address[6];
7706   u8 random_mac = 1;
7707   u8 name_set = 0;
7708   u8 *tap_name;
7709   u32 sw_if_index = ~0;
7710   u8 sw_if_index_set = 0;
7711   int ret;
7712
7713   memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7723         {
7724           random_mac = 0;
7725         }
7726       else if (unformat (i, "random-mac"))
7727         random_mac = 1;
7728       else if (unformat (i, "tapname %s", &tap_name))
7729         name_set = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing vpp interface name");
7737       return -99;
7738     }
7739   if (name_set == 0)
7740     {
7741       errmsg ("missing tap name");
7742       return -99;
7743     }
7744   if (vec_len (tap_name) > 63)
7745     {
7746       errmsg ("tap name too long");
7747     }
7748   vec_add1 (tap_name, 0);
7749
7750   /* Construct the API message */
7751   M (TAP_MODIFY, mp);
7752
7753   mp->use_random_mac = random_mac;
7754   mp->sw_if_index = ntohl (sw_if_index);
7755   clib_memcpy (mp->mac_address, mac_address, 6);
7756   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7757   vec_free (tap_name);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_tap_delete (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_tap_delete_t *mp;
7772   u32 sw_if_index = ~0;
7773   u8 sw_if_index_set = 0;
7774   int ret;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing vpp interface name");
7790       return -99;
7791     }
7792
7793   /* Construct the API message */
7794   M (TAP_DELETE, mp);
7795
7796   mp->sw_if_index = ntohl (sw_if_index);
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply... */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 static int
7807 api_tap_create_v2 (vat_main_t * vam)
7808 {
7809   unformat_input_t *i = vam->input;
7810   vl_api_tap_create_v2_t *mp;
7811   u8 mac_address[6];
7812   u8 random_mac = 1;
7813   u8 name_set = 0;
7814   u8 *tap_name;
7815   u8 *net_ns = 0;
7816   u8 net_ns_set = 0;
7817   int ret;
7818   int rx_ring_sz = 0, tx_ring_sz = 0;
7819
7820   memset (mac_address, 0, sizeof (mac_address));
7821
7822   /* Parse args required to build the message */
7823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7824     {
7825       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7826         {
7827           random_mac = 0;
7828         }
7829       else if (unformat (i, "name %s", &tap_name))
7830         name_set = 1;
7831       else if (unformat (i, "host-ns %s", &net_ns))
7832         net_ns_set = 1;
7833       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7834         ;
7835       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7836         ;
7837       else
7838         break;
7839     }
7840
7841   if (name_set == 0)
7842     {
7843       errmsg ("missing tap name. ");
7844       return -99;
7845     }
7846   if (vec_len (tap_name) > 63)
7847     {
7848       errmsg ("tap name too long. ");
7849       return -99;
7850     }
7851   if (vec_len (net_ns) > 63)
7852     {
7853       errmsg ("host name space too long. ");
7854       return -99;
7855     }
7856   if (!is_pow2 (rx_ring_sz))
7857     {
7858       errmsg ("rx ring size must be power of 2. ");
7859       return -99;
7860     }
7861   if (rx_ring_sz > 32768)
7862     {
7863       errmsg ("rx ring size must be 32768 or lower. ");
7864       return -99;
7865     }
7866   if (!is_pow2 (tx_ring_sz))
7867     {
7868       errmsg ("tx ring size must be power of 2. ");
7869       return -99;
7870     }
7871   if (tx_ring_sz > 32768)
7872     {
7873       errmsg ("tx ring size must be 32768 or lower. ");
7874       return -99;
7875     }
7876
7877   vec_add1 (tap_name, 0);
7878
7879   /* Construct the API message */
7880   M (TAP_CREATE_V2, mp);
7881
7882   mp->use_random_mac = random_mac;
7883   clib_memcpy (mp->mac_address, mac_address, 6);
7884   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7885   mp->net_ns_set = net_ns_set;
7886   mp->rx_ring_sz = rx_ring_sz;
7887   mp->tx_ring_sz = tx_ring_sz;
7888   if (net_ns)
7889     clib_memcpy (mp->net_ns, net_ns, vec_len (net_ns));
7890
7891   vec_free (tap_name);
7892
7893   /* send it... */
7894   S (mp);
7895
7896   /* Wait for a reply... */
7897   W (ret);
7898   return ret;
7899 }
7900
7901 static int
7902 api_tap_delete_v2 (vat_main_t * vam)
7903 {
7904   unformat_input_t *i = vam->input;
7905   vl_api_tap_delete_v2_t *mp;
7906   u32 sw_if_index = ~0;
7907   u8 sw_if_index_set = 0;
7908   int ret;
7909
7910   /* Parse args required to build the message */
7911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7912     {
7913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7914         sw_if_index_set = 1;
7915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7916         sw_if_index_set = 1;
7917       else
7918         break;
7919     }
7920
7921   if (sw_if_index_set == 0)
7922     {
7923       errmsg ("missing vpp interface name. ");
7924       return -99;
7925     }
7926
7927   /* Construct the API message */
7928   M (TAP_DELETE_V2, mp);
7929
7930   mp->sw_if_index = ntohl (sw_if_index);
7931
7932   /* send it... */
7933   S (mp);
7934
7935   /* Wait for a reply... */
7936   W (ret);
7937   return ret;
7938 }
7939
7940 static int
7941 api_ip_table_add_del (vat_main_t * vam)
7942 {
7943   unformat_input_t *i = vam->input;
7944   vl_api_ip_table_add_del_t *mp;
7945   u32 table_id = ~0;
7946   u8 is_ipv6 = 0;
7947   u8 is_add = 1;
7948   int ret = 0;
7949
7950   /* Parse args required to build the message */
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "ipv6"))
7954         is_ipv6 = 1;
7955       else if (unformat (i, "del"))
7956         is_add = 0;
7957       else if (unformat (i, "add"))
7958         is_add = 1;
7959       else if (unformat (i, "table %d", &table_id))
7960         ;
7961       else
7962         {
7963           clib_warning ("parse error '%U'", format_unformat_error, i);
7964           return -99;
7965         }
7966     }
7967
7968   if (~0 == table_id)
7969     {
7970       errmsg ("missing table-ID");
7971       return -99;
7972     }
7973
7974   /* Construct the API message */
7975   M (IP_TABLE_ADD_DEL, mp);
7976
7977   mp->table_id = ntohl (table_id);
7978   mp->is_ipv6 = is_ipv6;
7979   mp->is_add = is_add;
7980
7981   /* send it... */
7982   S (mp);
7983
7984   /* Wait for a reply... */
7985   W (ret);
7986
7987   return ret;
7988 }
7989
7990 static int
7991 api_ip_add_del_route (vat_main_t * vam)
7992 {
7993   unformat_input_t *i = vam->input;
7994   vl_api_ip_add_del_route_t *mp;
7995   u32 sw_if_index = ~0, vrf_id = 0;
7996   u8 is_ipv6 = 0;
7997   u8 is_local = 0, is_drop = 0;
7998   u8 is_unreach = 0, is_prohibit = 0;
7999   u8 create_vrf_if_needed = 0;
8000   u8 is_add = 1;
8001   u32 next_hop_weight = 1;
8002   u8 is_multipath = 0;
8003   u8 address_set = 0;
8004   u8 address_length_set = 0;
8005   u32 next_hop_table_id = 0;
8006   u32 resolve_attempts = 0;
8007   u32 dst_address_length = 0;
8008   u8 next_hop_set = 0;
8009   ip4_address_t v4_dst_address, v4_next_hop_address;
8010   ip6_address_t v6_dst_address, v6_next_hop_address;
8011   int count = 1;
8012   int j;
8013   f64 before = 0;
8014   u32 random_add_del = 0;
8015   u32 *random_vector = 0;
8016   uword *random_hash;
8017   u32 random_seed = 0xdeaddabe;
8018   u32 classify_table_index = ~0;
8019   u8 is_classify = 0;
8020   u8 resolve_host = 0, resolve_attached = 0;
8021   mpls_label_t *next_hop_out_label_stack = NULL;
8022   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8023   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8024
8025   /* Parse args required to build the message */
8026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8029         ;
8030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8031         ;
8032       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8033         {
8034           address_set = 1;
8035           is_ipv6 = 0;
8036         }
8037       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8038         {
8039           address_set = 1;
8040           is_ipv6 = 1;
8041         }
8042       else if (unformat (i, "/%d", &dst_address_length))
8043         {
8044           address_length_set = 1;
8045         }
8046
8047       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8048                                          &v4_next_hop_address))
8049         {
8050           next_hop_set = 1;
8051         }
8052       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8053                                          &v6_next_hop_address))
8054         {
8055           next_hop_set = 1;
8056         }
8057       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8058         ;
8059       else if (unformat (i, "weight %d", &next_hop_weight))
8060         ;
8061       else if (unformat (i, "drop"))
8062         {
8063           is_drop = 1;
8064         }
8065       else if (unformat (i, "null-send-unreach"))
8066         {
8067           is_unreach = 1;
8068         }
8069       else if (unformat (i, "null-send-prohibit"))
8070         {
8071           is_prohibit = 1;
8072         }
8073       else if (unformat (i, "local"))
8074         {
8075           is_local = 1;
8076         }
8077       else if (unformat (i, "classify %d", &classify_table_index))
8078         {
8079           is_classify = 1;
8080         }
8081       else if (unformat (i, "del"))
8082         is_add = 0;
8083       else if (unformat (i, "add"))
8084         is_add = 1;
8085       else if (unformat (i, "resolve-via-host"))
8086         resolve_host = 1;
8087       else if (unformat (i, "resolve-via-attached"))
8088         resolve_attached = 1;
8089       else if (unformat (i, "multipath"))
8090         is_multipath = 1;
8091       else if (unformat (i, "vrf %d", &vrf_id))
8092         ;
8093       else if (unformat (i, "create-vrf"))
8094         create_vrf_if_needed = 1;
8095       else if (unformat (i, "count %d", &count))
8096         ;
8097       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8098         ;
8099       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8100         ;
8101       else if (unformat (i, "out-label %d", &next_hop_out_label))
8102         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8103       else if (unformat (i, "via-label %d", &next_hop_via_label))
8104         ;
8105       else if (unformat (i, "random"))
8106         random_add_del = 1;
8107       else if (unformat (i, "seed %d", &random_seed))
8108         ;
8109       else
8110         {
8111           clib_warning ("parse error '%U'", format_unformat_error, i);
8112           return -99;
8113         }
8114     }
8115
8116   if (!next_hop_set && !is_drop && !is_local &&
8117       !is_classify && !is_unreach && !is_prohibit &&
8118       MPLS_LABEL_INVALID == next_hop_via_label)
8119     {
8120       errmsg
8121         ("next hop / local / drop / unreach / prohibit / classify not set");
8122       return -99;
8123     }
8124
8125   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8126     {
8127       errmsg ("next hop and next-hop via label set");
8128       return -99;
8129     }
8130   if (address_set == 0)
8131     {
8132       errmsg ("missing addresses");
8133       return -99;
8134     }
8135
8136   if (address_length_set == 0)
8137     {
8138       errmsg ("missing address length");
8139       return -99;
8140     }
8141
8142   /* Generate a pile of unique, random routes */
8143   if (random_add_del)
8144     {
8145       u32 this_random_address;
8146       random_hash = hash_create (count, sizeof (uword));
8147
8148       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8149       for (j = 0; j <= count; j++)
8150         {
8151           do
8152             {
8153               this_random_address = random_u32 (&random_seed);
8154               this_random_address =
8155                 clib_host_to_net_u32 (this_random_address);
8156             }
8157           while (hash_get (random_hash, this_random_address));
8158           vec_add1 (random_vector, this_random_address);
8159           hash_set (random_hash, this_random_address, 1);
8160         }
8161       hash_free (random_hash);
8162       v4_dst_address.as_u32 = random_vector[0];
8163     }
8164
8165   if (count > 1)
8166     {
8167       /* Turn on async mode */
8168       vam->async_mode = 1;
8169       vam->async_errors = 0;
8170       before = vat_time_now (vam);
8171     }
8172
8173   for (j = 0; j < count; j++)
8174     {
8175       /* Construct the API message */
8176       M2 (IP_ADD_DEL_ROUTE, mp,
8177           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8178
8179       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8180       mp->table_id = ntohl (vrf_id);
8181       mp->create_vrf_if_needed = create_vrf_if_needed;
8182
8183       mp->is_add = is_add;
8184       mp->is_drop = is_drop;
8185       mp->is_unreach = is_unreach;
8186       mp->is_prohibit = is_prohibit;
8187       mp->is_ipv6 = is_ipv6;
8188       mp->is_local = is_local;
8189       mp->is_classify = is_classify;
8190       mp->is_multipath = is_multipath;
8191       mp->is_resolve_host = resolve_host;
8192       mp->is_resolve_attached = resolve_attached;
8193       mp->next_hop_weight = next_hop_weight;
8194       mp->dst_address_length = dst_address_length;
8195       mp->next_hop_table_id = ntohl (next_hop_table_id);
8196       mp->classify_table_index = ntohl (classify_table_index);
8197       mp->next_hop_via_label = ntohl (next_hop_via_label);
8198       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8199       if (0 != mp->next_hop_n_out_labels)
8200         {
8201           memcpy (mp->next_hop_out_label_stack,
8202                   next_hop_out_label_stack,
8203                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8204           vec_free (next_hop_out_label_stack);
8205         }
8206
8207       if (is_ipv6)
8208         {
8209           clib_memcpy (mp->dst_address, &v6_dst_address,
8210                        sizeof (v6_dst_address));
8211           if (next_hop_set)
8212             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8213                          sizeof (v6_next_hop_address));
8214           increment_v6_address (&v6_dst_address);
8215         }
8216       else
8217         {
8218           clib_memcpy (mp->dst_address, &v4_dst_address,
8219                        sizeof (v4_dst_address));
8220           if (next_hop_set)
8221             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8222                          sizeof (v4_next_hop_address));
8223           if (random_add_del)
8224             v4_dst_address.as_u32 = random_vector[j + 1];
8225           else
8226             increment_v4_address (&v4_dst_address);
8227         }
8228       /* send it... */
8229       S (mp);
8230       /* If we receive SIGTERM, stop now... */
8231       if (vam->do_exit)
8232         break;
8233     }
8234
8235   /* When testing multiple add/del ops, use a control-ping to sync */
8236   if (count > 1)
8237     {
8238       vl_api_control_ping_t *mp_ping;
8239       f64 after;
8240       f64 timeout;
8241
8242       /* Shut off async mode */
8243       vam->async_mode = 0;
8244
8245       MPING (CONTROL_PING, mp_ping);
8246       S (mp_ping);
8247
8248       timeout = vat_time_now (vam) + 1.0;
8249       while (vat_time_now (vam) < timeout)
8250         if (vam->result_ready == 1)
8251           goto out;
8252       vam->retval = -99;
8253
8254     out:
8255       if (vam->retval == -99)
8256         errmsg ("timeout");
8257
8258       if (vam->async_errors > 0)
8259         {
8260           errmsg ("%d asynchronous errors", vam->async_errors);
8261           vam->retval = -98;
8262         }
8263       vam->async_errors = 0;
8264       after = vat_time_now (vam);
8265
8266       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8267       if (j > 0)
8268         count = j;
8269
8270       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8271              count, after - before, count / (after - before));
8272     }
8273   else
8274     {
8275       int ret;
8276
8277       /* Wait for a reply... */
8278       W (ret);
8279       return ret;
8280     }
8281
8282   /* Return the good/bad news */
8283   return (vam->retval);
8284 }
8285
8286 static int
8287 api_ip_mroute_add_del (vat_main_t * vam)
8288 {
8289   unformat_input_t *i = vam->input;
8290   vl_api_ip_mroute_add_del_t *mp;
8291   u32 sw_if_index = ~0, vrf_id = 0;
8292   u8 is_ipv6 = 0;
8293   u8 is_local = 0;
8294   u8 create_vrf_if_needed = 0;
8295   u8 is_add = 1;
8296   u8 address_set = 0;
8297   u32 grp_address_length = 0;
8298   ip4_address_t v4_grp_address, v4_src_address;
8299   ip6_address_t v6_grp_address, v6_src_address;
8300   mfib_itf_flags_t iflags = 0;
8301   mfib_entry_flags_t eflags = 0;
8302   int ret;
8303
8304   /* Parse args required to build the message */
8305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8306     {
8307       if (unformat (i, "sw_if_index %d", &sw_if_index))
8308         ;
8309       else if (unformat (i, "%U %U",
8310                          unformat_ip4_address, &v4_src_address,
8311                          unformat_ip4_address, &v4_grp_address))
8312         {
8313           grp_address_length = 64;
8314           address_set = 1;
8315           is_ipv6 = 0;
8316         }
8317       else if (unformat (i, "%U %U",
8318                          unformat_ip6_address, &v6_src_address,
8319                          unformat_ip6_address, &v6_grp_address))
8320         {
8321           grp_address_length = 256;
8322           address_set = 1;
8323           is_ipv6 = 1;
8324         }
8325       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8326         {
8327           memset (&v4_src_address, 0, sizeof (v4_src_address));
8328           grp_address_length = 32;
8329           address_set = 1;
8330           is_ipv6 = 0;
8331         }
8332       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8333         {
8334           memset (&v6_src_address, 0, sizeof (v6_src_address));
8335           grp_address_length = 128;
8336           address_set = 1;
8337           is_ipv6 = 1;
8338         }
8339       else if (unformat (i, "/%d", &grp_address_length))
8340         ;
8341       else if (unformat (i, "local"))
8342         {
8343           is_local = 1;
8344         }
8345       else if (unformat (i, "del"))
8346         is_add = 0;
8347       else if (unformat (i, "add"))
8348         is_add = 1;
8349       else if (unformat (i, "vrf %d", &vrf_id))
8350         ;
8351       else if (unformat (i, "create-vrf"))
8352         create_vrf_if_needed = 1;
8353       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8354         ;
8355       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8356         ;
8357       else
8358         {
8359           clib_warning ("parse error '%U'", format_unformat_error, i);
8360           return -99;
8361         }
8362     }
8363
8364   if (address_set == 0)
8365     {
8366       errmsg ("missing addresses\n");
8367       return -99;
8368     }
8369
8370   /* Construct the API message */
8371   M (IP_MROUTE_ADD_DEL, mp);
8372
8373   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8374   mp->table_id = ntohl (vrf_id);
8375   mp->create_vrf_if_needed = create_vrf_if_needed;
8376
8377   mp->is_add = is_add;
8378   mp->is_ipv6 = is_ipv6;
8379   mp->is_local = is_local;
8380   mp->itf_flags = ntohl (iflags);
8381   mp->entry_flags = ntohl (eflags);
8382   mp->grp_address_length = grp_address_length;
8383   mp->grp_address_length = ntohs (mp->grp_address_length);
8384
8385   if (is_ipv6)
8386     {
8387       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8388       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8389     }
8390   else
8391     {
8392       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8393       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8394
8395     }
8396
8397   /* send it... */
8398   S (mp);
8399   /* Wait for a reply... */
8400   W (ret);
8401   return ret;
8402 }
8403
8404 static int
8405 api_mpls_table_add_del (vat_main_t * vam)
8406 {
8407   unformat_input_t *i = vam->input;
8408   vl_api_mpls_table_add_del_t *mp;
8409   u32 table_id = ~0;
8410   u8 is_add = 1;
8411   int ret = 0;
8412
8413   /* Parse args required to build the message */
8414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8415     {
8416       if (unformat (i, "table %d", &table_id))
8417         ;
8418       else if (unformat (i, "del"))
8419         is_add = 0;
8420       else if (unformat (i, "add"))
8421         is_add = 1;
8422       else
8423         {
8424           clib_warning ("parse error '%U'", format_unformat_error, i);
8425           return -99;
8426         }
8427     }
8428
8429   if (~0 == table_id)
8430     {
8431       errmsg ("missing table-ID");
8432       return -99;
8433     }
8434
8435   /* Construct the API message */
8436   M (MPLS_TABLE_ADD_DEL, mp);
8437
8438   mp->mt_table_id = ntohl (table_id);
8439   mp->mt_is_add = is_add;
8440
8441   /* send it... */
8442   S (mp);
8443
8444   /* Wait for a reply... */
8445   W (ret);
8446
8447   return ret;
8448 }
8449
8450 static int
8451 api_mpls_route_add_del (vat_main_t * vam)
8452 {
8453   unformat_input_t *i = vam->input;
8454   vl_api_mpls_route_add_del_t *mp;
8455   u32 sw_if_index = ~0, table_id = 0;
8456   u8 create_table_if_needed = 0;
8457   u8 is_add = 1;
8458   u32 next_hop_weight = 1;
8459   u8 is_multipath = 0;
8460   u32 next_hop_table_id = 0;
8461   u8 next_hop_set = 0;
8462   ip4_address_t v4_next_hop_address = {
8463     .as_u32 = 0,
8464   };
8465   ip6_address_t v6_next_hop_address = { {0} };
8466   int count = 1;
8467   int j;
8468   f64 before = 0;
8469   u32 classify_table_index = ~0;
8470   u8 is_classify = 0;
8471   u8 resolve_host = 0, resolve_attached = 0;
8472   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8473   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8474   mpls_label_t *next_hop_out_label_stack = NULL;
8475   mpls_label_t local_label = MPLS_LABEL_INVALID;
8476   u8 is_eos = 0;
8477   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8478
8479   /* Parse args required to build the message */
8480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8481     {
8482       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8483         ;
8484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8485         ;
8486       else if (unformat (i, "%d", &local_label))
8487         ;
8488       else if (unformat (i, "eos"))
8489         is_eos = 1;
8490       else if (unformat (i, "non-eos"))
8491         is_eos = 0;
8492       else if (unformat (i, "via %U", unformat_ip4_address,
8493                          &v4_next_hop_address))
8494         {
8495           next_hop_set = 1;
8496           next_hop_proto = DPO_PROTO_IP4;
8497         }
8498       else if (unformat (i, "via %U", unformat_ip6_address,
8499                          &v6_next_hop_address))
8500         {
8501           next_hop_set = 1;
8502           next_hop_proto = DPO_PROTO_IP6;
8503         }
8504       else if (unformat (i, "weight %d", &next_hop_weight))
8505         ;
8506       else if (unformat (i, "create-table"))
8507         create_table_if_needed = 1;
8508       else if (unformat (i, "classify %d", &classify_table_index))
8509         {
8510           is_classify = 1;
8511         }
8512       else if (unformat (i, "del"))
8513         is_add = 0;
8514       else if (unformat (i, "add"))
8515         is_add = 1;
8516       else if (unformat (i, "resolve-via-host"))
8517         resolve_host = 1;
8518       else if (unformat (i, "resolve-via-attached"))
8519         resolve_attached = 1;
8520       else if (unformat (i, "multipath"))
8521         is_multipath = 1;
8522       else if (unformat (i, "count %d", &count))
8523         ;
8524       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8525         {
8526           next_hop_set = 1;
8527           next_hop_proto = DPO_PROTO_IP4;
8528         }
8529       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8530         {
8531           next_hop_set = 1;
8532           next_hop_proto = DPO_PROTO_IP6;
8533         }
8534       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8535         ;
8536       else if (unformat (i, "via-label %d", &next_hop_via_label))
8537         ;
8538       else if (unformat (i, "out-label %d", &next_hop_out_label))
8539         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8540       else
8541         {
8542           clib_warning ("parse error '%U'", format_unformat_error, i);
8543           return -99;
8544         }
8545     }
8546
8547   if (!next_hop_set && !is_classify)
8548     {
8549       errmsg ("next hop / classify not set");
8550       return -99;
8551     }
8552
8553   if (MPLS_LABEL_INVALID == local_label)
8554     {
8555       errmsg ("missing label");
8556       return -99;
8557     }
8558
8559   if (count > 1)
8560     {
8561       /* Turn on async mode */
8562       vam->async_mode = 1;
8563       vam->async_errors = 0;
8564       before = vat_time_now (vam);
8565     }
8566
8567   for (j = 0; j < count; j++)
8568     {
8569       /* Construct the API message */
8570       M2 (MPLS_ROUTE_ADD_DEL, mp,
8571           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8572
8573       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8574       mp->mr_table_id = ntohl (table_id);
8575       mp->mr_create_table_if_needed = create_table_if_needed;
8576
8577       mp->mr_is_add = is_add;
8578       mp->mr_next_hop_proto = next_hop_proto;
8579       mp->mr_is_classify = is_classify;
8580       mp->mr_is_multipath = is_multipath;
8581       mp->mr_is_resolve_host = resolve_host;
8582       mp->mr_is_resolve_attached = resolve_attached;
8583       mp->mr_next_hop_weight = next_hop_weight;
8584       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8585       mp->mr_classify_table_index = ntohl (classify_table_index);
8586       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8587       mp->mr_label = ntohl (local_label);
8588       mp->mr_eos = is_eos;
8589
8590       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8591       if (0 != mp->mr_next_hop_n_out_labels)
8592         {
8593           memcpy (mp->mr_next_hop_out_label_stack,
8594                   next_hop_out_label_stack,
8595                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8596           vec_free (next_hop_out_label_stack);
8597         }
8598
8599       if (next_hop_set)
8600         {
8601           if (DPO_PROTO_IP4 == next_hop_proto)
8602             {
8603               clib_memcpy (mp->mr_next_hop,
8604                            &v4_next_hop_address,
8605                            sizeof (v4_next_hop_address));
8606             }
8607           else if (DPO_PROTO_IP6 == next_hop_proto)
8608
8609             {
8610               clib_memcpy (mp->mr_next_hop,
8611                            &v6_next_hop_address,
8612                            sizeof (v6_next_hop_address));
8613             }
8614         }
8615       local_label++;
8616
8617       /* send it... */
8618       S (mp);
8619       /* If we receive SIGTERM, stop now... */
8620       if (vam->do_exit)
8621         break;
8622     }
8623
8624   /* When testing multiple add/del ops, use a control-ping to sync */
8625   if (count > 1)
8626     {
8627       vl_api_control_ping_t *mp_ping;
8628       f64 after;
8629       f64 timeout;
8630
8631       /* Shut off async mode */
8632       vam->async_mode = 0;
8633
8634       MPING (CONTROL_PING, mp_ping);
8635       S (mp_ping);
8636
8637       timeout = vat_time_now (vam) + 1.0;
8638       while (vat_time_now (vam) < timeout)
8639         if (vam->result_ready == 1)
8640           goto out;
8641       vam->retval = -99;
8642
8643     out:
8644       if (vam->retval == -99)
8645         errmsg ("timeout");
8646
8647       if (vam->async_errors > 0)
8648         {
8649           errmsg ("%d asynchronous errors", vam->async_errors);
8650           vam->retval = -98;
8651         }
8652       vam->async_errors = 0;
8653       after = vat_time_now (vam);
8654
8655       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8656       if (j > 0)
8657         count = j;
8658
8659       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8660              count, after - before, count / (after - before));
8661     }
8662   else
8663     {
8664       int ret;
8665
8666       /* Wait for a reply... */
8667       W (ret);
8668       return ret;
8669     }
8670
8671   /* Return the good/bad news */
8672   return (vam->retval);
8673 }
8674
8675 static int
8676 api_mpls_ip_bind_unbind (vat_main_t * vam)
8677 {
8678   unformat_input_t *i = vam->input;
8679   vl_api_mpls_ip_bind_unbind_t *mp;
8680   u32 ip_table_id = 0;
8681   u8 create_table_if_needed = 0;
8682   u8 is_bind = 1;
8683   u8 is_ip4 = 1;
8684   ip4_address_t v4_address;
8685   ip6_address_t v6_address;
8686   u32 address_length;
8687   u8 address_set = 0;
8688   mpls_label_t local_label = MPLS_LABEL_INVALID;
8689   int ret;
8690
8691   /* Parse args required to build the message */
8692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8693     {
8694       if (unformat (i, "%U/%d", unformat_ip4_address,
8695                     &v4_address, &address_length))
8696         {
8697           is_ip4 = 1;
8698           address_set = 1;
8699         }
8700       else if (unformat (i, "%U/%d", unformat_ip6_address,
8701                          &v6_address, &address_length))
8702         {
8703           is_ip4 = 0;
8704           address_set = 1;
8705         }
8706       else if (unformat (i, "%d", &local_label))
8707         ;
8708       else if (unformat (i, "create-table"))
8709         create_table_if_needed = 1;
8710       else if (unformat (i, "table-id %d", &ip_table_id))
8711         ;
8712       else if (unformat (i, "unbind"))
8713         is_bind = 0;
8714       else if (unformat (i, "bind"))
8715         is_bind = 1;
8716       else
8717         {
8718           clib_warning ("parse error '%U'", format_unformat_error, i);
8719           return -99;
8720         }
8721     }
8722
8723   if (!address_set)
8724     {
8725       errmsg ("IP addres not set");
8726       return -99;
8727     }
8728
8729   if (MPLS_LABEL_INVALID == local_label)
8730     {
8731       errmsg ("missing label");
8732       return -99;
8733     }
8734
8735   /* Construct the API message */
8736   M (MPLS_IP_BIND_UNBIND, mp);
8737
8738   mp->mb_create_table_if_needed = create_table_if_needed;
8739   mp->mb_is_bind = is_bind;
8740   mp->mb_is_ip4 = is_ip4;
8741   mp->mb_ip_table_id = ntohl (ip_table_id);
8742   mp->mb_mpls_table_id = 0;
8743   mp->mb_label = ntohl (local_label);
8744   mp->mb_address_length = address_length;
8745
8746   if (is_ip4)
8747     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8748   else
8749     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8750
8751   /* send it... */
8752   S (mp);
8753
8754   /* Wait for a reply... */
8755   W (ret);
8756   return ret;
8757 }
8758
8759 static int
8760 api_bier_table_add_del (vat_main_t * vam)
8761 {
8762   unformat_input_t *i = vam->input;
8763   vl_api_bier_table_add_del_t *mp;
8764   u8 is_add = 1;
8765   u32 set = 0, sub_domain = 0, hdr_len = 3;
8766   mpls_label_t local_label = MPLS_LABEL_INVALID;
8767   int ret;
8768
8769   /* Parse args required to build the message */
8770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8771     {
8772       if (unformat (i, "sub-domain %d", &sub_domain))
8773         ;
8774       else if (unformat (i, "set %d", &set))
8775         ;
8776       else if (unformat (i, "label %d", &local_label))
8777         ;
8778       else if (unformat (i, "hdr-len %d", &hdr_len))
8779         ;
8780       else if (unformat (i, "add"))
8781         is_add = 1;
8782       else if (unformat (i, "del"))
8783         is_add = 0;
8784       else
8785         {
8786           clib_warning ("parse error '%U'", format_unformat_error, i);
8787           return -99;
8788         }
8789     }
8790
8791   if (MPLS_LABEL_INVALID == local_label)
8792     {
8793       errmsg ("missing label\n");
8794       return -99;
8795     }
8796
8797   /* Construct the API message */
8798   M (BIER_TABLE_ADD_DEL, mp);
8799
8800   mp->bt_is_add = is_add;
8801   mp->bt_label = ntohl (local_label);
8802   mp->bt_tbl_id.bt_set = set;
8803   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8804   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8805
8806   /* send it... */
8807   S (mp);
8808
8809   /* Wait for a reply... */
8810   W (ret);
8811
8812   return (ret);
8813 }
8814
8815 static int
8816 api_bier_route_add_del (vat_main_t * vam)
8817 {
8818   unformat_input_t *i = vam->input;
8819   vl_api_bier_route_add_del_t *mp;
8820   u8 is_add = 1;
8821   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8822   ip4_address_t v4_next_hop_address;
8823   ip6_address_t v6_next_hop_address;
8824   u8 next_hop_set = 0;
8825   u8 next_hop_proto_is_ip4 = 1;
8826   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8827   int ret;
8828
8829   /* Parse args required to build the message */
8830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8833         {
8834           next_hop_proto_is_ip4 = 1;
8835           next_hop_set = 1;
8836         }
8837       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8838         {
8839           next_hop_proto_is_ip4 = 0;
8840           next_hop_set = 1;
8841         }
8842       if (unformat (i, "sub-domain %d", &sub_domain))
8843         ;
8844       else if (unformat (i, "set %d", &set))
8845         ;
8846       else if (unformat (i, "hdr-len %d", &hdr_len))
8847         ;
8848       else if (unformat (i, "bp %d", &bp))
8849         ;
8850       else if (unformat (i, "add"))
8851         is_add = 1;
8852       else if (unformat (i, "del"))
8853         is_add = 0;
8854       else if (unformat (i, "out-label %d", &next_hop_out_label))
8855         ;
8856       else
8857         {
8858           clib_warning ("parse error '%U'", format_unformat_error, i);
8859           return -99;
8860         }
8861     }
8862
8863   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8864     {
8865       errmsg ("next hop / label set\n");
8866       return -99;
8867     }
8868   if (0 == bp)
8869     {
8870       errmsg ("bit=position not set\n");
8871       return -99;
8872     }
8873
8874   /* Construct the API message */
8875   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8876
8877   mp->br_is_add = is_add;
8878   mp->br_tbl_id.bt_set = set;
8879   mp->br_tbl_id.bt_sub_domain = sub_domain;
8880   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8881   mp->br_bp = ntohs (bp);
8882   mp->br_n_paths = 1;
8883   mp->br_paths[0].n_labels = 1;
8884   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8885   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8886
8887   if (next_hop_proto_is_ip4)
8888     {
8889       clib_memcpy (mp->br_paths[0].next_hop,
8890                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8891     }
8892   else
8893     {
8894       clib_memcpy (mp->br_paths[0].next_hop,
8895                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8896     }
8897
8898   /* send it... */
8899   S (mp);
8900
8901   /* Wait for a reply... */
8902   W (ret);
8903
8904   return (ret);
8905 }
8906
8907 static int
8908 api_proxy_arp_add_del (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_proxy_arp_add_del_t *mp;
8912   u32 vrf_id = 0;
8913   u8 is_add = 1;
8914   ip4_address_t lo, hi;
8915   u8 range_set = 0;
8916   int ret;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "vrf %d", &vrf_id))
8921         ;
8922       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8923                          unformat_ip4_address, &hi))
8924         range_set = 1;
8925       else if (unformat (i, "del"))
8926         is_add = 0;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (range_set == 0)
8935     {
8936       errmsg ("address range not set");
8937       return -99;
8938     }
8939
8940   M (PROXY_ARP_ADD_DEL, mp);
8941
8942   mp->vrf_id = ntohl (vrf_id);
8943   mp->is_add = is_add;
8944   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8945   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8946
8947   S (mp);
8948   W (ret);
8949   return ret;
8950 }
8951
8952 static int
8953 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8957   u32 sw_if_index;
8958   u8 enable = 1;
8959   u8 sw_if_index_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "enable"))
8969         enable = 1;
8970       else if (unformat (i, "disable"))
8971         enable = 0;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index_set == 0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984
8985   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->enable_disable = enable;
8989
8990   S (mp);
8991   W (ret);
8992   return ret;
8993 }
8994
8995 static int
8996 api_mpls_tunnel_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_mpls_tunnel_add_del_t *mp;
9000
9001   u8 is_add = 1;
9002   u8 l2_only = 0;
9003   u32 sw_if_index = ~0;
9004   u32 next_hop_sw_if_index = ~0;
9005   u32 next_hop_proto_is_ip4 = 1;
9006
9007   u32 next_hop_table_id = 0;
9008   ip4_address_t v4_next_hop_address = {
9009     .as_u32 = 0,
9010   };
9011   ip6_address_t v6_next_hop_address = { {0} };
9012   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9013   int ret;
9014
9015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9016     {
9017       if (unformat (i, "add"))
9018         is_add = 1;
9019       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9020         is_add = 0;
9021       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9022         ;
9023       else if (unformat (i, "via %U",
9024                          unformat_ip4_address, &v4_next_hop_address))
9025         {
9026           next_hop_proto_is_ip4 = 1;
9027         }
9028       else if (unformat (i, "via %U",
9029                          unformat_ip6_address, &v6_next_hop_address))
9030         {
9031           next_hop_proto_is_ip4 = 0;
9032         }
9033       else if (unformat (i, "l2-only"))
9034         l2_only = 1;
9035       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9036         ;
9037       else if (unformat (i, "out-label %d", &next_hop_out_label))
9038         vec_add1 (labels, ntohl (next_hop_out_label));
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9047
9048   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9049   mp->mt_sw_if_index = ntohl (sw_if_index);
9050   mp->mt_is_add = is_add;
9051   mp->mt_l2_only = l2_only;
9052   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9053   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9054
9055   mp->mt_next_hop_n_out_labels = vec_len (labels);
9056
9057   if (0 != mp->mt_next_hop_n_out_labels)
9058     {
9059       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9060                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9061       vec_free (labels);
9062     }
9063
9064   if (next_hop_proto_is_ip4)
9065     {
9066       clib_memcpy (mp->mt_next_hop,
9067                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9068     }
9069   else
9070     {
9071       clib_memcpy (mp->mt_next_hop,
9072                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9073     }
9074
9075   S (mp);
9076   W (ret);
9077   return ret;
9078 }
9079
9080 static int
9081 api_sw_interface_set_unnumbered (vat_main_t * vam)
9082 {
9083   unformat_input_t *i = vam->input;
9084   vl_api_sw_interface_set_unnumbered_t *mp;
9085   u32 sw_if_index;
9086   u32 unnum_sw_index = ~0;
9087   u8 is_add = 1;
9088   u8 sw_if_index_set = 0;
9089   int ret;
9090
9091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9094         sw_if_index_set = 1;
9095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9098         ;
9099       else if (unformat (i, "del"))
9100         is_add = 0;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (sw_if_index_set == 0)
9109     {
9110       errmsg ("missing interface name or sw_if_index");
9111       return -99;
9112     }
9113
9114   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9115
9116   mp->sw_if_index = ntohl (sw_if_index);
9117   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9118   mp->is_add = is_add;
9119
9120   S (mp);
9121   W (ret);
9122   return ret;
9123 }
9124
9125 static int
9126 api_ip_neighbor_add_del (vat_main_t * vam)
9127 {
9128   unformat_input_t *i = vam->input;
9129   vl_api_ip_neighbor_add_del_t *mp;
9130   u32 sw_if_index;
9131   u8 sw_if_index_set = 0;
9132   u8 is_add = 1;
9133   u8 is_static = 0;
9134   u8 is_no_fib_entry = 0;
9135   u8 mac_address[6];
9136   u8 mac_set = 0;
9137   u8 v4_address_set = 0;
9138   u8 v6_address_set = 0;
9139   ip4_address_t v4address;
9140   ip6_address_t v6address;
9141   int ret;
9142
9143   memset (mac_address, 0, sizeof (mac_address));
9144
9145   /* Parse args required to build the message */
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9149         {
9150           mac_set = 1;
9151         }
9152       else if (unformat (i, "del"))
9153         is_add = 0;
9154       else
9155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "is_static"))
9160         is_static = 1;
9161       else if (unformat (i, "no-fib-entry"))
9162         is_no_fib_entry = 1;
9163       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9164         v4_address_set = 1;
9165       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9166         v6_address_set = 1;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179   if (v4_address_set && v6_address_set)
9180     {
9181       errmsg ("both v4 and v6 addresses set");
9182       return -99;
9183     }
9184   if (!v4_address_set && !v6_address_set)
9185     {
9186       errmsg ("no address set");
9187       return -99;
9188     }
9189
9190   /* Construct the API message */
9191   M (IP_NEIGHBOR_ADD_DEL, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->is_add = is_add;
9195   mp->is_static = is_static;
9196   mp->is_no_adj_fib = is_no_fib_entry;
9197   if (mac_set)
9198     clib_memcpy (mp->mac_address, mac_address, 6);
9199   if (v6_address_set)
9200     {
9201       mp->is_ipv6 = 1;
9202       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9203     }
9204   else
9205     {
9206       /* mp->is_ipv6 = 0; via memset in M macro above */
9207       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9208     }
9209
9210   /* send it... */
9211   S (mp);
9212
9213   /* Wait for a reply, return good/bad news  */
9214   W (ret);
9215   return ret;
9216 }
9217
9218 static int
9219 api_create_vlan_subif (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_create_vlan_subif_t *mp;
9223   u32 sw_if_index;
9224   u8 sw_if_index_set = 0;
9225   u32 vlan_id;
9226   u8 vlan_id_set = 0;
9227   int ret;
9228
9229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9230     {
9231       if (unformat (i, "sw_if_index %d", &sw_if_index))
9232         sw_if_index_set = 1;
9233       else
9234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9235         sw_if_index_set = 1;
9236       else if (unformat (i, "vlan %d", &vlan_id))
9237         vlan_id_set = 1;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (sw_if_index_set == 0)
9246     {
9247       errmsg ("missing interface name or sw_if_index");
9248       return -99;
9249     }
9250
9251   if (vlan_id_set == 0)
9252     {
9253       errmsg ("missing vlan_id");
9254       return -99;
9255     }
9256   M (CREATE_VLAN_SUBIF, mp);
9257
9258   mp->sw_if_index = ntohl (sw_if_index);
9259   mp->vlan_id = ntohl (vlan_id);
9260
9261   S (mp);
9262   W (ret);
9263   return ret;
9264 }
9265
9266 #define foreach_create_subif_bit                \
9267 _(no_tags)                                      \
9268 _(one_tag)                                      \
9269 _(two_tags)                                     \
9270 _(dot1ad)                                       \
9271 _(exact_match)                                  \
9272 _(default_sub)                                  \
9273 _(outer_vlan_id_any)                            \
9274 _(inner_vlan_id_any)
9275
9276 static int
9277 api_create_subif (vat_main_t * vam)
9278 {
9279   unformat_input_t *i = vam->input;
9280   vl_api_create_subif_t *mp;
9281   u32 sw_if_index;
9282   u8 sw_if_index_set = 0;
9283   u32 sub_id;
9284   u8 sub_id_set = 0;
9285   u32 no_tags = 0;
9286   u32 one_tag = 0;
9287   u32 two_tags = 0;
9288   u32 dot1ad = 0;
9289   u32 exact_match = 0;
9290   u32 default_sub = 0;
9291   u32 outer_vlan_id_any = 0;
9292   u32 inner_vlan_id_any = 0;
9293   u32 tmp;
9294   u16 outer_vlan_id = 0;
9295   u16 inner_vlan_id = 0;
9296   int ret;
9297
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "sw_if_index %d", &sw_if_index))
9301         sw_if_index_set = 1;
9302       else
9303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "sub_id %d", &sub_id))
9306         sub_id_set = 1;
9307       else if (unformat (i, "outer_vlan_id %d", &tmp))
9308         outer_vlan_id = tmp;
9309       else if (unformat (i, "inner_vlan_id %d", &tmp))
9310         inner_vlan_id = tmp;
9311
9312 #define _(a) else if (unformat (i, #a)) a = 1 ;
9313       foreach_create_subif_bit
9314 #undef _
9315         else
9316         {
9317           clib_warning ("parse error '%U'", format_unformat_error, i);
9318           return -99;
9319         }
9320     }
9321
9322   if (sw_if_index_set == 0)
9323     {
9324       errmsg ("missing interface name or sw_if_index");
9325       return -99;
9326     }
9327
9328   if (sub_id_set == 0)
9329     {
9330       errmsg ("missing sub_id");
9331       return -99;
9332     }
9333   M (CREATE_SUBIF, mp);
9334
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->sub_id = ntohl (sub_id);
9337
9338 #define _(a) mp->a = a;
9339   foreach_create_subif_bit;
9340 #undef _
9341
9342   mp->outer_vlan_id = ntohs (outer_vlan_id);
9343   mp->inner_vlan_id = ntohs (inner_vlan_id);
9344
9345   S (mp);
9346   W (ret);
9347   return ret;
9348 }
9349
9350 static int
9351 api_oam_add_del (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_oam_add_del_t *mp;
9355   u32 vrf_id = 0;
9356   u8 is_add = 1;
9357   ip4_address_t src, dst;
9358   u8 src_set = 0;
9359   u8 dst_set = 0;
9360   int ret;
9361
9362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (i, "vrf %d", &vrf_id))
9365         ;
9366       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9367         src_set = 1;
9368       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9369         dst_set = 1;
9370       else if (unformat (i, "del"))
9371         is_add = 0;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (src_set == 0)
9380     {
9381       errmsg ("missing src addr");
9382       return -99;
9383     }
9384
9385   if (dst_set == 0)
9386     {
9387       errmsg ("missing dst addr");
9388       return -99;
9389     }
9390
9391   M (OAM_ADD_DEL, mp);
9392
9393   mp->vrf_id = ntohl (vrf_id);
9394   mp->is_add = is_add;
9395   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9396   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_reset_fib (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_reset_fib_t *mp;
9408   u32 vrf_id = 0;
9409   u8 is_ipv6 = 0;
9410   u8 vrf_id_set = 0;
9411
9412   int ret;
9413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (i, "vrf %d", &vrf_id))
9416         vrf_id_set = 1;
9417       else if (unformat (i, "ipv6"))
9418         is_ipv6 = 1;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (vrf_id_set == 0)
9427     {
9428       errmsg ("missing vrf id");
9429       return -99;
9430     }
9431
9432   M (RESET_FIB, mp);
9433
9434   mp->vrf_id = ntohl (vrf_id);
9435   mp->is_ipv6 = is_ipv6;
9436
9437   S (mp);
9438   W (ret);
9439   return ret;
9440 }
9441
9442 static int
9443 api_dhcp_proxy_config (vat_main_t * vam)
9444 {
9445   unformat_input_t *i = vam->input;
9446   vl_api_dhcp_proxy_config_t *mp;
9447   u32 rx_vrf_id = 0;
9448   u32 server_vrf_id = 0;
9449   u8 is_add = 1;
9450   u8 v4_address_set = 0;
9451   u8 v6_address_set = 0;
9452   ip4_address_t v4address;
9453   ip6_address_t v6address;
9454   u8 v4_src_address_set = 0;
9455   u8 v6_src_address_set = 0;
9456   ip4_address_t v4srcaddress;
9457   ip6_address_t v6srcaddress;
9458   int ret;
9459
9460   /* Parse args required to build the message */
9461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (i, "del"))
9464         is_add = 0;
9465       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9466         ;
9467       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9468         ;
9469       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9470         v4_address_set = 1;
9471       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9472         v6_address_set = 1;
9473       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9474         v4_src_address_set = 1;
9475       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9476         v6_src_address_set = 1;
9477       else
9478         break;
9479     }
9480
9481   if (v4_address_set && v6_address_set)
9482     {
9483       errmsg ("both v4 and v6 server addresses set");
9484       return -99;
9485     }
9486   if (!v4_address_set && !v6_address_set)
9487     {
9488       errmsg ("no server addresses set");
9489       return -99;
9490     }
9491
9492   if (v4_src_address_set && v6_src_address_set)
9493     {
9494       errmsg ("both v4 and v6  src addresses set");
9495       return -99;
9496     }
9497   if (!v4_src_address_set && !v6_src_address_set)
9498     {
9499       errmsg ("no src addresses set");
9500       return -99;
9501     }
9502
9503   if (!(v4_src_address_set && v4_address_set) &&
9504       !(v6_src_address_set && v6_address_set))
9505     {
9506       errmsg ("no matching server and src addresses set");
9507       return -99;
9508     }
9509
9510   /* Construct the API message */
9511   M (DHCP_PROXY_CONFIG, mp);
9512
9513   mp->is_add = is_add;
9514   mp->rx_vrf_id = ntohl (rx_vrf_id);
9515   mp->server_vrf_id = ntohl (server_vrf_id);
9516   if (v6_address_set)
9517     {
9518       mp->is_ipv6 = 1;
9519       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9520       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9521     }
9522   else
9523     {
9524       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9525       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9526     }
9527
9528   /* send it... */
9529   S (mp);
9530
9531   /* Wait for a reply, return good/bad news  */
9532   W (ret);
9533   return ret;
9534 }
9535
9536 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9537 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9538
9539 static void
9540 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9541 {
9542   vat_main_t *vam = &vat_main;
9543   u32 i, count = mp->count;
9544   vl_api_dhcp_server_t *s;
9545
9546   if (mp->is_ipv6)
9547     print (vam->ofp,
9548            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9549            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9550            ntohl (mp->rx_vrf_id),
9551            format_ip6_address, mp->dhcp_src_address,
9552            mp->vss_type, mp->vss_vpn_ascii_id,
9553            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9554   else
9555     print (vam->ofp,
9556            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9557            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9558            ntohl (mp->rx_vrf_id),
9559            format_ip4_address, mp->dhcp_src_address,
9560            mp->vss_type, mp->vss_vpn_ascii_id,
9561            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9562
9563   for (i = 0; i < count; i++)
9564     {
9565       s = &mp->servers[i];
9566
9567       if (mp->is_ipv6)
9568         print (vam->ofp,
9569                " Server Table-ID %d, Server Address %U",
9570                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9571       else
9572         print (vam->ofp,
9573                " Server Table-ID %d, Server Address %U",
9574                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9575     }
9576 }
9577
9578 static void vl_api_dhcp_proxy_details_t_handler_json
9579   (vl_api_dhcp_proxy_details_t * mp)
9580 {
9581   vat_main_t *vam = &vat_main;
9582   vat_json_node_t *node = NULL;
9583   u32 i, count = mp->count;
9584   struct in_addr ip4;
9585   struct in6_addr ip6;
9586   vl_api_dhcp_server_t *s;
9587
9588   if (VAT_JSON_ARRAY != vam->json_tree.type)
9589     {
9590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9591       vat_json_init_array (&vam->json_tree);
9592     }
9593   node = vat_json_array_add (&vam->json_tree);
9594
9595   vat_json_init_object (node);
9596   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9597   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9598                              sizeof (mp->vss_type));
9599   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9600                                    mp->vss_vpn_ascii_id);
9601   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9602   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9603
9604   if (mp->is_ipv6)
9605     {
9606       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9607       vat_json_object_add_ip6 (node, "src_address", ip6);
9608     }
9609   else
9610     {
9611       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9612       vat_json_object_add_ip4 (node, "src_address", ip4);
9613     }
9614
9615   for (i = 0; i < count; i++)
9616     {
9617       s = &mp->servers[i];
9618
9619       vat_json_object_add_uint (node, "server-table-id",
9620                                 ntohl (s->server_vrf_id));
9621
9622       if (mp->is_ipv6)
9623         {
9624           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9625           vat_json_object_add_ip4 (node, "src_address", ip4);
9626         }
9627       else
9628         {
9629           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9630           vat_json_object_add_ip6 (node, "server_address", ip6);
9631         }
9632     }
9633 }
9634
9635 static int
9636 api_dhcp_proxy_dump (vat_main_t * vam)
9637 {
9638   unformat_input_t *i = vam->input;
9639   vl_api_control_ping_t *mp_ping;
9640   vl_api_dhcp_proxy_dump_t *mp;
9641   u8 is_ipv6 = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "ipv6"))
9647         is_ipv6 = 1;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   M (DHCP_PROXY_DUMP, mp);
9656
9657   mp->is_ip6 = is_ipv6;
9658   S (mp);
9659
9660   /* Use a control ping for synchronization */
9661   MPING (CONTROL_PING, mp_ping);
9662   S (mp_ping);
9663
9664   W (ret);
9665   return ret;
9666 }
9667
9668 static int
9669 api_dhcp_proxy_set_vss (vat_main_t * vam)
9670 {
9671   unformat_input_t *i = vam->input;
9672   vl_api_dhcp_proxy_set_vss_t *mp;
9673   u8 is_ipv6 = 0;
9674   u8 is_add = 1;
9675   u32 tbl_id = ~0;
9676   u8 vss_type = VSS_TYPE_DEFAULT;
9677   u8 *vpn_ascii_id = 0;
9678   u32 oui = 0;
9679   u32 fib_id = 0;
9680   int ret;
9681
9682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (i, "tbl_id %d", &tbl_id))
9685         ;
9686       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9687         vss_type = VSS_TYPE_ASCII;
9688       else if (unformat (i, "fib_id %d", &fib_id))
9689         vss_type = VSS_TYPE_VPN_ID;
9690       else if (unformat (i, "oui %d", &oui))
9691         vss_type = VSS_TYPE_VPN_ID;
9692       else if (unformat (i, "ipv6"))
9693         is_ipv6 = 1;
9694       else if (unformat (i, "del"))
9695         is_add = 0;
9696       else
9697         break;
9698     }
9699
9700   if (tbl_id == ~0)
9701     {
9702       errmsg ("missing tbl_id ");
9703       vec_free (vpn_ascii_id);
9704       return -99;
9705     }
9706
9707   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9708     {
9709       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9710       vec_free (vpn_ascii_id);
9711       return -99;
9712     }
9713
9714   M (DHCP_PROXY_SET_VSS, mp);
9715   mp->tbl_id = ntohl (tbl_id);
9716   mp->vss_type = vss_type;
9717   if (vpn_ascii_id)
9718     {
9719       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9720       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9721     }
9722   mp->vpn_index = ntohl (fib_id);
9723   mp->oui = ntohl (oui);
9724   mp->is_ipv6 = is_ipv6;
9725   mp->is_add = is_add;
9726
9727   S (mp);
9728   W (ret);
9729
9730   vec_free (vpn_ascii_id);
9731   return ret;
9732 }
9733
9734 static int
9735 api_dhcp_client_config (vat_main_t * vam)
9736 {
9737   unformat_input_t *i = vam->input;
9738   vl_api_dhcp_client_config_t *mp;
9739   u32 sw_if_index;
9740   u8 sw_if_index_set = 0;
9741   u8 is_add = 1;
9742   u8 *hostname = 0;
9743   u8 disable_event = 0;
9744   int ret;
9745
9746   /* Parse args required to build the message */
9747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (i, "del"))
9750         is_add = 0;
9751       else
9752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9753         sw_if_index_set = 1;
9754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9755         sw_if_index_set = 1;
9756       else if (unformat (i, "hostname %s", &hostname))
9757         ;
9758       else if (unformat (i, "disable_event"))
9759         disable_event = 1;
9760       else
9761         break;
9762     }
9763
9764   if (sw_if_index_set == 0)
9765     {
9766       errmsg ("missing interface name or sw_if_index");
9767       return -99;
9768     }
9769
9770   if (vec_len (hostname) > 63)
9771     {
9772       errmsg ("hostname too long");
9773     }
9774   vec_add1 (hostname, 0);
9775
9776   /* Construct the API message */
9777   M (DHCP_CLIENT_CONFIG, mp);
9778
9779   mp->sw_if_index = htonl (sw_if_index);
9780   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9781   vec_free (hostname);
9782   mp->is_add = is_add;
9783   mp->want_dhcp_event = disable_event ? 0 : 1;
9784   mp->pid = htonl (getpid ());
9785
9786   /* send it... */
9787   S (mp);
9788
9789   /* Wait for a reply, return good/bad news  */
9790   W (ret);
9791   return ret;
9792 }
9793
9794 static int
9795 api_set_ip_flow_hash (vat_main_t * vam)
9796 {
9797   unformat_input_t *i = vam->input;
9798   vl_api_set_ip_flow_hash_t *mp;
9799   u32 vrf_id = 0;
9800   u8 is_ipv6 = 0;
9801   u8 vrf_id_set = 0;
9802   u8 src = 0;
9803   u8 dst = 0;
9804   u8 sport = 0;
9805   u8 dport = 0;
9806   u8 proto = 0;
9807   u8 reverse = 0;
9808   int ret;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "vrf %d", &vrf_id))
9813         vrf_id_set = 1;
9814       else if (unformat (i, "ipv6"))
9815         is_ipv6 = 1;
9816       else if (unformat (i, "src"))
9817         src = 1;
9818       else if (unformat (i, "dst"))
9819         dst = 1;
9820       else if (unformat (i, "sport"))
9821         sport = 1;
9822       else if (unformat (i, "dport"))
9823         dport = 1;
9824       else if (unformat (i, "proto"))
9825         proto = 1;
9826       else if (unformat (i, "reverse"))
9827         reverse = 1;
9828
9829       else
9830         {
9831           clib_warning ("parse error '%U'", format_unformat_error, i);
9832           return -99;
9833         }
9834     }
9835
9836   if (vrf_id_set == 0)
9837     {
9838       errmsg ("missing vrf id");
9839       return -99;
9840     }
9841
9842   M (SET_IP_FLOW_HASH, mp);
9843   mp->src = src;
9844   mp->dst = dst;
9845   mp->sport = sport;
9846   mp->dport = dport;
9847   mp->proto = proto;
9848   mp->reverse = reverse;
9849   mp->vrf_id = ntohl (vrf_id);
9850   mp->is_ipv6 = is_ipv6;
9851
9852   S (mp);
9853   W (ret);
9854   return ret;
9855 }
9856
9857 static int
9858 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_sw_interface_ip6_enable_disable_t *mp;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable = 0;
9865   int ret;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable = 1;
9875       else if (unformat (i, "disable"))
9876         enable = 0;
9877       else
9878         {
9879           clib_warning ("parse error '%U'", format_unformat_error, i);
9880           return -99;
9881         }
9882     }
9883
9884   if (sw_if_index_set == 0)
9885     {
9886       errmsg ("missing interface name or sw_if_index");
9887       return -99;
9888     }
9889
9890   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9891
9892   mp->sw_if_index = ntohl (sw_if_index);
9893   mp->enable = enable;
9894
9895   S (mp);
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u8 v6_address_set = 0;
9908   ip6_address_t v6address;
9909   int ret;
9910
9911   /* Parse args required to build the message */
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9919         v6_address_set = 1;
9920       else
9921         break;
9922     }
9923
9924   if (sw_if_index_set == 0)
9925     {
9926       errmsg ("missing interface name or sw_if_index");
9927       return -99;
9928     }
9929   if (!v6_address_set)
9930     {
9931       errmsg ("no address set");
9932       return -99;
9933     }
9934
9935   /* Construct the API message */
9936   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9937
9938   mp->sw_if_index = ntohl (sw_if_index);
9939   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9940
9941   /* send it... */
9942   S (mp);
9943
9944   /* Wait for a reply, return good/bad news  */
9945   W (ret);
9946   return ret;
9947 }
9948
9949 static int
9950 api_ip6nd_proxy_add_del (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_ip6nd_proxy_add_del_t *mp;
9954   u32 sw_if_index = ~0;
9955   u8 v6_address_set = 0;
9956   ip6_address_t v6address;
9957   u8 is_del = 0;
9958   int ret;
9959
9960   /* Parse args required to build the message */
9961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9962     {
9963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9964         ;
9965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9966         ;
9967       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9968         v6_address_set = 1;
9969       if (unformat (i, "del"))
9970         is_del = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index == ~0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983   if (!v6_address_set)
9984     {
9985       errmsg ("no address set");
9986       return -99;
9987     }
9988
9989   /* Construct the API message */
9990   M (IP6ND_PROXY_ADD_DEL, mp);
9991
9992   mp->is_del = is_del;
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9995
9996   /* send it... */
9997   S (mp);
9998
9999   /* Wait for a reply, return good/bad news  */
10000   W (ret);
10001   return ret;
10002 }
10003
10004 static int
10005 api_ip6nd_proxy_dump (vat_main_t * vam)
10006 {
10007   vl_api_ip6nd_proxy_dump_t *mp;
10008   vl_api_control_ping_t *mp_ping;
10009   int ret;
10010
10011   M (IP6ND_PROXY_DUMP, mp);
10012
10013   S (mp);
10014
10015   /* Use a control ping for synchronization */
10016   MPING (CONTROL_PING, mp_ping);
10017   S (mp_ping);
10018
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static void vl_api_ip6nd_proxy_details_t_handler
10024   (vl_api_ip6nd_proxy_details_t * mp)
10025 {
10026   vat_main_t *vam = &vat_main;
10027
10028   print (vam->ofp, "host %U sw_if_index %d",
10029          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10030 }
10031
10032 static void vl_api_ip6nd_proxy_details_t_handler_json
10033   (vl_api_ip6nd_proxy_details_t * mp)
10034 {
10035   vat_main_t *vam = &vat_main;
10036   struct in6_addr ip6;
10037   vat_json_node_t *node = NULL;
10038
10039   if (VAT_JSON_ARRAY != vam->json_tree.type)
10040     {
10041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10042       vat_json_init_array (&vam->json_tree);
10043     }
10044   node = vat_json_array_add (&vam->json_tree);
10045
10046   vat_json_init_object (node);
10047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10048
10049   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10050   vat_json_object_add_ip6 (node, "host", ip6);
10051 }
10052
10053 static int
10054 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10058   u32 sw_if_index;
10059   u8 sw_if_index_set = 0;
10060   u32 address_length = 0;
10061   u8 v6_address_set = 0;
10062   ip6_address_t v6address;
10063   u8 use_default = 0;
10064   u8 no_advertise = 0;
10065   u8 off_link = 0;
10066   u8 no_autoconfig = 0;
10067   u8 no_onlink = 0;
10068   u8 is_no = 0;
10069   u32 val_lifetime = 0;
10070   u32 pref_lifetime = 0;
10071   int ret;
10072
10073   /* Parse args required to build the message */
10074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10075     {
10076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10079         sw_if_index_set = 1;
10080       else if (unformat (i, "%U/%d",
10081                          unformat_ip6_address, &v6address, &address_length))
10082         v6_address_set = 1;
10083       else if (unformat (i, "val_life %d", &val_lifetime))
10084         ;
10085       else if (unformat (i, "pref_life %d", &pref_lifetime))
10086         ;
10087       else if (unformat (i, "def"))
10088         use_default = 1;
10089       else if (unformat (i, "noadv"))
10090         no_advertise = 1;
10091       else if (unformat (i, "offl"))
10092         off_link = 1;
10093       else if (unformat (i, "noauto"))
10094         no_autoconfig = 1;
10095       else if (unformat (i, "nolink"))
10096         no_onlink = 1;
10097       else if (unformat (i, "isno"))
10098         is_no = 1;
10099       else
10100         {
10101           clib_warning ("parse error '%U'", format_unformat_error, i);
10102           return -99;
10103         }
10104     }
10105
10106   if (sw_if_index_set == 0)
10107     {
10108       errmsg ("missing interface name or sw_if_index");
10109       return -99;
10110     }
10111   if (!v6_address_set)
10112     {
10113       errmsg ("no address set");
10114       return -99;
10115     }
10116
10117   /* Construct the API message */
10118   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10122   mp->address_length = address_length;
10123   mp->use_default = use_default;
10124   mp->no_advertise = no_advertise;
10125   mp->off_link = off_link;
10126   mp->no_autoconfig = no_autoconfig;
10127   mp->no_onlink = no_onlink;
10128   mp->is_no = is_no;
10129   mp->val_lifetime = ntohl (val_lifetime);
10130   mp->pref_lifetime = ntohl (pref_lifetime);
10131
10132   /* send it... */
10133   S (mp);
10134
10135   /* Wait for a reply, return good/bad news  */
10136   W (ret);
10137   return ret;
10138 }
10139
10140 static int
10141 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10145   u32 sw_if_index;
10146   u8 sw_if_index_set = 0;
10147   u8 suppress = 0;
10148   u8 managed = 0;
10149   u8 other = 0;
10150   u8 ll_option = 0;
10151   u8 send_unicast = 0;
10152   u8 cease = 0;
10153   u8 is_no = 0;
10154   u8 default_router = 0;
10155   u32 max_interval = 0;
10156   u32 min_interval = 0;
10157   u32 lifetime = 0;
10158   u32 initial_count = 0;
10159   u32 initial_interval = 0;
10160   int ret;
10161
10162
10163   /* Parse args required to build the message */
10164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169         sw_if_index_set = 1;
10170       else if (unformat (i, "maxint %d", &max_interval))
10171         ;
10172       else if (unformat (i, "minint %d", &min_interval))
10173         ;
10174       else if (unformat (i, "life %d", &lifetime))
10175         ;
10176       else if (unformat (i, "count %d", &initial_count))
10177         ;
10178       else if (unformat (i, "interval %d", &initial_interval))
10179         ;
10180       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10181         suppress = 1;
10182       else if (unformat (i, "managed"))
10183         managed = 1;
10184       else if (unformat (i, "other"))
10185         other = 1;
10186       else if (unformat (i, "ll"))
10187         ll_option = 1;
10188       else if (unformat (i, "send"))
10189         send_unicast = 1;
10190       else if (unformat (i, "cease"))
10191         cease = 1;
10192       else if (unformat (i, "isno"))
10193         is_no = 1;
10194       else if (unformat (i, "def"))
10195         default_router = 1;
10196       else
10197         {
10198           clib_warning ("parse error '%U'", format_unformat_error, i);
10199           return -99;
10200         }
10201     }
10202
10203   if (sw_if_index_set == 0)
10204     {
10205       errmsg ("missing interface name or sw_if_index");
10206       return -99;
10207     }
10208
10209   /* Construct the API message */
10210   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10211
10212   mp->sw_if_index = ntohl (sw_if_index);
10213   mp->max_interval = ntohl (max_interval);
10214   mp->min_interval = ntohl (min_interval);
10215   mp->lifetime = ntohl (lifetime);
10216   mp->initial_count = ntohl (initial_count);
10217   mp->initial_interval = ntohl (initial_interval);
10218   mp->suppress = suppress;
10219   mp->managed = managed;
10220   mp->other = other;
10221   mp->ll_option = ll_option;
10222   mp->send_unicast = send_unicast;
10223   mp->cease = cease;
10224   mp->is_no = is_no;
10225   mp->default_router = default_router;
10226
10227   /* send it... */
10228   S (mp);
10229
10230   /* Wait for a reply, return good/bad news  */
10231   W (ret);
10232   return ret;
10233 }
10234
10235 static int
10236 api_set_arp_neighbor_limit (vat_main_t * vam)
10237 {
10238   unformat_input_t *i = vam->input;
10239   vl_api_set_arp_neighbor_limit_t *mp;
10240   u32 arp_nbr_limit;
10241   u8 limit_set = 0;
10242   u8 is_ipv6 = 0;
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10248         limit_set = 1;
10249       else if (unformat (i, "ipv6"))
10250         is_ipv6 = 1;
10251       else
10252         {
10253           clib_warning ("parse error '%U'", format_unformat_error, i);
10254           return -99;
10255         }
10256     }
10257
10258   if (limit_set == 0)
10259     {
10260       errmsg ("missing limit value");
10261       return -99;
10262     }
10263
10264   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10265
10266   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10267   mp->is_ipv6 = is_ipv6;
10268
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_l2_patch_add_del (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_l2_patch_add_del_t *mp;
10279   u32 rx_sw_if_index;
10280   u8 rx_sw_if_index_set = 0;
10281   u32 tx_sw_if_index;
10282   u8 tx_sw_if_index_set = 0;
10283   u8 is_add = 1;
10284   int ret;
10285
10286   /* Parse args required to build the message */
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10290         rx_sw_if_index_set = 1;
10291       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10292         tx_sw_if_index_set = 1;
10293       else if (unformat (i, "rx"))
10294         {
10295           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10296             {
10297               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10298                             &rx_sw_if_index))
10299                 rx_sw_if_index_set = 1;
10300             }
10301           else
10302             break;
10303         }
10304       else if (unformat (i, "tx"))
10305         {
10306           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307             {
10308               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10309                             &tx_sw_if_index))
10310                 tx_sw_if_index_set = 1;
10311             }
10312           else
10313             break;
10314         }
10315       else if (unformat (i, "del"))
10316         is_add = 0;
10317       else
10318         break;
10319     }
10320
10321   if (rx_sw_if_index_set == 0)
10322     {
10323       errmsg ("missing rx interface name or rx_sw_if_index");
10324       return -99;
10325     }
10326
10327   if (tx_sw_if_index_set == 0)
10328     {
10329       errmsg ("missing tx interface name or tx_sw_if_index");
10330       return -99;
10331     }
10332
10333   M (L2_PATCH_ADD_DEL, mp);
10334
10335   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10336   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10337   mp->is_add = is_add;
10338
10339   S (mp);
10340   W (ret);
10341   return ret;
10342 }
10343
10344 u8 is_del;
10345 u8 localsid_addr[16];
10346 u8 end_psp;
10347 u8 behavior;
10348 u32 sw_if_index;
10349 u32 vlan_index;
10350 u32 fib_table;
10351 u8 nh_addr[16];
10352
10353 static int
10354 api_sr_localsid_add_del (vat_main_t * vam)
10355 {
10356   unformat_input_t *i = vam->input;
10357   vl_api_sr_localsid_add_del_t *mp;
10358
10359   u8 is_del;
10360   ip6_address_t localsid;
10361   u8 end_psp = 0;
10362   u8 behavior = ~0;
10363   u32 sw_if_index;
10364   u32 fib_table = ~(u32) 0;
10365   ip6_address_t next_hop;
10366
10367   bool nexthop_set = 0;
10368
10369   int ret;
10370
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "del"))
10374         is_del = 1;
10375       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10376       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10377         nexthop_set = 1;
10378       else if (unformat (i, "behavior %u", &behavior));
10379       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10380       else if (unformat (i, "fib-table %u", &fib_table));
10381       else if (unformat (i, "end.psp %u", &behavior));
10382       else
10383         break;
10384     }
10385
10386   M (SR_LOCALSID_ADD_DEL, mp);
10387
10388   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10389   if (nexthop_set)
10390     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10391   mp->behavior = behavior;
10392   mp->sw_if_index = ntohl (sw_if_index);
10393   mp->fib_table = ntohl (fib_table);
10394   mp->end_psp = end_psp;
10395   mp->is_del = is_del;
10396
10397   S (mp);
10398   W (ret);
10399   return ret;
10400 }
10401
10402 static int
10403 api_ioam_enable (vat_main_t * vam)
10404 {
10405   unformat_input_t *input = vam->input;
10406   vl_api_ioam_enable_t *mp;
10407   u32 id = 0;
10408   int has_trace_option = 0;
10409   int has_pot_option = 0;
10410   int has_seqno_option = 0;
10411   int has_analyse_option = 0;
10412   int ret;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "trace"))
10417         has_trace_option = 1;
10418       else if (unformat (input, "pot"))
10419         has_pot_option = 1;
10420       else if (unformat (input, "seqno"))
10421         has_seqno_option = 1;
10422       else if (unformat (input, "analyse"))
10423         has_analyse_option = 1;
10424       else
10425         break;
10426     }
10427   M (IOAM_ENABLE, mp);
10428   mp->id = htons (id);
10429   mp->seqno = has_seqno_option;
10430   mp->analyse = has_analyse_option;
10431   mp->pot_enable = has_pot_option;
10432   mp->trace_enable = has_trace_option;
10433
10434   S (mp);
10435   W (ret);
10436   return ret;
10437 }
10438
10439
10440 static int
10441 api_ioam_disable (vat_main_t * vam)
10442 {
10443   vl_api_ioam_disable_t *mp;
10444   int ret;
10445
10446   M (IOAM_DISABLE, mp);
10447   S (mp);
10448   W (ret);
10449   return ret;
10450 }
10451
10452 #define foreach_tcp_proto_field                 \
10453 _(src_port)                                     \
10454 _(dst_port)
10455
10456 #define foreach_udp_proto_field                 \
10457 _(src_port)                                     \
10458 _(dst_port)
10459
10460 #define foreach_ip4_proto_field                 \
10461 _(src_address)                                  \
10462 _(dst_address)                                  \
10463 _(tos)                                          \
10464 _(length)                                       \
10465 _(fragment_id)                                  \
10466 _(ttl)                                          \
10467 _(protocol)                                     \
10468 _(checksum)
10469
10470 typedef struct
10471 {
10472   u16 src_port, dst_port;
10473 } tcpudp_header_t;
10474
10475 #if VPP_API_TEST_BUILTIN == 0
10476 uword
10477 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10478 {
10479   u8 **maskp = va_arg (*args, u8 **);
10480   u8 *mask = 0;
10481   u8 found_something = 0;
10482   tcp_header_t *tcp;
10483
10484 #define _(a) u8 a=0;
10485   foreach_tcp_proto_field;
10486 #undef _
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (0);
10491 #define _(a) else if (unformat (input, #a)) a=1;
10492       foreach_tcp_proto_field
10493 #undef _
10494         else
10495         break;
10496     }
10497
10498 #define _(a) found_something += a;
10499   foreach_tcp_proto_field;
10500 #undef _
10501
10502   if (found_something == 0)
10503     return 0;
10504
10505   vec_validate (mask, sizeof (*tcp) - 1);
10506
10507   tcp = (tcp_header_t *) mask;
10508
10509 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10510   foreach_tcp_proto_field;
10511 #undef _
10512
10513   *maskp = mask;
10514   return 1;
10515 }
10516
10517 uword
10518 unformat_udp_mask (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **maskp = va_arg (*args, u8 **);
10521   u8 *mask = 0;
10522   u8 found_something = 0;
10523   udp_header_t *udp;
10524
10525 #define _(a) u8 a=0;
10526   foreach_udp_proto_field;
10527 #undef _
10528
10529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10530     {
10531       if (0);
10532 #define _(a) else if (unformat (input, #a)) a=1;
10533       foreach_udp_proto_field
10534 #undef _
10535         else
10536         break;
10537     }
10538
10539 #define _(a) found_something += a;
10540   foreach_udp_proto_field;
10541 #undef _
10542
10543   if (found_something == 0)
10544     return 0;
10545
10546   vec_validate (mask, sizeof (*udp) - 1);
10547
10548   udp = (udp_header_t *) mask;
10549
10550 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10551   foreach_udp_proto_field;
10552 #undef _
10553
10554   *maskp = mask;
10555   return 1;
10556 }
10557
10558 uword
10559 unformat_l4_mask (unformat_input_t * input, va_list * args)
10560 {
10561   u8 **maskp = va_arg (*args, u8 **);
10562   u16 src_port = 0, dst_port = 0;
10563   tcpudp_header_t *tcpudp;
10564
10565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10568         return 1;
10569       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10570         return 1;
10571       else if (unformat (input, "src_port"))
10572         src_port = 0xFFFF;
10573       else if (unformat (input, "dst_port"))
10574         dst_port = 0xFFFF;
10575       else
10576         return 0;
10577     }
10578
10579   if (!src_port && !dst_port)
10580     return 0;
10581
10582   u8 *mask = 0;
10583   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10584
10585   tcpudp = (tcpudp_header_t *) mask;
10586   tcpudp->src_port = src_port;
10587   tcpudp->dst_port = dst_port;
10588
10589   *maskp = mask;
10590
10591   return 1;
10592 }
10593
10594 uword
10595 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10596 {
10597   u8 **maskp = va_arg (*args, u8 **);
10598   u8 *mask = 0;
10599   u8 found_something = 0;
10600   ip4_header_t *ip;
10601
10602 #define _(a) u8 a=0;
10603   foreach_ip4_proto_field;
10604 #undef _
10605   u8 version = 0;
10606   u8 hdr_length = 0;
10607
10608
10609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (input, "version"))
10612         version = 1;
10613       else if (unformat (input, "hdr_length"))
10614         hdr_length = 1;
10615       else if (unformat (input, "src"))
10616         src_address = 1;
10617       else if (unformat (input, "dst"))
10618         dst_address = 1;
10619       else if (unformat (input, "proto"))
10620         protocol = 1;
10621
10622 #define _(a) else if (unformat (input, #a)) a=1;
10623       foreach_ip4_proto_field
10624 #undef _
10625         else
10626         break;
10627     }
10628
10629 #define _(a) found_something += a;
10630   foreach_ip4_proto_field;
10631 #undef _
10632
10633   if (found_something == 0)
10634     return 0;
10635
10636   vec_validate (mask, sizeof (*ip) - 1);
10637
10638   ip = (ip4_header_t *) mask;
10639
10640 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10641   foreach_ip4_proto_field;
10642 #undef _
10643
10644   ip->ip_version_and_header_length = 0;
10645
10646   if (version)
10647     ip->ip_version_and_header_length |= 0xF0;
10648
10649   if (hdr_length)
10650     ip->ip_version_and_header_length |= 0x0F;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 #define foreach_ip6_proto_field                 \
10657 _(src_address)                                  \
10658 _(dst_address)                                  \
10659 _(payload_length)                               \
10660 _(hop_limit)                                    \
10661 _(protocol)
10662
10663 uword
10664 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10665 {
10666   u8 **maskp = va_arg (*args, u8 **);
10667   u8 *mask = 0;
10668   u8 found_something = 0;
10669   ip6_header_t *ip;
10670   u32 ip_version_traffic_class_and_flow_label;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip6_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 traffic_class = 0;
10677   u8 flow_label = 0;
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "traffic-class"))
10684         traffic_class = 1;
10685       else if (unformat (input, "flow-label"))
10686         flow_label = 1;
10687       else if (unformat (input, "src"))
10688         src_address = 1;
10689       else if (unformat (input, "dst"))
10690         dst_address = 1;
10691       else if (unformat (input, "proto"))
10692         protocol = 1;
10693
10694 #define _(a) else if (unformat (input, #a)) a=1;
10695       foreach_ip6_proto_field
10696 #undef _
10697         else
10698         break;
10699     }
10700
10701 #define _(a) found_something += a;
10702   foreach_ip6_proto_field;
10703 #undef _
10704
10705   if (found_something == 0)
10706     return 0;
10707
10708   vec_validate (mask, sizeof (*ip) - 1);
10709
10710   ip = (ip6_header_t *) mask;
10711
10712 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10713   foreach_ip6_proto_field;
10714 #undef _
10715
10716   ip_version_traffic_class_and_flow_label = 0;
10717
10718   if (version)
10719     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10720
10721   if (traffic_class)
10722     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10723
10724   if (flow_label)
10725     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10726
10727   ip->ip_version_traffic_class_and_flow_label =
10728     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10729
10730   *maskp = mask;
10731   return 1;
10732 }
10733
10734 uword
10735 unformat_l3_mask (unformat_input_t * input, va_list * args)
10736 {
10737   u8 **maskp = va_arg (*args, u8 **);
10738
10739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10742         return 1;
10743       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10744         return 1;
10745       else
10746         break;
10747     }
10748   return 0;
10749 }
10750
10751 uword
10752 unformat_l2_mask (unformat_input_t * input, va_list * args)
10753 {
10754   u8 **maskp = va_arg (*args, u8 **);
10755   u8 *mask = 0;
10756   u8 src = 0;
10757   u8 dst = 0;
10758   u8 proto = 0;
10759   u8 tag1 = 0;
10760   u8 tag2 = 0;
10761   u8 ignore_tag1 = 0;
10762   u8 ignore_tag2 = 0;
10763   u8 cos1 = 0;
10764   u8 cos2 = 0;
10765   u8 dot1q = 0;
10766   u8 dot1ad = 0;
10767   int len = 14;
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "src"))
10772         src = 1;
10773       else if (unformat (input, "dst"))
10774         dst = 1;
10775       else if (unformat (input, "proto"))
10776         proto = 1;
10777       else if (unformat (input, "tag1"))
10778         tag1 = 1;
10779       else if (unformat (input, "tag2"))
10780         tag2 = 1;
10781       else if (unformat (input, "ignore-tag1"))
10782         ignore_tag1 = 1;
10783       else if (unformat (input, "ignore-tag2"))
10784         ignore_tag2 = 1;
10785       else if (unformat (input, "cos1"))
10786         cos1 = 1;
10787       else if (unformat (input, "cos2"))
10788         cos2 = 1;
10789       else if (unformat (input, "dot1q"))
10790         dot1q = 1;
10791       else if (unformat (input, "dot1ad"))
10792         dot1ad = 1;
10793       else
10794         break;
10795     }
10796   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10797        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10798     return 0;
10799
10800   if (tag1 || ignore_tag1 || cos1 || dot1q)
10801     len = 18;
10802   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10803     len = 22;
10804
10805   vec_validate (mask, len - 1);
10806
10807   if (dst)
10808     memset (mask, 0xff, 6);
10809
10810   if (src)
10811     memset (mask + 6, 0xff, 6);
10812
10813   if (tag2 || dot1ad)
10814     {
10815       /* inner vlan tag */
10816       if (tag2)
10817         {
10818           mask[19] = 0xff;
10819           mask[18] = 0x0f;
10820         }
10821       if (cos2)
10822         mask[18] |= 0xe0;
10823       if (proto)
10824         mask[21] = mask[20] = 0xff;
10825       if (tag1)
10826         {
10827           mask[15] = 0xff;
10828           mask[14] = 0x0f;
10829         }
10830       if (cos1)
10831         mask[14] |= 0xe0;
10832       *maskp = mask;
10833       return 1;
10834     }
10835   if (tag1 | dot1q)
10836     {
10837       if (tag1)
10838         {
10839           mask[15] = 0xff;
10840           mask[14] = 0x0f;
10841         }
10842       if (cos1)
10843         mask[14] |= 0xe0;
10844       if (proto)
10845         mask[16] = mask[17] = 0xff;
10846
10847       *maskp = mask;
10848       return 1;
10849     }
10850   if (cos2)
10851     mask[18] |= 0xe0;
10852   if (cos1)
10853     mask[14] |= 0xe0;
10854   if (proto)
10855     mask[12] = mask[13] = 0xff;
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_classify_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u32 *skipp = va_arg (*args, u32 *);
10866   u32 *matchp = va_arg (*args, u32 *);
10867   u32 match;
10868   u8 *mask = 0;
10869   u8 *l2 = 0;
10870   u8 *l3 = 0;
10871   u8 *l4 = 0;
10872   int i;
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10877         ;
10878       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10879         ;
10880       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10881         ;
10882       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10883         ;
10884       else
10885         break;
10886     }
10887
10888   if (l4 && !l3)
10889     {
10890       vec_free (mask);
10891       vec_free (l2);
10892       vec_free (l4);
10893       return 0;
10894     }
10895
10896   if (mask || l2 || l3 || l4)
10897     {
10898       if (l2 || l3 || l4)
10899         {
10900           /* "With a free Ethernet header in every package" */
10901           if (l2 == 0)
10902             vec_validate (l2, 13);
10903           mask = l2;
10904           if (vec_len (l3))
10905             {
10906               vec_append (mask, l3);
10907               vec_free (l3);
10908             }
10909           if (vec_len (l4))
10910             {
10911               vec_append (mask, l4);
10912               vec_free (l4);
10913             }
10914         }
10915
10916       /* Scan forward looking for the first significant mask octet */
10917       for (i = 0; i < vec_len (mask); i++)
10918         if (mask[i])
10919           break;
10920
10921       /* compute (skip, match) params */
10922       *skipp = i / sizeof (u32x4);
10923       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10924
10925       /* Pad mask to an even multiple of the vector size */
10926       while (vec_len (mask) % sizeof (u32x4))
10927         vec_add1 (mask, 0);
10928
10929       match = vec_len (mask) / sizeof (u32x4);
10930
10931       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10932         {
10933           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10934           if (*tmp || *(tmp + 1))
10935             break;
10936           match--;
10937         }
10938       if (match == 0)
10939         clib_warning ("BUG: match 0");
10940
10941       _vec_len (mask) = match * sizeof (u32x4);
10942
10943       *matchp = match;
10944       *maskp = mask;
10945
10946       return 1;
10947     }
10948
10949   return 0;
10950 }
10951 #endif /* VPP_API_TEST_BUILTIN */
10952
10953 #define foreach_l2_next                         \
10954 _(drop, DROP)                                   \
10955 _(ethernet, ETHERNET_INPUT)                     \
10956 _(ip4, IP4_INPUT)                               \
10957 _(ip6, IP6_INPUT)
10958
10959 uword
10960 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10961 {
10962   u32 *miss_next_indexp = va_arg (*args, u32 *);
10963   u32 next_index = 0;
10964   u32 tmp;
10965
10966 #define _(n,N) \
10967   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10968   foreach_l2_next;
10969 #undef _
10970
10971   if (unformat (input, "%d", &tmp))
10972     {
10973       next_index = tmp;
10974       goto out;
10975     }
10976
10977   return 0;
10978
10979 out:
10980   *miss_next_indexp = next_index;
10981   return 1;
10982 }
10983
10984 #define foreach_ip_next                         \
10985 _(drop, DROP)                                   \
10986 _(local, LOCAL)                                 \
10987 _(rewrite, REWRITE)
10988
10989 uword
10990 api_unformat_ip_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 = IP_LOOKUP_NEXT_##N; goto out;}
10998   foreach_ip_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_acl_next                        \
11015 _(deny, DENY)
11016
11017 uword
11018 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11019 {
11020   u32 *miss_next_indexp = va_arg (*args, u32 *);
11021   u32 next_index = 0;
11022   u32 tmp;
11023
11024 #define _(n,N) \
11025   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11026   foreach_acl_next;
11027 #undef _
11028
11029   if (unformat (input, "permit"))
11030     {
11031       next_index = ~0;
11032       goto out;
11033     }
11034   else if (unformat (input, "%d", &tmp))
11035     {
11036       next_index = tmp;
11037       goto out;
11038     }
11039
11040   return 0;
11041
11042 out:
11043   *miss_next_indexp = next_index;
11044   return 1;
11045 }
11046
11047 uword
11048 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *r = va_arg (*args, u32 *);
11051
11052   if (unformat (input, "conform-color"))
11053     *r = POLICE_CONFORM;
11054   else if (unformat (input, "exceed-color"))
11055     *r = POLICE_EXCEED;
11056   else
11057     return 0;
11058
11059   return 1;
11060 }
11061
11062 static int
11063 api_classify_add_del_table (vat_main_t * vam)
11064 {
11065   unformat_input_t *i = vam->input;
11066   vl_api_classify_add_del_table_t *mp;
11067
11068   u32 nbuckets = 2;
11069   u32 skip = ~0;
11070   u32 match = ~0;
11071   int is_add = 1;
11072   int del_chain = 0;
11073   u32 table_index = ~0;
11074   u32 next_table_index = ~0;
11075   u32 miss_next_index = ~0;
11076   u32 memory_size = 32 << 20;
11077   u8 *mask = 0;
11078   u32 current_data_flag = 0;
11079   int current_data_offset = 0;
11080   int ret;
11081
11082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11083     {
11084       if (unformat (i, "del"))
11085         is_add = 0;
11086       else if (unformat (i, "del-chain"))
11087         {
11088           is_add = 0;
11089           del_chain = 1;
11090         }
11091       else if (unformat (i, "buckets %d", &nbuckets))
11092         ;
11093       else if (unformat (i, "memory_size %d", &memory_size))
11094         ;
11095       else if (unformat (i, "skip %d", &skip))
11096         ;
11097       else if (unformat (i, "match %d", &match))
11098         ;
11099       else if (unformat (i, "table %d", &table_index))
11100         ;
11101       else if (unformat (i, "mask %U", unformat_classify_mask,
11102                          &mask, &skip, &match))
11103         ;
11104       else if (unformat (i, "next-table %d", &next_table_index))
11105         ;
11106       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11107                          &miss_next_index))
11108         ;
11109       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11110                          &miss_next_index))
11111         ;
11112       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11113                          &miss_next_index))
11114         ;
11115       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11116         ;
11117       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11118         ;
11119       else
11120         break;
11121     }
11122
11123   if (is_add && mask == 0)
11124     {
11125       errmsg ("Mask required");
11126       return -99;
11127     }
11128
11129   if (is_add && skip == ~0)
11130     {
11131       errmsg ("skip count required");
11132       return -99;
11133     }
11134
11135   if (is_add && match == ~0)
11136     {
11137       errmsg ("match count required");
11138       return -99;
11139     }
11140
11141   if (!is_add && table_index == ~0)
11142     {
11143       errmsg ("table index required for delete");
11144       return -99;
11145     }
11146
11147   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11148
11149   mp->is_add = is_add;
11150   mp->del_chain = del_chain;
11151   mp->table_index = ntohl (table_index);
11152   mp->nbuckets = ntohl (nbuckets);
11153   mp->memory_size = ntohl (memory_size);
11154   mp->skip_n_vectors = ntohl (skip);
11155   mp->match_n_vectors = ntohl (match);
11156   mp->next_table_index = ntohl (next_table_index);
11157   mp->miss_next_index = ntohl (miss_next_index);
11158   mp->current_data_flag = ntohl (current_data_flag);
11159   mp->current_data_offset = ntohl (current_data_offset);
11160   clib_memcpy (mp->mask, mask, vec_len (mask));
11161
11162   vec_free (mask);
11163
11164   S (mp);
11165   W (ret);
11166   return ret;
11167 }
11168
11169 #if VPP_API_TEST_BUILTIN == 0
11170 uword
11171 unformat_l4_match (unformat_input_t * input, va_list * args)
11172 {
11173   u8 **matchp = va_arg (*args, u8 **);
11174
11175   u8 *proto_header = 0;
11176   int src_port = 0;
11177   int dst_port = 0;
11178
11179   tcpudp_header_t h;
11180
11181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (input, "src_port %d", &src_port))
11184         ;
11185       else if (unformat (input, "dst_port %d", &dst_port))
11186         ;
11187       else
11188         return 0;
11189     }
11190
11191   h.src_port = clib_host_to_net_u16 (src_port);
11192   h.dst_port = clib_host_to_net_u16 (dst_port);
11193   vec_validate (proto_header, sizeof (h) - 1);
11194   memcpy (proto_header, &h, sizeof (h));
11195
11196   *matchp = proto_header;
11197
11198   return 1;
11199 }
11200
11201 uword
11202 unformat_ip4_match (unformat_input_t * input, va_list * args)
11203 {
11204   u8 **matchp = va_arg (*args, u8 **);
11205   u8 *match = 0;
11206   ip4_header_t *ip;
11207   int version = 0;
11208   u32 version_val;
11209   int hdr_length = 0;
11210   u32 hdr_length_val;
11211   int src = 0, dst = 0;
11212   ip4_address_t src_val, dst_val;
11213   int proto = 0;
11214   u32 proto_val;
11215   int tos = 0;
11216   u32 tos_val;
11217   int length = 0;
11218   u32 length_val;
11219   int fragment_id = 0;
11220   u32 fragment_id_val;
11221   int ttl = 0;
11222   int ttl_val;
11223   int checksum = 0;
11224   u32 checksum_val;
11225
11226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11227     {
11228       if (unformat (input, "version %d", &version_val))
11229         version = 1;
11230       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11231         hdr_length = 1;
11232       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11233         src = 1;
11234       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11235         dst = 1;
11236       else if (unformat (input, "proto %d", &proto_val))
11237         proto = 1;
11238       else if (unformat (input, "tos %d", &tos_val))
11239         tos = 1;
11240       else if (unformat (input, "length %d", &length_val))
11241         length = 1;
11242       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11243         fragment_id = 1;
11244       else if (unformat (input, "ttl %d", &ttl_val))
11245         ttl = 1;
11246       else if (unformat (input, "checksum %d", &checksum_val))
11247         checksum = 1;
11248       else
11249         break;
11250     }
11251
11252   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11253       + ttl + checksum == 0)
11254     return 0;
11255
11256   /*
11257    * Aligned because we use the real comparison functions
11258    */
11259   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11260
11261   ip = (ip4_header_t *) match;
11262
11263   /* These are realistically matched in practice */
11264   if (src)
11265     ip->src_address.as_u32 = src_val.as_u32;
11266
11267   if (dst)
11268     ip->dst_address.as_u32 = dst_val.as_u32;
11269
11270   if (proto)
11271     ip->protocol = proto_val;
11272
11273
11274   /* These are not, but they're included for completeness */
11275   if (version)
11276     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11277
11278   if (hdr_length)
11279     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11280
11281   if (tos)
11282     ip->tos = tos_val;
11283
11284   if (length)
11285     ip->length = clib_host_to_net_u16 (length_val);
11286
11287   if (ttl)
11288     ip->ttl = ttl_val;
11289
11290   if (checksum)
11291     ip->checksum = clib_host_to_net_u16 (checksum_val);
11292
11293   *matchp = match;
11294   return 1;
11295 }
11296
11297 uword
11298 unformat_ip6_match (unformat_input_t * input, va_list * args)
11299 {
11300   u8 **matchp = va_arg (*args, u8 **);
11301   u8 *match = 0;
11302   ip6_header_t *ip;
11303   int version = 0;
11304   u32 version_val;
11305   u8 traffic_class = 0;
11306   u32 traffic_class_val = 0;
11307   u8 flow_label = 0;
11308   u8 flow_label_val;
11309   int src = 0, dst = 0;
11310   ip6_address_t src_val, dst_val;
11311   int proto = 0;
11312   u32 proto_val;
11313   int payload_length = 0;
11314   u32 payload_length_val;
11315   int hop_limit = 0;
11316   int hop_limit_val;
11317   u32 ip_version_traffic_class_and_flow_label;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "version %d", &version_val))
11322         version = 1;
11323       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11324         traffic_class = 1;
11325       else if (unformat (input, "flow_label %d", &flow_label_val))
11326         flow_label = 1;
11327       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11328         src = 1;
11329       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11330         dst = 1;
11331       else if (unformat (input, "proto %d", &proto_val))
11332         proto = 1;
11333       else if (unformat (input, "payload_length %d", &payload_length_val))
11334         payload_length = 1;
11335       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11336         hop_limit = 1;
11337       else
11338         break;
11339     }
11340
11341   if (version + traffic_class + flow_label + src + dst + proto +
11342       payload_length + hop_limit == 0)
11343     return 0;
11344
11345   /*
11346    * Aligned because we use the real comparison functions
11347    */
11348   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11349
11350   ip = (ip6_header_t *) match;
11351
11352   if (src)
11353     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11354
11355   if (dst)
11356     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11357
11358   if (proto)
11359     ip->protocol = proto_val;
11360
11361   ip_version_traffic_class_and_flow_label = 0;
11362
11363   if (version)
11364     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11365
11366   if (traffic_class)
11367     ip_version_traffic_class_and_flow_label |=
11368       (traffic_class_val & 0xFF) << 20;
11369
11370   if (flow_label)
11371     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11372
11373   ip->ip_version_traffic_class_and_flow_label =
11374     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11375
11376   if (payload_length)
11377     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11378
11379   if (hop_limit)
11380     ip->hop_limit = hop_limit_val;
11381
11382   *matchp = match;
11383   return 1;
11384 }
11385
11386 uword
11387 unformat_l3_match (unformat_input_t * input, va_list * args)
11388 {
11389   u8 **matchp = va_arg (*args, u8 **);
11390
11391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11394         return 1;
11395       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11396         return 1;
11397       else
11398         break;
11399     }
11400   return 0;
11401 }
11402
11403 uword
11404 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11405 {
11406   u8 *tagp = va_arg (*args, u8 *);
11407   u32 tag;
11408
11409   if (unformat (input, "%d", &tag))
11410     {
11411       tagp[0] = (tag >> 8) & 0x0F;
11412       tagp[1] = tag & 0xFF;
11413       return 1;
11414     }
11415
11416   return 0;
11417 }
11418
11419 uword
11420 unformat_l2_match (unformat_input_t * input, va_list * args)
11421 {
11422   u8 **matchp = va_arg (*args, u8 **);
11423   u8 *match = 0;
11424   u8 src = 0;
11425   u8 src_val[6];
11426   u8 dst = 0;
11427   u8 dst_val[6];
11428   u8 proto = 0;
11429   u16 proto_val;
11430   u8 tag1 = 0;
11431   u8 tag1_val[2];
11432   u8 tag2 = 0;
11433   u8 tag2_val[2];
11434   int len = 14;
11435   u8 ignore_tag1 = 0;
11436   u8 ignore_tag2 = 0;
11437   u8 cos1 = 0;
11438   u8 cos2 = 0;
11439   u32 cos1_val = 0;
11440   u32 cos2_val = 0;
11441
11442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11445         src = 1;
11446       else
11447         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11448         dst = 1;
11449       else if (unformat (input, "proto %U",
11450                          unformat_ethernet_type_host_byte_order, &proto_val))
11451         proto = 1;
11452       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11453         tag1 = 1;
11454       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11455         tag2 = 1;
11456       else if (unformat (input, "ignore-tag1"))
11457         ignore_tag1 = 1;
11458       else if (unformat (input, "ignore-tag2"))
11459         ignore_tag2 = 1;
11460       else if (unformat (input, "cos1 %d", &cos1_val))
11461         cos1 = 1;
11462       else if (unformat (input, "cos2 %d", &cos2_val))
11463         cos2 = 1;
11464       else
11465         break;
11466     }
11467   if ((src + dst + proto + tag1 + tag2 +
11468        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11469     return 0;
11470
11471   if (tag1 || ignore_tag1 || cos1)
11472     len = 18;
11473   if (tag2 || ignore_tag2 || cos2)
11474     len = 22;
11475
11476   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11477
11478   if (dst)
11479     clib_memcpy (match, dst_val, 6);
11480
11481   if (src)
11482     clib_memcpy (match + 6, src_val, 6);
11483
11484   if (tag2)
11485     {
11486       /* inner vlan tag */
11487       match[19] = tag2_val[1];
11488       match[18] = tag2_val[0];
11489       if (cos2)
11490         match[18] |= (cos2_val & 0x7) << 5;
11491       if (proto)
11492         {
11493           match[21] = proto_val & 0xff;
11494           match[20] = proto_val >> 8;
11495         }
11496       if (tag1)
11497         {
11498           match[15] = tag1_val[1];
11499           match[14] = tag1_val[0];
11500         }
11501       if (cos1)
11502         match[14] |= (cos1_val & 0x7) << 5;
11503       *matchp = match;
11504       return 1;
11505     }
11506   if (tag1)
11507     {
11508       match[15] = tag1_val[1];
11509       match[14] = tag1_val[0];
11510       if (proto)
11511         {
11512           match[17] = proto_val & 0xff;
11513           match[16] = proto_val >> 8;
11514         }
11515       if (cos1)
11516         match[14] |= (cos1_val & 0x7) << 5;
11517
11518       *matchp = match;
11519       return 1;
11520     }
11521   if (cos2)
11522     match[18] |= (cos2_val & 0x7) << 5;
11523   if (cos1)
11524     match[14] |= (cos1_val & 0x7) << 5;
11525   if (proto)
11526     {
11527       match[13] = proto_val & 0xff;
11528       match[12] = proto_val >> 8;
11529     }
11530
11531   *matchp = match;
11532   return 1;
11533 }
11534 #endif
11535
11536 uword
11537 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11538 {
11539   u8 **matchp = va_arg (*args, u8 **);
11540   u32 skip_n_vectors = va_arg (*args, u32);
11541   u32 match_n_vectors = va_arg (*args, u32);
11542
11543   u8 *match = 0;
11544   u8 *l2 = 0;
11545   u8 *l3 = 0;
11546   u8 *l4 = 0;
11547
11548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (input, "hex %U", unformat_hex_string, &match))
11551         ;
11552       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11553         ;
11554       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11555         ;
11556       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11557         ;
11558       else
11559         break;
11560     }
11561
11562   if (l4 && !l3)
11563     {
11564       vec_free (match);
11565       vec_free (l2);
11566       vec_free (l4);
11567       return 0;
11568     }
11569
11570   if (match || l2 || l3 || l4)
11571     {
11572       if (l2 || l3 || l4)
11573         {
11574           /* "Win a free Ethernet header in every packet" */
11575           if (l2 == 0)
11576             vec_validate_aligned (l2, 13, sizeof (u32x4));
11577           match = l2;
11578           if (vec_len (l3))
11579             {
11580               vec_append_aligned (match, l3, sizeof (u32x4));
11581               vec_free (l3);
11582             }
11583           if (vec_len (l4))
11584             {
11585               vec_append_aligned (match, l4, sizeof (u32x4));
11586               vec_free (l4);
11587             }
11588         }
11589
11590       /* Make sure the vector is big enough even if key is all 0's */
11591       vec_validate_aligned
11592         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11593          sizeof (u32x4));
11594
11595       /* Set size, include skipped vectors */
11596       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11597
11598       *matchp = match;
11599
11600       return 1;
11601     }
11602
11603   return 0;
11604 }
11605
11606 static int
11607 api_classify_add_del_session (vat_main_t * vam)
11608 {
11609   unformat_input_t *i = vam->input;
11610   vl_api_classify_add_del_session_t *mp;
11611   int is_add = 1;
11612   u32 table_index = ~0;
11613   u32 hit_next_index = ~0;
11614   u32 opaque_index = ~0;
11615   u8 *match = 0;
11616   i32 advance = 0;
11617   u32 skip_n_vectors = 0;
11618   u32 match_n_vectors = 0;
11619   u32 action = 0;
11620   u32 metadata = 0;
11621   int ret;
11622
11623   /*
11624    * Warning: you have to supply skip_n and match_n
11625    * because the API client cant simply look at the classify
11626    * table object.
11627    */
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "del"))
11632         is_add = 0;
11633       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11634                          &hit_next_index))
11635         ;
11636       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11637                          &hit_next_index))
11638         ;
11639       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11640                          &hit_next_index))
11641         ;
11642       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11643         ;
11644       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11645         ;
11646       else if (unformat (i, "opaque-index %d", &opaque_index))
11647         ;
11648       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11649         ;
11650       else if (unformat (i, "match_n %d", &match_n_vectors))
11651         ;
11652       else if (unformat (i, "match %U", api_unformat_classify_match,
11653                          &match, skip_n_vectors, match_n_vectors))
11654         ;
11655       else if (unformat (i, "advance %d", &advance))
11656         ;
11657       else if (unformat (i, "table-index %d", &table_index))
11658         ;
11659       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11660         action = 1;
11661       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11662         action = 2;
11663       else if (unformat (i, "action %d", &action))
11664         ;
11665       else if (unformat (i, "metadata %d", &metadata))
11666         ;
11667       else
11668         break;
11669     }
11670
11671   if (table_index == ~0)
11672     {
11673       errmsg ("Table index required");
11674       return -99;
11675     }
11676
11677   if (is_add && match == 0)
11678     {
11679       errmsg ("Match value required");
11680       return -99;
11681     }
11682
11683   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11684
11685   mp->is_add = is_add;
11686   mp->table_index = ntohl (table_index);
11687   mp->hit_next_index = ntohl (hit_next_index);
11688   mp->opaque_index = ntohl (opaque_index);
11689   mp->advance = ntohl (advance);
11690   mp->action = action;
11691   mp->metadata = ntohl (metadata);
11692   clib_memcpy (mp->match, match, vec_len (match));
11693   vec_free (match);
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_classify_set_interface_ip_table (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_classify_set_interface_ip_table_t *mp;
11705   u32 sw_if_index;
11706   int sw_if_index_set;
11707   u32 table_index = ~0;
11708   u8 is_ipv6 = 0;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "table %d", &table_index))
11718         ;
11719       else
11720         {
11721           clib_warning ("parse error '%U'", format_unformat_error, i);
11722           return -99;
11723         }
11724     }
11725
11726   if (sw_if_index_set == 0)
11727     {
11728       errmsg ("missing interface name or sw_if_index");
11729       return -99;
11730     }
11731
11732
11733   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11734
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->table_index = ntohl (table_index);
11737   mp->is_ipv6 = is_ipv6;
11738
11739   S (mp);
11740   W (ret);
11741   return ret;
11742 }
11743
11744 static int
11745 api_classify_set_interface_l2_tables (vat_main_t * vam)
11746 {
11747   unformat_input_t *i = vam->input;
11748   vl_api_classify_set_interface_l2_tables_t *mp;
11749   u32 sw_if_index;
11750   int sw_if_index_set;
11751   u32 ip4_table_index = ~0;
11752   u32 ip6_table_index = ~0;
11753   u32 other_table_index = ~0;
11754   u32 is_input = 1;
11755   int ret;
11756
11757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11758     {
11759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11762         sw_if_index_set = 1;
11763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11764         ;
11765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11766         ;
11767       else if (unformat (i, "other-table %d", &other_table_index))
11768         ;
11769       else if (unformat (i, "is-input %d", &is_input))
11770         ;
11771       else
11772         {
11773           clib_warning ("parse error '%U'", format_unformat_error, i);
11774           return -99;
11775         }
11776     }
11777
11778   if (sw_if_index_set == 0)
11779     {
11780       errmsg ("missing interface name or sw_if_index");
11781       return -99;
11782     }
11783
11784
11785   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11786
11787   mp->sw_if_index = ntohl (sw_if_index);
11788   mp->ip4_table_index = ntohl (ip4_table_index);
11789   mp->ip6_table_index = ntohl (ip6_table_index);
11790   mp->other_table_index = ntohl (other_table_index);
11791   mp->is_input = (u8) is_input;
11792
11793   S (mp);
11794   W (ret);
11795   return ret;
11796 }
11797
11798 static int
11799 api_set_ipfix_exporter (vat_main_t * vam)
11800 {
11801   unformat_input_t *i = vam->input;
11802   vl_api_set_ipfix_exporter_t *mp;
11803   ip4_address_t collector_address;
11804   u8 collector_address_set = 0;
11805   u32 collector_port = ~0;
11806   ip4_address_t src_address;
11807   u8 src_address_set = 0;
11808   u32 vrf_id = ~0;
11809   u32 path_mtu = ~0;
11810   u32 template_interval = ~0;
11811   u8 udp_checksum = 0;
11812   int ret;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "collector_address %U", unformat_ip4_address,
11817                     &collector_address))
11818         collector_address_set = 1;
11819       else if (unformat (i, "collector_port %d", &collector_port))
11820         ;
11821       else if (unformat (i, "src_address %U", unformat_ip4_address,
11822                          &src_address))
11823         src_address_set = 1;
11824       else if (unformat (i, "vrf_id %d", &vrf_id))
11825         ;
11826       else if (unformat (i, "path_mtu %d", &path_mtu))
11827         ;
11828       else if (unformat (i, "template_interval %d", &template_interval))
11829         ;
11830       else if (unformat (i, "udp_checksum"))
11831         udp_checksum = 1;
11832       else
11833         break;
11834     }
11835
11836   if (collector_address_set == 0)
11837     {
11838       errmsg ("collector_address required");
11839       return -99;
11840     }
11841
11842   if (src_address_set == 0)
11843     {
11844       errmsg ("src_address required");
11845       return -99;
11846     }
11847
11848   M (SET_IPFIX_EXPORTER, mp);
11849
11850   memcpy (mp->collector_address, collector_address.data,
11851           sizeof (collector_address.data));
11852   mp->collector_port = htons ((u16) collector_port);
11853   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11854   mp->vrf_id = htonl (vrf_id);
11855   mp->path_mtu = htonl (path_mtu);
11856   mp->template_interval = htonl (template_interval);
11857   mp->udp_checksum = udp_checksum;
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_set_ipfix_classify_stream (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_set_ipfix_classify_stream_t *mp;
11869   u32 domain_id = 0;
11870   u32 src_port = UDP_DST_PORT_ipfix;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "domain %d", &domain_id))
11876         ;
11877       else if (unformat (i, "src_port %d", &src_port))
11878         ;
11879       else
11880         {
11881           errmsg ("unknown input `%U'", format_unformat_error, i);
11882           return -99;
11883         }
11884     }
11885
11886   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11887
11888   mp->domain_id = htonl (domain_id);
11889   mp->src_port = htons ((u16) src_port);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_ipfix_classify_table_add_del (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_ipfix_classify_table_add_del_t *mp;
11901   int is_add = -1;
11902   u32 classify_table_index = ~0;
11903   u8 ip_version = 0;
11904   u8 transport_protocol = 255;
11905   int ret;
11906
11907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11908     {
11909       if (unformat (i, "add"))
11910         is_add = 1;
11911       else if (unformat (i, "del"))
11912         is_add = 0;
11913       else if (unformat (i, "table %d", &classify_table_index))
11914         ;
11915       else if (unformat (i, "ip4"))
11916         ip_version = 4;
11917       else if (unformat (i, "ip6"))
11918         ip_version = 6;
11919       else if (unformat (i, "tcp"))
11920         transport_protocol = 6;
11921       else if (unformat (i, "udp"))
11922         transport_protocol = 17;
11923       else
11924         {
11925           errmsg ("unknown input `%U'", format_unformat_error, i);
11926           return -99;
11927         }
11928     }
11929
11930   if (is_add == -1)
11931     {
11932       errmsg ("expecting: add|del");
11933       return -99;
11934     }
11935   if (classify_table_index == ~0)
11936     {
11937       errmsg ("classifier table not specified");
11938       return -99;
11939     }
11940   if (ip_version == 0)
11941     {
11942       errmsg ("IP version not specified");
11943       return -99;
11944     }
11945
11946   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11947
11948   mp->is_add = is_add;
11949   mp->table_id = htonl (classify_table_index);
11950   mp->ip_version = ip_version;
11951   mp->transport_protocol = transport_protocol;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_get_node_index (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_get_node_index_t *mp;
11963   u8 *name = 0;
11964   int ret;
11965
11966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (i, "node %s", &name))
11969         ;
11970       else
11971         break;
11972     }
11973   if (name == 0)
11974     {
11975       errmsg ("node name required");
11976       return -99;
11977     }
11978   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11979     {
11980       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11981       return -99;
11982     }
11983
11984   M (GET_NODE_INDEX, mp);
11985   clib_memcpy (mp->node_name, name, vec_len (name));
11986   vec_free (name);
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993 static int
11994 api_get_next_index (vat_main_t * vam)
11995 {
11996   unformat_input_t *i = vam->input;
11997   vl_api_get_next_index_t *mp;
11998   u8 *node_name = 0, *next_node_name = 0;
11999   int ret;
12000
12001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (i, "node-name %s", &node_name))
12004         ;
12005       else if (unformat (i, "next-node-name %s", &next_node_name))
12006         break;
12007     }
12008
12009   if (node_name == 0)
12010     {
12011       errmsg ("node name required");
12012       return -99;
12013     }
12014   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12015     {
12016       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12017       return -99;
12018     }
12019
12020   if (next_node_name == 0)
12021     {
12022       errmsg ("next node name required");
12023       return -99;
12024     }
12025   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12026     {
12027       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12028       return -99;
12029     }
12030
12031   M (GET_NEXT_INDEX, mp);
12032   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12033   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12034   vec_free (node_name);
12035   vec_free (next_node_name);
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_add_node_next (vat_main_t * vam)
12044 {
12045   unformat_input_t *i = vam->input;
12046   vl_api_add_node_next_t *mp;
12047   u8 *name = 0;
12048   u8 *next = 0;
12049   int ret;
12050
12051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (i, "node %s", &name))
12054         ;
12055       else if (unformat (i, "next %s", &next))
12056         ;
12057       else
12058         break;
12059     }
12060   if (name == 0)
12061     {
12062       errmsg ("node name required");
12063       return -99;
12064     }
12065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12066     {
12067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12068       return -99;
12069     }
12070   if (next == 0)
12071     {
12072       errmsg ("next node required");
12073       return -99;
12074     }
12075   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12076     {
12077       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12078       return -99;
12079     }
12080
12081   M (ADD_NODE_NEXT, mp);
12082   clib_memcpy (mp->node_name, name, vec_len (name));
12083   clib_memcpy (mp->next_name, next, vec_len (next));
12084   vec_free (name);
12085   vec_free (next);
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_l2tpv3_create_tunnel (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   ip6_address_t client_address, our_address;
12097   int client_address_set = 0;
12098   int our_address_set = 0;
12099   u32 local_session_id = 0;
12100   u32 remote_session_id = 0;
12101   u64 local_cookie = 0;
12102   u64 remote_cookie = 0;
12103   u8 l2_sublayer_present = 0;
12104   vl_api_l2tpv3_create_tunnel_t *mp;
12105   int ret;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "client_address %U", unformat_ip6_address,
12110                     &client_address))
12111         client_address_set = 1;
12112       else if (unformat (i, "our_address %U", unformat_ip6_address,
12113                          &our_address))
12114         our_address_set = 1;
12115       else if (unformat (i, "local_session_id %d", &local_session_id))
12116         ;
12117       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12118         ;
12119       else if (unformat (i, "local_cookie %lld", &local_cookie))
12120         ;
12121       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12122         ;
12123       else if (unformat (i, "l2-sublayer-present"))
12124         l2_sublayer_present = 1;
12125       else
12126         break;
12127     }
12128
12129   if (client_address_set == 0)
12130     {
12131       errmsg ("client_address required");
12132       return -99;
12133     }
12134
12135   if (our_address_set == 0)
12136     {
12137       errmsg ("our_address required");
12138       return -99;
12139     }
12140
12141   M (L2TPV3_CREATE_TUNNEL, mp);
12142
12143   clib_memcpy (mp->client_address, client_address.as_u8,
12144                sizeof (mp->client_address));
12145
12146   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12147
12148   mp->local_session_id = ntohl (local_session_id);
12149   mp->remote_session_id = ntohl (remote_session_id);
12150   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12151   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12152   mp->l2_sublayer_present = l2_sublayer_present;
12153   mp->is_ipv6 = 1;
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   u32 sw_if_index;
12165   u8 sw_if_index_set = 0;
12166   u64 new_local_cookie = 0;
12167   u64 new_remote_cookie = 0;
12168   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12174         sw_if_index_set = 1;
12175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12178         ;
12179       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12180         ;
12181       else
12182         break;
12183     }
12184
12185   if (sw_if_index_set == 0)
12186     {
12187       errmsg ("missing interface name or sw_if_index");
12188       return -99;
12189     }
12190
12191   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12192
12193   mp->sw_if_index = ntohl (sw_if_index);
12194   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12195   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_l2tpv3_interface_enable_disable_t *mp;
12207   u32 sw_if_index;
12208   u8 sw_if_index_set = 0;
12209   u8 enable_disable = 1;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "enable"))
12219         enable_disable = 1;
12220       else if (unformat (i, "disable"))
12221         enable_disable = 0;
12222       else
12223         break;
12224     }
12225
12226   if (sw_if_index_set == 0)
12227     {
12228       errmsg ("missing interface name or sw_if_index");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12233
12234   mp->sw_if_index = ntohl (sw_if_index);
12235   mp->enable_disable = enable_disable;
12236
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 static int
12243 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12244 {
12245   unformat_input_t *i = vam->input;
12246   vl_api_l2tpv3_set_lookup_key_t *mp;
12247   u8 key = ~0;
12248   int ret;
12249
12250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12251     {
12252       if (unformat (i, "lookup_v6_src"))
12253         key = L2T_LOOKUP_SRC_ADDRESS;
12254       else if (unformat (i, "lookup_v6_dst"))
12255         key = L2T_LOOKUP_DST_ADDRESS;
12256       else if (unformat (i, "lookup_session_id"))
12257         key = L2T_LOOKUP_SESSION_ID;
12258       else
12259         break;
12260     }
12261
12262   if (key == (u8) ~ 0)
12263     {
12264       errmsg ("l2tp session lookup key unset");
12265       return -99;
12266     }
12267
12268   M (L2TPV3_SET_LOOKUP_KEY, mp);
12269
12270   mp->key = key;
12271
12272   S (mp);
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12278   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281
12282   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12283          format_ip6_address, mp->our_address,
12284          format_ip6_address, mp->client_address,
12285          clib_net_to_host_u32 (mp->sw_if_index));
12286
12287   print (vam->ofp,
12288          "   local cookies %016llx %016llx remote cookie %016llx",
12289          clib_net_to_host_u64 (mp->local_cookie[0]),
12290          clib_net_to_host_u64 (mp->local_cookie[1]),
12291          clib_net_to_host_u64 (mp->remote_cookie));
12292
12293   print (vam->ofp, "   local session-id %d remote session-id %d",
12294          clib_net_to_host_u32 (mp->local_session_id),
12295          clib_net_to_host_u32 (mp->remote_session_id));
12296
12297   print (vam->ofp, "   l2 specific sublayer %s\n",
12298          mp->l2_sublayer_present ? "preset" : "absent");
12299
12300 }
12301
12302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12304 {
12305   vat_main_t *vam = &vat_main;
12306   vat_json_node_t *node = NULL;
12307   struct in6_addr addr;
12308
12309   if (VAT_JSON_ARRAY != vam->json_tree.type)
12310     {
12311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12312       vat_json_init_array (&vam->json_tree);
12313     }
12314   node = vat_json_array_add (&vam->json_tree);
12315
12316   vat_json_init_object (node);
12317
12318   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12319   vat_json_object_add_ip6 (node, "our_address", addr);
12320   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12321   vat_json_object_add_ip6 (node, "client_address", addr);
12322
12323   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12324   vat_json_init_array (lc);
12325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12327   vat_json_object_add_uint (node, "remote_cookie",
12328                             clib_net_to_host_u64 (mp->remote_cookie));
12329
12330   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12331   vat_json_object_add_uint (node, "local_session_id",
12332                             clib_net_to_host_u32 (mp->local_session_id));
12333   vat_json_object_add_uint (node, "remote_session_id",
12334                             clib_net_to_host_u32 (mp->remote_session_id));
12335   vat_json_object_add_string_copy (node, "l2_sublayer",
12336                                    mp->l2_sublayer_present ? (u8 *) "present"
12337                                    : (u8 *) "absent");
12338 }
12339
12340 static int
12341 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12342 {
12343   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12344   vl_api_control_ping_t *mp_ping;
12345   int ret;
12346
12347   /* Get list of l2tpv3-tunnel interfaces */
12348   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12349   S (mp);
12350
12351   /* Use a control ping for synchronization */
12352   MPING (CONTROL_PING, mp_ping);
12353   S (mp_ping);
12354
12355   W (ret);
12356   return ret;
12357 }
12358
12359
12360 static void vl_api_sw_interface_tap_details_t_handler
12361   (vl_api_sw_interface_tap_details_t * mp)
12362 {
12363   vat_main_t *vam = &vat_main;
12364
12365   print (vam->ofp, "%-16s %d",
12366          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12367 }
12368
12369 static void vl_api_sw_interface_tap_details_t_handler_json
12370   (vl_api_sw_interface_tap_details_t * mp)
12371 {
12372   vat_main_t *vam = &vat_main;
12373   vat_json_node_t *node = NULL;
12374
12375   if (VAT_JSON_ARRAY != vam->json_tree.type)
12376     {
12377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12378       vat_json_init_array (&vam->json_tree);
12379     }
12380   node = vat_json_array_add (&vam->json_tree);
12381
12382   vat_json_init_object (node);
12383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12384   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12385 }
12386
12387 static int
12388 api_sw_interface_tap_dump (vat_main_t * vam)
12389 {
12390   vl_api_sw_interface_tap_dump_t *mp;
12391   vl_api_control_ping_t *mp_ping;
12392   int ret;
12393
12394   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12395   /* Get list of tap interfaces */
12396   M (SW_INTERFACE_TAP_DUMP, mp);
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   MPING (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static void vl_api_sw_interface_tap_v2_details_t_handler
12408   (vl_api_sw_interface_tap_v2_details_t * mp)
12409 {
12410   vat_main_t *vam = &vat_main;
12411
12412   print (vam->ofp, "%-16s %d",
12413          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12414 }
12415
12416 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12417   (vl_api_sw_interface_tap_v2_details_t * mp)
12418 {
12419   vat_main_t *vam = &vat_main;
12420   vat_json_node_t *node = NULL;
12421
12422   if (VAT_JSON_ARRAY != vam->json_tree.type)
12423     {
12424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12425       vat_json_init_array (&vam->json_tree);
12426     }
12427   node = vat_json_array_add (&vam->json_tree);
12428
12429   vat_json_init_object (node);
12430   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12431   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12432 }
12433
12434 static int
12435 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12436 {
12437   vl_api_sw_interface_tap_v2_dump_t *mp;
12438   vl_api_control_ping_t *mp_ping;
12439   int ret;
12440
12441   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12442   /* Get list of tap interfaces */
12443   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12444   S (mp);
12445
12446   /* Use a control ping for synchronization */
12447   MPING (CONTROL_PING, mp_ping);
12448   S (mp_ping);
12449
12450   W (ret);
12451   return ret;
12452 }
12453
12454 static uword unformat_vxlan_decap_next
12455   (unformat_input_t * input, va_list * args)
12456 {
12457   u32 *result = va_arg (*args, u32 *);
12458   u32 tmp;
12459
12460   if (unformat (input, "l2"))
12461     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12462   else if (unformat (input, "%d", &tmp))
12463     *result = tmp;
12464   else
12465     return 0;
12466   return 1;
12467 }
12468
12469 static int
12470 api_vxlan_add_del_tunnel (vat_main_t * vam)
12471 {
12472   unformat_input_t *line_input = vam->input;
12473   vl_api_vxlan_add_del_tunnel_t *mp;
12474   ip46_address_t src, dst;
12475   u8 is_add = 1;
12476   u8 ipv4_set = 0, ipv6_set = 0;
12477   u8 src_set = 0;
12478   u8 dst_set = 0;
12479   u8 grp_set = 0;
12480   u32 mcast_sw_if_index = ~0;
12481   u32 encap_vrf_id = 0;
12482   u32 decap_next_index = ~0;
12483   u32 vni = 0;
12484   int ret;
12485
12486   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12487   memset (&src, 0, sizeof src);
12488   memset (&dst, 0, sizeof dst);
12489
12490   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12491     {
12492       if (unformat (line_input, "del"))
12493         is_add = 0;
12494       else
12495         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12496         {
12497           ipv4_set = 1;
12498           src_set = 1;
12499         }
12500       else
12501         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12502         {
12503           ipv4_set = 1;
12504           dst_set = 1;
12505         }
12506       else
12507         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12508         {
12509           ipv6_set = 1;
12510           src_set = 1;
12511         }
12512       else
12513         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12514         {
12515           ipv6_set = 1;
12516           dst_set = 1;
12517         }
12518       else if (unformat (line_input, "group %U %U",
12519                          unformat_ip4_address, &dst.ip4,
12520                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12521         {
12522           grp_set = dst_set = 1;
12523           ipv4_set = 1;
12524         }
12525       else if (unformat (line_input, "group %U",
12526                          unformat_ip4_address, &dst.ip4))
12527         {
12528           grp_set = dst_set = 1;
12529           ipv4_set = 1;
12530         }
12531       else if (unformat (line_input, "group %U %U",
12532                          unformat_ip6_address, &dst.ip6,
12533                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12534         {
12535           grp_set = dst_set = 1;
12536           ipv6_set = 1;
12537         }
12538       else if (unformat (line_input, "group %U",
12539                          unformat_ip6_address, &dst.ip6))
12540         {
12541           grp_set = dst_set = 1;
12542           ipv6_set = 1;
12543         }
12544       else
12545         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12546         ;
12547       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12548         ;
12549       else if (unformat (line_input, "decap-next %U",
12550                          unformat_vxlan_decap_next, &decap_next_index))
12551         ;
12552       else if (unformat (line_input, "vni %d", &vni))
12553         ;
12554       else
12555         {
12556           errmsg ("parse error '%U'", format_unformat_error, line_input);
12557           return -99;
12558         }
12559     }
12560
12561   if (src_set == 0)
12562     {
12563       errmsg ("tunnel src address not specified");
12564       return -99;
12565     }
12566   if (dst_set == 0)
12567     {
12568       errmsg ("tunnel dst address not specified");
12569       return -99;
12570     }
12571
12572   if (grp_set && !ip46_address_is_multicast (&dst))
12573     {
12574       errmsg ("tunnel group address not multicast");
12575       return -99;
12576     }
12577   if (grp_set && mcast_sw_if_index == ~0)
12578     {
12579       errmsg ("tunnel nonexistent multicast device");
12580       return -99;
12581     }
12582   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12583     {
12584       errmsg ("tunnel dst address must be unicast");
12585       return -99;
12586     }
12587
12588
12589   if (ipv4_set && ipv6_set)
12590     {
12591       errmsg ("both IPv4 and IPv6 addresses specified");
12592       return -99;
12593     }
12594
12595   if ((vni == 0) || (vni >> 24))
12596     {
12597       errmsg ("vni not specified or out of range");
12598       return -99;
12599     }
12600
12601   M (VXLAN_ADD_DEL_TUNNEL, mp);
12602
12603   if (ipv6_set)
12604     {
12605       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12606       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12607     }
12608   else
12609     {
12610       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12611       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12612     }
12613   mp->encap_vrf_id = ntohl (encap_vrf_id);
12614   mp->decap_next_index = ntohl (decap_next_index);
12615   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12616   mp->vni = ntohl (vni);
12617   mp->is_add = is_add;
12618   mp->is_ipv6 = ipv6_set;
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static void vl_api_vxlan_tunnel_details_t_handler
12626   (vl_api_vxlan_tunnel_details_t * mp)
12627 {
12628   vat_main_t *vam = &vat_main;
12629   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12630   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12631
12632   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12633          ntohl (mp->sw_if_index),
12634          format_ip46_address, &src, IP46_TYPE_ANY,
12635          format_ip46_address, &dst, IP46_TYPE_ANY,
12636          ntohl (mp->encap_vrf_id),
12637          ntohl (mp->decap_next_index), ntohl (mp->vni),
12638          ntohl (mp->mcast_sw_if_index));
12639 }
12640
12641 static void vl_api_vxlan_tunnel_details_t_handler_json
12642   (vl_api_vxlan_tunnel_details_t * mp)
12643 {
12644   vat_main_t *vam = &vat_main;
12645   vat_json_node_t *node = NULL;
12646
12647   if (VAT_JSON_ARRAY != vam->json_tree.type)
12648     {
12649       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12650       vat_json_init_array (&vam->json_tree);
12651     }
12652   node = vat_json_array_add (&vam->json_tree);
12653
12654   vat_json_init_object (node);
12655   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12656   if (mp->is_ipv6)
12657     {
12658       struct in6_addr ip6;
12659
12660       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12661       vat_json_object_add_ip6 (node, "src_address", ip6);
12662       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12663       vat_json_object_add_ip6 (node, "dst_address", ip6);
12664     }
12665   else
12666     {
12667       struct in_addr ip4;
12668
12669       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12670       vat_json_object_add_ip4 (node, "src_address", ip4);
12671       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12672       vat_json_object_add_ip4 (node, "dst_address", ip4);
12673     }
12674   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12675   vat_json_object_add_uint (node, "decap_next_index",
12676                             ntohl (mp->decap_next_index));
12677   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12678   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12679   vat_json_object_add_uint (node, "mcast_sw_if_index",
12680                             ntohl (mp->mcast_sw_if_index));
12681 }
12682
12683 static int
12684 api_vxlan_tunnel_dump (vat_main_t * vam)
12685 {
12686   unformat_input_t *i = vam->input;
12687   vl_api_vxlan_tunnel_dump_t *mp;
12688   vl_api_control_ping_t *mp_ping;
12689   u32 sw_if_index;
12690   u8 sw_if_index_set = 0;
12691   int ret;
12692
12693   /* Parse args required to build the message */
12694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12695     {
12696       if (unformat (i, "sw_if_index %d", &sw_if_index))
12697         sw_if_index_set = 1;
12698       else
12699         break;
12700     }
12701
12702   if (sw_if_index_set == 0)
12703     {
12704       sw_if_index = ~0;
12705     }
12706
12707   if (!vam->json_output)
12708     {
12709       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12710              "sw_if_index", "src_address", "dst_address",
12711              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12712     }
12713
12714   /* Get list of vxlan-tunnel interfaces */
12715   M (VXLAN_TUNNEL_DUMP, mp);
12716
12717   mp->sw_if_index = htonl (sw_if_index);
12718
12719   S (mp);
12720
12721   /* Use a control ping for synchronization */
12722   MPING (CONTROL_PING, mp_ping);
12723   S (mp_ping);
12724
12725   W (ret);
12726   return ret;
12727 }
12728
12729 static uword unformat_geneve_decap_next
12730   (unformat_input_t * input, va_list * args)
12731 {
12732   u32 *result = va_arg (*args, u32 *);
12733   u32 tmp;
12734
12735   if (unformat (input, "l2"))
12736     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12737   else if (unformat (input, "%d", &tmp))
12738     *result = tmp;
12739   else
12740     return 0;
12741   return 1;
12742 }
12743
12744 static int
12745 api_geneve_add_del_tunnel (vat_main_t * vam)
12746 {
12747   unformat_input_t *line_input = vam->input;
12748   vl_api_geneve_add_del_tunnel_t *mp;
12749   ip46_address_t src, dst;
12750   u8 is_add = 1;
12751   u8 ipv4_set = 0, ipv6_set = 0;
12752   u8 src_set = 0;
12753   u8 dst_set = 0;
12754   u8 grp_set = 0;
12755   u32 mcast_sw_if_index = ~0;
12756   u32 encap_vrf_id = 0;
12757   u32 decap_next_index = ~0;
12758   u32 vni = 0;
12759   int ret;
12760
12761   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12762   memset (&src, 0, sizeof src);
12763   memset (&dst, 0, sizeof dst);
12764
12765   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12766     {
12767       if (unformat (line_input, "del"))
12768         is_add = 0;
12769       else
12770         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12771         {
12772           ipv4_set = 1;
12773           src_set = 1;
12774         }
12775       else
12776         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12777         {
12778           ipv4_set = 1;
12779           dst_set = 1;
12780         }
12781       else
12782         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12783         {
12784           ipv6_set = 1;
12785           src_set = 1;
12786         }
12787       else
12788         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12789         {
12790           ipv6_set = 1;
12791           dst_set = 1;
12792         }
12793       else if (unformat (line_input, "group %U %U",
12794                          unformat_ip4_address, &dst.ip4,
12795                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12796         {
12797           grp_set = dst_set = 1;
12798           ipv4_set = 1;
12799         }
12800       else if (unformat (line_input, "group %U",
12801                          unformat_ip4_address, &dst.ip4))
12802         {
12803           grp_set = dst_set = 1;
12804           ipv4_set = 1;
12805         }
12806       else if (unformat (line_input, "group %U %U",
12807                          unformat_ip6_address, &dst.ip6,
12808                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12809         {
12810           grp_set = dst_set = 1;
12811           ipv6_set = 1;
12812         }
12813       else if (unformat (line_input, "group %U",
12814                          unformat_ip6_address, &dst.ip6))
12815         {
12816           grp_set = dst_set = 1;
12817           ipv6_set = 1;
12818         }
12819       else
12820         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12821         ;
12822       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12823         ;
12824       else if (unformat (line_input, "decap-next %U",
12825                          unformat_geneve_decap_next, &decap_next_index))
12826         ;
12827       else if (unformat (line_input, "vni %d", &vni))
12828         ;
12829       else
12830         {
12831           errmsg ("parse error '%U'", format_unformat_error, line_input);
12832           return -99;
12833         }
12834     }
12835
12836   if (src_set == 0)
12837     {
12838       errmsg ("tunnel src address not specified");
12839       return -99;
12840     }
12841   if (dst_set == 0)
12842     {
12843       errmsg ("tunnel dst address not specified");
12844       return -99;
12845     }
12846
12847   if (grp_set && !ip46_address_is_multicast (&dst))
12848     {
12849       errmsg ("tunnel group address not multicast");
12850       return -99;
12851     }
12852   if (grp_set && mcast_sw_if_index == ~0)
12853     {
12854       errmsg ("tunnel nonexistent multicast device");
12855       return -99;
12856     }
12857   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12858     {
12859       errmsg ("tunnel dst address must be unicast");
12860       return -99;
12861     }
12862
12863
12864   if (ipv4_set && ipv6_set)
12865     {
12866       errmsg ("both IPv4 and IPv6 addresses specified");
12867       return -99;
12868     }
12869
12870   if ((vni == 0) || (vni >> 24))
12871     {
12872       errmsg ("vni not specified or out of range");
12873       return -99;
12874     }
12875
12876   M (GENEVE_ADD_DEL_TUNNEL, mp);
12877
12878   if (ipv6_set)
12879     {
12880       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12881       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12882     }
12883   else
12884     {
12885       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12886       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12887     }
12888   mp->encap_vrf_id = ntohl (encap_vrf_id);
12889   mp->decap_next_index = ntohl (decap_next_index);
12890   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12891   mp->vni = ntohl (vni);
12892   mp->is_add = is_add;
12893   mp->is_ipv6 = ipv6_set;
12894
12895   S (mp);
12896   W (ret);
12897   return ret;
12898 }
12899
12900 static void vl_api_geneve_tunnel_details_t_handler
12901   (vl_api_geneve_tunnel_details_t * mp)
12902 {
12903   vat_main_t *vam = &vat_main;
12904   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12905   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12906
12907   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12908          ntohl (mp->sw_if_index),
12909          format_ip46_address, &src, IP46_TYPE_ANY,
12910          format_ip46_address, &dst, IP46_TYPE_ANY,
12911          ntohl (mp->encap_vrf_id),
12912          ntohl (mp->decap_next_index), ntohl (mp->vni),
12913          ntohl (mp->mcast_sw_if_index));
12914 }
12915
12916 static void vl_api_geneve_tunnel_details_t_handler_json
12917   (vl_api_geneve_tunnel_details_t * mp)
12918 {
12919   vat_main_t *vam = &vat_main;
12920   vat_json_node_t *node = NULL;
12921
12922   if (VAT_JSON_ARRAY != vam->json_tree.type)
12923     {
12924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12925       vat_json_init_array (&vam->json_tree);
12926     }
12927   node = vat_json_array_add (&vam->json_tree);
12928
12929   vat_json_init_object (node);
12930   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12931   if (mp->is_ipv6)
12932     {
12933       struct in6_addr ip6;
12934
12935       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12936       vat_json_object_add_ip6 (node, "src_address", ip6);
12937       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12938       vat_json_object_add_ip6 (node, "dst_address", ip6);
12939     }
12940   else
12941     {
12942       struct in_addr ip4;
12943
12944       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12945       vat_json_object_add_ip4 (node, "src_address", ip4);
12946       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12947       vat_json_object_add_ip4 (node, "dst_address", ip4);
12948     }
12949   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12950   vat_json_object_add_uint (node, "decap_next_index",
12951                             ntohl (mp->decap_next_index));
12952   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12953   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12954   vat_json_object_add_uint (node, "mcast_sw_if_index",
12955                             ntohl (mp->mcast_sw_if_index));
12956 }
12957
12958 static int
12959 api_geneve_tunnel_dump (vat_main_t * vam)
12960 {
12961   unformat_input_t *i = vam->input;
12962   vl_api_geneve_tunnel_dump_t *mp;
12963   vl_api_control_ping_t *mp_ping;
12964   u32 sw_if_index;
12965   u8 sw_if_index_set = 0;
12966   int ret;
12967
12968   /* Parse args required to build the message */
12969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12970     {
12971       if (unformat (i, "sw_if_index %d", &sw_if_index))
12972         sw_if_index_set = 1;
12973       else
12974         break;
12975     }
12976
12977   if (sw_if_index_set == 0)
12978     {
12979       sw_if_index = ~0;
12980     }
12981
12982   if (!vam->json_output)
12983     {
12984       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12985              "sw_if_index", "local_address", "remote_address",
12986              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12987     }
12988
12989   /* Get list of geneve-tunnel interfaces */
12990   M (GENEVE_TUNNEL_DUMP, mp);
12991
12992   mp->sw_if_index = htonl (sw_if_index);
12993
12994   S (mp);
12995
12996   /* Use a control ping for synchronization */
12997   M (CONTROL_PING, mp_ping);
12998   S (mp_ping);
12999
13000   W (ret);
13001   return ret;
13002 }
13003
13004 static int
13005 api_gre_add_del_tunnel (vat_main_t * vam)
13006 {
13007   unformat_input_t *line_input = vam->input;
13008   vl_api_gre_add_del_tunnel_t *mp;
13009   ip4_address_t src4, dst4;
13010   ip6_address_t src6, dst6;
13011   u8 is_add = 1;
13012   u8 ipv4_set = 0;
13013   u8 ipv6_set = 0;
13014   u8 teb = 0;
13015   u8 src_set = 0;
13016   u8 dst_set = 0;
13017   u32 outer_fib_id = 0;
13018   int ret;
13019
13020   memset (&src4, 0, sizeof src4);
13021   memset (&dst4, 0, sizeof dst4);
13022   memset (&src6, 0, sizeof src6);
13023   memset (&dst6, 0, sizeof dst6);
13024
13025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (line_input, "del"))
13028         is_add = 0;
13029       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13030         {
13031           src_set = 1;
13032           ipv4_set = 1;
13033         }
13034       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13035         {
13036           dst_set = 1;
13037           ipv4_set = 1;
13038         }
13039       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13040         {
13041           src_set = 1;
13042           ipv6_set = 1;
13043         }
13044       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13045         {
13046           dst_set = 1;
13047           ipv6_set = 1;
13048         }
13049       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13050         ;
13051       else if (unformat (line_input, "teb"))
13052         teb = 1;
13053       else
13054         {
13055           errmsg ("parse error '%U'", format_unformat_error, line_input);
13056           return -99;
13057         }
13058     }
13059
13060   if (src_set == 0)
13061     {
13062       errmsg ("tunnel src address not specified");
13063       return -99;
13064     }
13065   if (dst_set == 0)
13066     {
13067       errmsg ("tunnel dst address not specified");
13068       return -99;
13069     }
13070   if (ipv4_set && ipv6_set)
13071     {
13072       errmsg ("both IPv4 and IPv6 addresses specified");
13073       return -99;
13074     }
13075
13076
13077   M (GRE_ADD_DEL_TUNNEL, mp);
13078
13079   if (ipv4_set)
13080     {
13081       clib_memcpy (&mp->src_address, &src4, 4);
13082       clib_memcpy (&mp->dst_address, &dst4, 4);
13083     }
13084   else
13085     {
13086       clib_memcpy (&mp->src_address, &src6, 16);
13087       clib_memcpy (&mp->dst_address, &dst6, 16);
13088     }
13089   mp->outer_fib_id = ntohl (outer_fib_id);
13090   mp->is_add = is_add;
13091   mp->teb = teb;
13092   mp->is_ipv6 = ipv6_set;
13093
13094   S (mp);
13095   W (ret);
13096   return ret;
13097 }
13098
13099 static void vl_api_gre_tunnel_details_t_handler
13100   (vl_api_gre_tunnel_details_t * mp)
13101 {
13102   vat_main_t *vam = &vat_main;
13103   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13104   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13105
13106   print (vam->ofp, "%11d%24U%24U%6d%14d",
13107          ntohl (mp->sw_if_index),
13108          format_ip46_address, &src, IP46_TYPE_ANY,
13109          format_ip46_address, &dst, IP46_TYPE_ANY,
13110          mp->teb, ntohl (mp->outer_fib_id));
13111 }
13112
13113 static void vl_api_gre_tunnel_details_t_handler_json
13114   (vl_api_gre_tunnel_details_t * mp)
13115 {
13116   vat_main_t *vam = &vat_main;
13117   vat_json_node_t *node = NULL;
13118   struct in_addr ip4;
13119   struct in6_addr ip6;
13120
13121   if (VAT_JSON_ARRAY != vam->json_tree.type)
13122     {
13123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13124       vat_json_init_array (&vam->json_tree);
13125     }
13126   node = vat_json_array_add (&vam->json_tree);
13127
13128   vat_json_init_object (node);
13129   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13130   if (!mp->is_ipv6)
13131     {
13132       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13133       vat_json_object_add_ip4 (node, "src_address", ip4);
13134       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13135       vat_json_object_add_ip4 (node, "dst_address", ip4);
13136     }
13137   else
13138     {
13139       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13140       vat_json_object_add_ip6 (node, "src_address", ip6);
13141       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13142       vat_json_object_add_ip6 (node, "dst_address", ip6);
13143     }
13144   vat_json_object_add_uint (node, "teb", mp->teb);
13145   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13146   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13147 }
13148
13149 static int
13150 api_gre_tunnel_dump (vat_main_t * vam)
13151 {
13152   unformat_input_t *i = vam->input;
13153   vl_api_gre_tunnel_dump_t *mp;
13154   vl_api_control_ping_t *mp_ping;
13155   u32 sw_if_index;
13156   u8 sw_if_index_set = 0;
13157   int ret;
13158
13159   /* Parse args required to build the message */
13160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13161     {
13162       if (unformat (i, "sw_if_index %d", &sw_if_index))
13163         sw_if_index_set = 1;
13164       else
13165         break;
13166     }
13167
13168   if (sw_if_index_set == 0)
13169     {
13170       sw_if_index = ~0;
13171     }
13172
13173   if (!vam->json_output)
13174     {
13175       print (vam->ofp, "%11s%24s%24s%6s%14s",
13176              "sw_if_index", "src_address", "dst_address", "teb",
13177              "outer_fib_id");
13178     }
13179
13180   /* Get list of gre-tunnel interfaces */
13181   M (GRE_TUNNEL_DUMP, mp);
13182
13183   mp->sw_if_index = htonl (sw_if_index);
13184
13185   S (mp);
13186
13187   /* Use a control ping for synchronization */
13188   MPING (CONTROL_PING, mp_ping);
13189   S (mp_ping);
13190
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_l2_fib_clear_table (vat_main_t * vam)
13197 {
13198 //  unformat_input_t * i = vam->input;
13199   vl_api_l2_fib_clear_table_t *mp;
13200   int ret;
13201
13202   M (L2_FIB_CLEAR_TABLE, mp);
13203
13204   S (mp);
13205   W (ret);
13206   return ret;
13207 }
13208
13209 static int
13210 api_l2_interface_efp_filter (vat_main_t * vam)
13211 {
13212   unformat_input_t *i = vam->input;
13213   vl_api_l2_interface_efp_filter_t *mp;
13214   u32 sw_if_index;
13215   u8 enable = 1;
13216   u8 sw_if_index_set = 0;
13217   int ret;
13218
13219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13220     {
13221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13222         sw_if_index_set = 1;
13223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13224         sw_if_index_set = 1;
13225       else if (unformat (i, "enable"))
13226         enable = 1;
13227       else if (unformat (i, "disable"))
13228         enable = 0;
13229       else
13230         {
13231           clib_warning ("parse error '%U'", format_unformat_error, i);
13232           return -99;
13233         }
13234     }
13235
13236   if (sw_if_index_set == 0)
13237     {
13238       errmsg ("missing sw_if_index");
13239       return -99;
13240     }
13241
13242   M (L2_INTERFACE_EFP_FILTER, mp);
13243
13244   mp->sw_if_index = ntohl (sw_if_index);
13245   mp->enable_disable = enable;
13246
13247   S (mp);
13248   W (ret);
13249   return ret;
13250 }
13251
13252 #define foreach_vtr_op                          \
13253 _("disable",  L2_VTR_DISABLED)                  \
13254 _("push-1",  L2_VTR_PUSH_1)                     \
13255 _("push-2",  L2_VTR_PUSH_2)                     \
13256 _("pop-1",  L2_VTR_POP_1)                       \
13257 _("pop-2",  L2_VTR_POP_2)                       \
13258 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13259 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13260 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13261 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13262
13263 static int
13264 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13265 {
13266   unformat_input_t *i = vam->input;
13267   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13268   u32 sw_if_index;
13269   u8 sw_if_index_set = 0;
13270   u8 vtr_op_set = 0;
13271   u32 vtr_op = 0;
13272   u32 push_dot1q = 1;
13273   u32 tag1 = ~0;
13274   u32 tag2 = ~0;
13275   int ret;
13276
13277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13278     {
13279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13280         sw_if_index_set = 1;
13281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13282         sw_if_index_set = 1;
13283       else if (unformat (i, "vtr_op %d", &vtr_op))
13284         vtr_op_set = 1;
13285 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13286       foreach_vtr_op
13287 #undef _
13288         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13289         ;
13290       else if (unformat (i, "tag1 %d", &tag1))
13291         ;
13292       else if (unformat (i, "tag2 %d", &tag2))
13293         ;
13294       else
13295         {
13296           clib_warning ("parse error '%U'", format_unformat_error, i);
13297           return -99;
13298         }
13299     }
13300
13301   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13302     {
13303       errmsg ("missing vtr operation or sw_if_index");
13304       return -99;
13305     }
13306
13307   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13308   mp->sw_if_index = ntohl (sw_if_index);
13309   mp->vtr_op = ntohl (vtr_op);
13310   mp->push_dot1q = ntohl (push_dot1q);
13311   mp->tag1 = ntohl (tag1);
13312   mp->tag2 = ntohl (tag2);
13313
13314   S (mp);
13315   W (ret);
13316   return ret;
13317 }
13318
13319 static int
13320 api_create_vhost_user_if (vat_main_t * vam)
13321 {
13322   unformat_input_t *i = vam->input;
13323   vl_api_create_vhost_user_if_t *mp;
13324   u8 *file_name;
13325   u8 is_server = 0;
13326   u8 file_name_set = 0;
13327   u32 custom_dev_instance = ~0;
13328   u8 hwaddr[6];
13329   u8 use_custom_mac = 0;
13330   u8 *tag = 0;
13331   int ret;
13332
13333   /* Shut up coverity */
13334   memset (hwaddr, 0, sizeof (hwaddr));
13335
13336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13337     {
13338       if (unformat (i, "socket %s", &file_name))
13339         {
13340           file_name_set = 1;
13341         }
13342       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13343         ;
13344       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13345         use_custom_mac = 1;
13346       else if (unformat (i, "server"))
13347         is_server = 1;
13348       else if (unformat (i, "tag %s", &tag))
13349         ;
13350       else
13351         break;
13352     }
13353
13354   if (file_name_set == 0)
13355     {
13356       errmsg ("missing socket file name");
13357       return -99;
13358     }
13359
13360   if (vec_len (file_name) > 255)
13361     {
13362       errmsg ("socket file name too long");
13363       return -99;
13364     }
13365   vec_add1 (file_name, 0);
13366
13367   M (CREATE_VHOST_USER_IF, mp);
13368
13369   mp->is_server = is_server;
13370   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13371   vec_free (file_name);
13372   if (custom_dev_instance != ~0)
13373     {
13374       mp->renumber = 1;
13375       mp->custom_dev_instance = ntohl (custom_dev_instance);
13376     }
13377   mp->use_custom_mac = use_custom_mac;
13378   clib_memcpy (mp->mac_address, hwaddr, 6);
13379   if (tag)
13380     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13381   vec_free (tag);
13382
13383   S (mp);
13384   W (ret);
13385   return ret;
13386 }
13387
13388 static int
13389 api_modify_vhost_user_if (vat_main_t * vam)
13390 {
13391   unformat_input_t *i = vam->input;
13392   vl_api_modify_vhost_user_if_t *mp;
13393   u8 *file_name;
13394   u8 is_server = 0;
13395   u8 file_name_set = 0;
13396   u32 custom_dev_instance = ~0;
13397   u8 sw_if_index_set = 0;
13398   u32 sw_if_index = (u32) ~ 0;
13399   int ret;
13400
13401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13402     {
13403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13404         sw_if_index_set = 1;
13405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13406         sw_if_index_set = 1;
13407       else if (unformat (i, "socket %s", &file_name))
13408         {
13409           file_name_set = 1;
13410         }
13411       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13412         ;
13413       else if (unformat (i, "server"))
13414         is_server = 1;
13415       else
13416         break;
13417     }
13418
13419   if (sw_if_index_set == 0)
13420     {
13421       errmsg ("missing sw_if_index or interface name");
13422       return -99;
13423     }
13424
13425   if (file_name_set == 0)
13426     {
13427       errmsg ("missing socket file name");
13428       return -99;
13429     }
13430
13431   if (vec_len (file_name) > 255)
13432     {
13433       errmsg ("socket file name too long");
13434       return -99;
13435     }
13436   vec_add1 (file_name, 0);
13437
13438   M (MODIFY_VHOST_USER_IF, mp);
13439
13440   mp->sw_if_index = ntohl (sw_if_index);
13441   mp->is_server = is_server;
13442   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13443   vec_free (file_name);
13444   if (custom_dev_instance != ~0)
13445     {
13446       mp->renumber = 1;
13447       mp->custom_dev_instance = ntohl (custom_dev_instance);
13448     }
13449
13450   S (mp);
13451   W (ret);
13452   return ret;
13453 }
13454
13455 static int
13456 api_delete_vhost_user_if (vat_main_t * vam)
13457 {
13458   unformat_input_t *i = vam->input;
13459   vl_api_delete_vhost_user_if_t *mp;
13460   u32 sw_if_index = ~0;
13461   u8 sw_if_index_set = 0;
13462   int ret;
13463
13464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13465     {
13466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13467         sw_if_index_set = 1;
13468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13469         sw_if_index_set = 1;
13470       else
13471         break;
13472     }
13473
13474   if (sw_if_index_set == 0)
13475     {
13476       errmsg ("missing sw_if_index or interface name");
13477       return -99;
13478     }
13479
13480
13481   M (DELETE_VHOST_USER_IF, mp);
13482
13483   mp->sw_if_index = ntohl (sw_if_index);
13484
13485   S (mp);
13486   W (ret);
13487   return ret;
13488 }
13489
13490 static void vl_api_sw_interface_vhost_user_details_t_handler
13491   (vl_api_sw_interface_vhost_user_details_t * mp)
13492 {
13493   vat_main_t *vam = &vat_main;
13494
13495   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13496          (char *) mp->interface_name,
13497          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13498          clib_net_to_host_u64 (mp->features), mp->is_server,
13499          ntohl (mp->num_regions), (char *) mp->sock_filename);
13500   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13501 }
13502
13503 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13504   (vl_api_sw_interface_vhost_user_details_t * mp)
13505 {
13506   vat_main_t *vam = &vat_main;
13507   vat_json_node_t *node = NULL;
13508
13509   if (VAT_JSON_ARRAY != vam->json_tree.type)
13510     {
13511       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13512       vat_json_init_array (&vam->json_tree);
13513     }
13514   node = vat_json_array_add (&vam->json_tree);
13515
13516   vat_json_init_object (node);
13517   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13518   vat_json_object_add_string_copy (node, "interface_name",
13519                                    mp->interface_name);
13520   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13521                             ntohl (mp->virtio_net_hdr_sz));
13522   vat_json_object_add_uint (node, "features",
13523                             clib_net_to_host_u64 (mp->features));
13524   vat_json_object_add_uint (node, "is_server", mp->is_server);
13525   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13526   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13527   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13528 }
13529
13530 static int
13531 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13532 {
13533   vl_api_sw_interface_vhost_user_dump_t *mp;
13534   vl_api_control_ping_t *mp_ping;
13535   int ret;
13536   print (vam->ofp,
13537          "Interface name            idx hdr_sz features server regions filename");
13538
13539   /* Get list of vhost-user interfaces */
13540   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13541   S (mp);
13542
13543   /* Use a control ping for synchronization */
13544   MPING (CONTROL_PING, mp_ping);
13545   S (mp_ping);
13546
13547   W (ret);
13548   return ret;
13549 }
13550
13551 static int
13552 api_show_version (vat_main_t * vam)
13553 {
13554   vl_api_show_version_t *mp;
13555   int ret;
13556
13557   M (SHOW_VERSION, mp);
13558
13559   S (mp);
13560   W (ret);
13561   return ret;
13562 }
13563
13564
13565 static int
13566 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13567 {
13568   unformat_input_t *line_input = vam->input;
13569   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13570   ip4_address_t local4, remote4;
13571   ip6_address_t local6, remote6;
13572   u8 is_add = 1;
13573   u8 ipv4_set = 0, ipv6_set = 0;
13574   u8 local_set = 0;
13575   u8 remote_set = 0;
13576   u8 grp_set = 0;
13577   u32 mcast_sw_if_index = ~0;
13578   u32 encap_vrf_id = 0;
13579   u32 decap_vrf_id = 0;
13580   u8 protocol = ~0;
13581   u32 vni;
13582   u8 vni_set = 0;
13583   int ret;
13584
13585   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13586   memset (&local4, 0, sizeof local4);
13587   memset (&remote4, 0, sizeof remote4);
13588   memset (&local6, 0, sizeof local6);
13589   memset (&remote6, 0, sizeof remote6);
13590
13591   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13592     {
13593       if (unformat (line_input, "del"))
13594         is_add = 0;
13595       else if (unformat (line_input, "local %U",
13596                          unformat_ip4_address, &local4))
13597         {
13598           local_set = 1;
13599           ipv4_set = 1;
13600         }
13601       else if (unformat (line_input, "remote %U",
13602                          unformat_ip4_address, &remote4))
13603         {
13604           remote_set = 1;
13605           ipv4_set = 1;
13606         }
13607       else if (unformat (line_input, "local %U",
13608                          unformat_ip6_address, &local6))
13609         {
13610           local_set = 1;
13611           ipv6_set = 1;
13612         }
13613       else if (unformat (line_input, "remote %U",
13614                          unformat_ip6_address, &remote6))
13615         {
13616           remote_set = 1;
13617           ipv6_set = 1;
13618         }
13619       else if (unformat (line_input, "group %U %U",
13620                          unformat_ip4_address, &remote4,
13621                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13622         {
13623           grp_set = remote_set = 1;
13624           ipv4_set = 1;
13625         }
13626       else if (unformat (line_input, "group %U",
13627                          unformat_ip4_address, &remote4))
13628         {
13629           grp_set = remote_set = 1;
13630           ipv4_set = 1;
13631         }
13632       else if (unformat (line_input, "group %U %U",
13633                          unformat_ip6_address, &remote6,
13634                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13635         {
13636           grp_set = remote_set = 1;
13637           ipv6_set = 1;
13638         }
13639       else if (unformat (line_input, "group %U",
13640                          unformat_ip6_address, &remote6))
13641         {
13642           grp_set = remote_set = 1;
13643           ipv6_set = 1;
13644         }
13645       else
13646         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13647         ;
13648       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13649         ;
13650       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13651         ;
13652       else if (unformat (line_input, "vni %d", &vni))
13653         vni_set = 1;
13654       else if (unformat (line_input, "next-ip4"))
13655         protocol = 1;
13656       else if (unformat (line_input, "next-ip6"))
13657         protocol = 2;
13658       else if (unformat (line_input, "next-ethernet"))
13659         protocol = 3;
13660       else if (unformat (line_input, "next-nsh"))
13661         protocol = 4;
13662       else
13663         {
13664           errmsg ("parse error '%U'", format_unformat_error, line_input);
13665           return -99;
13666         }
13667     }
13668
13669   if (local_set == 0)
13670     {
13671       errmsg ("tunnel local address not specified");
13672       return -99;
13673     }
13674   if (remote_set == 0)
13675     {
13676       errmsg ("tunnel remote address not specified");
13677       return -99;
13678     }
13679   if (grp_set && mcast_sw_if_index == ~0)
13680     {
13681       errmsg ("tunnel nonexistent multicast device");
13682       return -99;
13683     }
13684   if (ipv4_set && ipv6_set)
13685     {
13686       errmsg ("both IPv4 and IPv6 addresses specified");
13687       return -99;
13688     }
13689
13690   if (vni_set == 0)
13691     {
13692       errmsg ("vni not specified");
13693       return -99;
13694     }
13695
13696   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13697
13698
13699   if (ipv6_set)
13700     {
13701       clib_memcpy (&mp->local, &local6, sizeof (local6));
13702       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13703     }
13704   else
13705     {
13706       clib_memcpy (&mp->local, &local4, sizeof (local4));
13707       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13708     }
13709
13710   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13711   mp->encap_vrf_id = ntohl (encap_vrf_id);
13712   mp->decap_vrf_id = ntohl (decap_vrf_id);
13713   mp->protocol = protocol;
13714   mp->vni = ntohl (vni);
13715   mp->is_add = is_add;
13716   mp->is_ipv6 = ipv6_set;
13717
13718   S (mp);
13719   W (ret);
13720   return ret;
13721 }
13722
13723 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13724   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13725 {
13726   vat_main_t *vam = &vat_main;
13727   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13728   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13729
13730   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13731          ntohl (mp->sw_if_index),
13732          format_ip46_address, &local, IP46_TYPE_ANY,
13733          format_ip46_address, &remote, IP46_TYPE_ANY,
13734          ntohl (mp->vni), mp->protocol,
13735          ntohl (mp->mcast_sw_if_index),
13736          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13737 }
13738
13739
13740 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13741   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13742 {
13743   vat_main_t *vam = &vat_main;
13744   vat_json_node_t *node = NULL;
13745   struct in_addr ip4;
13746   struct in6_addr ip6;
13747
13748   if (VAT_JSON_ARRAY != vam->json_tree.type)
13749     {
13750       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13751       vat_json_init_array (&vam->json_tree);
13752     }
13753   node = vat_json_array_add (&vam->json_tree);
13754
13755   vat_json_init_object (node);
13756   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13757   if (mp->is_ipv6)
13758     {
13759       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13760       vat_json_object_add_ip6 (node, "local", ip6);
13761       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13762       vat_json_object_add_ip6 (node, "remote", ip6);
13763     }
13764   else
13765     {
13766       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13767       vat_json_object_add_ip4 (node, "local", ip4);
13768       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13769       vat_json_object_add_ip4 (node, "remote", ip4);
13770     }
13771   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13772   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13773   vat_json_object_add_uint (node, "mcast_sw_if_index",
13774                             ntohl (mp->mcast_sw_if_index));
13775   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13776   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13777   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13778 }
13779
13780 static int
13781 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13782 {
13783   unformat_input_t *i = vam->input;
13784   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13785   vl_api_control_ping_t *mp_ping;
13786   u32 sw_if_index;
13787   u8 sw_if_index_set = 0;
13788   int ret;
13789
13790   /* Parse args required to build the message */
13791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13792     {
13793       if (unformat (i, "sw_if_index %d", &sw_if_index))
13794         sw_if_index_set = 1;
13795       else
13796         break;
13797     }
13798
13799   if (sw_if_index_set == 0)
13800     {
13801       sw_if_index = ~0;
13802     }
13803
13804   if (!vam->json_output)
13805     {
13806       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13807              "sw_if_index", "local", "remote", "vni",
13808              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13809     }
13810
13811   /* Get list of vxlan-tunnel interfaces */
13812   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13813
13814   mp->sw_if_index = htonl (sw_if_index);
13815
13816   S (mp);
13817
13818   /* Use a control ping for synchronization */
13819   MPING (CONTROL_PING, mp_ping);
13820   S (mp_ping);
13821
13822   W (ret);
13823   return ret;
13824 }
13825
13826 static void vl_api_l2_fib_table_details_t_handler
13827   (vl_api_l2_fib_table_details_t * mp)
13828 {
13829   vat_main_t *vam = &vat_main;
13830
13831   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13832          "       %d       %d     %d",
13833          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13834          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13835          mp->bvi_mac);
13836 }
13837
13838 static void vl_api_l2_fib_table_details_t_handler_json
13839   (vl_api_l2_fib_table_details_t * mp)
13840 {
13841   vat_main_t *vam = &vat_main;
13842   vat_json_node_t *node = NULL;
13843
13844   if (VAT_JSON_ARRAY != vam->json_tree.type)
13845     {
13846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13847       vat_json_init_array (&vam->json_tree);
13848     }
13849   node = vat_json_array_add (&vam->json_tree);
13850
13851   vat_json_init_object (node);
13852   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13853   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13855   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13856   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13857   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13858 }
13859
13860 static int
13861 api_l2_fib_table_dump (vat_main_t * vam)
13862 {
13863   unformat_input_t *i = vam->input;
13864   vl_api_l2_fib_table_dump_t *mp;
13865   vl_api_control_ping_t *mp_ping;
13866   u32 bd_id;
13867   u8 bd_id_set = 0;
13868   int ret;
13869
13870   /* Parse args required to build the message */
13871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13872     {
13873       if (unformat (i, "bd_id %d", &bd_id))
13874         bd_id_set = 1;
13875       else
13876         break;
13877     }
13878
13879   if (bd_id_set == 0)
13880     {
13881       errmsg ("missing bridge domain");
13882       return -99;
13883     }
13884
13885   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13886
13887   /* Get list of l2 fib entries */
13888   M (L2_FIB_TABLE_DUMP, mp);
13889
13890   mp->bd_id = ntohl (bd_id);
13891   S (mp);
13892
13893   /* Use a control ping for synchronization */
13894   MPING (CONTROL_PING, mp_ping);
13895   S (mp_ping);
13896
13897   W (ret);
13898   return ret;
13899 }
13900
13901
13902 static int
13903 api_interface_name_renumber (vat_main_t * vam)
13904 {
13905   unformat_input_t *line_input = vam->input;
13906   vl_api_interface_name_renumber_t *mp;
13907   u32 sw_if_index = ~0;
13908   u32 new_show_dev_instance = ~0;
13909   int ret;
13910
13911   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13912     {
13913       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13914                     &sw_if_index))
13915         ;
13916       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13917         ;
13918       else if (unformat (line_input, "new_show_dev_instance %d",
13919                          &new_show_dev_instance))
13920         ;
13921       else
13922         break;
13923     }
13924
13925   if (sw_if_index == ~0)
13926     {
13927       errmsg ("missing interface name or sw_if_index");
13928       return -99;
13929     }
13930
13931   if (new_show_dev_instance == ~0)
13932     {
13933       errmsg ("missing new_show_dev_instance");
13934       return -99;
13935     }
13936
13937   M (INTERFACE_NAME_RENUMBER, mp);
13938
13939   mp->sw_if_index = ntohl (sw_if_index);
13940   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13941
13942   S (mp);
13943   W (ret);
13944   return ret;
13945 }
13946
13947 static int
13948 api_want_ip4_arp_events (vat_main_t * vam)
13949 {
13950   unformat_input_t *line_input = vam->input;
13951   vl_api_want_ip4_arp_events_t *mp;
13952   ip4_address_t address;
13953   int address_set = 0;
13954   u32 enable_disable = 1;
13955   int ret;
13956
13957   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13960         address_set = 1;
13961       else if (unformat (line_input, "del"))
13962         enable_disable = 0;
13963       else
13964         break;
13965     }
13966
13967   if (address_set == 0)
13968     {
13969       errmsg ("missing addresses");
13970       return -99;
13971     }
13972
13973   M (WANT_IP4_ARP_EVENTS, mp);
13974   mp->enable_disable = enable_disable;
13975   mp->pid = htonl (getpid ());
13976   mp->address = address.as_u32;
13977
13978   S (mp);
13979   W (ret);
13980   return ret;
13981 }
13982
13983 static int
13984 api_want_ip6_nd_events (vat_main_t * vam)
13985 {
13986   unformat_input_t *line_input = vam->input;
13987   vl_api_want_ip6_nd_events_t *mp;
13988   ip6_address_t address;
13989   int address_set = 0;
13990   u32 enable_disable = 1;
13991   int ret;
13992
13993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13994     {
13995       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13996         address_set = 1;
13997       else if (unformat (line_input, "del"))
13998         enable_disable = 0;
13999       else
14000         break;
14001     }
14002
14003   if (address_set == 0)
14004     {
14005       errmsg ("missing addresses");
14006       return -99;
14007     }
14008
14009   M (WANT_IP6_ND_EVENTS, mp);
14010   mp->enable_disable = enable_disable;
14011   mp->pid = htonl (getpid ());
14012   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14013
14014   S (mp);
14015   W (ret);
14016   return ret;
14017 }
14018
14019 static int
14020 api_want_l2_macs_events (vat_main_t * vam)
14021 {
14022   unformat_input_t *line_input = vam->input;
14023   vl_api_want_l2_macs_events_t *mp;
14024   u8 enable_disable = 1;
14025   u32 scan_delay = 0;
14026   u32 max_macs_in_event = 0;
14027   u32 learn_limit = 0;
14028   int ret;
14029
14030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (line_input, "learn-limit %d", &learn_limit))
14033         ;
14034       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14035         ;
14036       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14037         ;
14038       else if (unformat (line_input, "disable"))
14039         enable_disable = 0;
14040       else
14041         break;
14042     }
14043
14044   M (WANT_L2_MACS_EVENTS, mp);
14045   mp->enable_disable = enable_disable;
14046   mp->pid = htonl (getpid ());
14047   mp->learn_limit = htonl (learn_limit);
14048   mp->scan_delay = (u8) scan_delay;
14049   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14050   S (mp);
14051   W (ret);
14052   return ret;
14053 }
14054
14055 static int
14056 api_input_acl_set_interface (vat_main_t * vam)
14057 {
14058   unformat_input_t *i = vam->input;
14059   vl_api_input_acl_set_interface_t *mp;
14060   u32 sw_if_index;
14061   int sw_if_index_set;
14062   u32 ip4_table_index = ~0;
14063   u32 ip6_table_index = ~0;
14064   u32 l2_table_index = ~0;
14065   u8 is_add = 1;
14066   int ret;
14067
14068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14069     {
14070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14071         sw_if_index_set = 1;
14072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14073         sw_if_index_set = 1;
14074       else if (unformat (i, "del"))
14075         is_add = 0;
14076       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14077         ;
14078       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14079         ;
14080       else if (unformat (i, "l2-table %d", &l2_table_index))
14081         ;
14082       else
14083         {
14084           clib_warning ("parse error '%U'", format_unformat_error, i);
14085           return -99;
14086         }
14087     }
14088
14089   if (sw_if_index_set == 0)
14090     {
14091       errmsg ("missing interface name or sw_if_index");
14092       return -99;
14093     }
14094
14095   M (INPUT_ACL_SET_INTERFACE, mp);
14096
14097   mp->sw_if_index = ntohl (sw_if_index);
14098   mp->ip4_table_index = ntohl (ip4_table_index);
14099   mp->ip6_table_index = ntohl (ip6_table_index);
14100   mp->l2_table_index = ntohl (l2_table_index);
14101   mp->is_add = is_add;
14102
14103   S (mp);
14104   W (ret);
14105   return ret;
14106 }
14107
14108 static int
14109 api_ip_address_dump (vat_main_t * vam)
14110 {
14111   unformat_input_t *i = vam->input;
14112   vl_api_ip_address_dump_t *mp;
14113   vl_api_control_ping_t *mp_ping;
14114   u32 sw_if_index = ~0;
14115   u8 sw_if_index_set = 0;
14116   u8 ipv4_set = 0;
14117   u8 ipv6_set = 0;
14118   int ret;
14119
14120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14121     {
14122       if (unformat (i, "sw_if_index %d", &sw_if_index))
14123         sw_if_index_set = 1;
14124       else
14125         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14126         sw_if_index_set = 1;
14127       else if (unformat (i, "ipv4"))
14128         ipv4_set = 1;
14129       else if (unformat (i, "ipv6"))
14130         ipv6_set = 1;
14131       else
14132         break;
14133     }
14134
14135   if (ipv4_set && ipv6_set)
14136     {
14137       errmsg ("ipv4 and ipv6 flags cannot be both set");
14138       return -99;
14139     }
14140
14141   if ((!ipv4_set) && (!ipv6_set))
14142     {
14143       errmsg ("no ipv4 nor ipv6 flag set");
14144       return -99;
14145     }
14146
14147   if (sw_if_index_set == 0)
14148     {
14149       errmsg ("missing interface name or sw_if_index");
14150       return -99;
14151     }
14152
14153   vam->current_sw_if_index = sw_if_index;
14154   vam->is_ipv6 = ipv6_set;
14155
14156   M (IP_ADDRESS_DUMP, mp);
14157   mp->sw_if_index = ntohl (sw_if_index);
14158   mp->is_ipv6 = ipv6_set;
14159   S (mp);
14160
14161   /* Use a control ping for synchronization */
14162   MPING (CONTROL_PING, mp_ping);
14163   S (mp_ping);
14164
14165   W (ret);
14166   return ret;
14167 }
14168
14169 static int
14170 api_ip_dump (vat_main_t * vam)
14171 {
14172   vl_api_ip_dump_t *mp;
14173   vl_api_control_ping_t *mp_ping;
14174   unformat_input_t *in = vam->input;
14175   int ipv4_set = 0;
14176   int ipv6_set = 0;
14177   int is_ipv6;
14178   int i;
14179   int ret;
14180
14181   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14182     {
14183       if (unformat (in, "ipv4"))
14184         ipv4_set = 1;
14185       else if (unformat (in, "ipv6"))
14186         ipv6_set = 1;
14187       else
14188         break;
14189     }
14190
14191   if (ipv4_set && ipv6_set)
14192     {
14193       errmsg ("ipv4 and ipv6 flags cannot be both set");
14194       return -99;
14195     }
14196
14197   if ((!ipv4_set) && (!ipv6_set))
14198     {
14199       errmsg ("no ipv4 nor ipv6 flag set");
14200       return -99;
14201     }
14202
14203   is_ipv6 = ipv6_set;
14204   vam->is_ipv6 = is_ipv6;
14205
14206   /* free old data */
14207   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14208     {
14209       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14210     }
14211   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14212
14213   M (IP_DUMP, mp);
14214   mp->is_ipv6 = ipv6_set;
14215   S (mp);
14216
14217   /* Use a control ping for synchronization */
14218   MPING (CONTROL_PING, mp_ping);
14219   S (mp_ping);
14220
14221   W (ret);
14222   return ret;
14223 }
14224
14225 static int
14226 api_ipsec_spd_add_del (vat_main_t * vam)
14227 {
14228   unformat_input_t *i = vam->input;
14229   vl_api_ipsec_spd_add_del_t *mp;
14230   u32 spd_id = ~0;
14231   u8 is_add = 1;
14232   int ret;
14233
14234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14235     {
14236       if (unformat (i, "spd_id %d", &spd_id))
14237         ;
14238       else if (unformat (i, "del"))
14239         is_add = 0;
14240       else
14241         {
14242           clib_warning ("parse error '%U'", format_unformat_error, i);
14243           return -99;
14244         }
14245     }
14246   if (spd_id == ~0)
14247     {
14248       errmsg ("spd_id must be set");
14249       return -99;
14250     }
14251
14252   M (IPSEC_SPD_ADD_DEL, mp);
14253
14254   mp->spd_id = ntohl (spd_id);
14255   mp->is_add = is_add;
14256
14257   S (mp);
14258   W (ret);
14259   return ret;
14260 }
14261
14262 static int
14263 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14264 {
14265   unformat_input_t *i = vam->input;
14266   vl_api_ipsec_interface_add_del_spd_t *mp;
14267   u32 sw_if_index;
14268   u8 sw_if_index_set = 0;
14269   u32 spd_id = (u32) ~ 0;
14270   u8 is_add = 1;
14271   int ret;
14272
14273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14274     {
14275       if (unformat (i, "del"))
14276         is_add = 0;
14277       else if (unformat (i, "spd_id %d", &spd_id))
14278         ;
14279       else
14280         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14281         sw_if_index_set = 1;
14282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14283         sw_if_index_set = 1;
14284       else
14285         {
14286           clib_warning ("parse error '%U'", format_unformat_error, i);
14287           return -99;
14288         }
14289
14290     }
14291
14292   if (spd_id == (u32) ~ 0)
14293     {
14294       errmsg ("spd_id must be set");
14295       return -99;
14296     }
14297
14298   if (sw_if_index_set == 0)
14299     {
14300       errmsg ("missing interface name or sw_if_index");
14301       return -99;
14302     }
14303
14304   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14305
14306   mp->spd_id = ntohl (spd_id);
14307   mp->sw_if_index = ntohl (sw_if_index);
14308   mp->is_add = is_add;
14309
14310   S (mp);
14311   W (ret);
14312   return ret;
14313 }
14314
14315 static int
14316 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14317 {
14318   unformat_input_t *i = vam->input;
14319   vl_api_ipsec_spd_add_del_entry_t *mp;
14320   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14321   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14322   i32 priority = 0;
14323   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14324   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14325   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14326   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14327   int ret;
14328
14329   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14330   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14331   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14332   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14333   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14334   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14335
14336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14337     {
14338       if (unformat (i, "del"))
14339         is_add = 0;
14340       if (unformat (i, "outbound"))
14341         is_outbound = 1;
14342       if (unformat (i, "inbound"))
14343         is_outbound = 0;
14344       else if (unformat (i, "spd_id %d", &spd_id))
14345         ;
14346       else if (unformat (i, "sa_id %d", &sa_id))
14347         ;
14348       else if (unformat (i, "priority %d", &priority))
14349         ;
14350       else if (unformat (i, "protocol %d", &protocol))
14351         ;
14352       else if (unformat (i, "lport_start %d", &lport_start))
14353         ;
14354       else if (unformat (i, "lport_stop %d", &lport_stop))
14355         ;
14356       else if (unformat (i, "rport_start %d", &rport_start))
14357         ;
14358       else if (unformat (i, "rport_stop %d", &rport_stop))
14359         ;
14360       else
14361         if (unformat
14362             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14363         {
14364           is_ipv6 = 0;
14365           is_ip_any = 0;
14366         }
14367       else
14368         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14369         {
14370           is_ipv6 = 0;
14371           is_ip_any = 0;
14372         }
14373       else
14374         if (unformat
14375             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14376         {
14377           is_ipv6 = 0;
14378           is_ip_any = 0;
14379         }
14380       else
14381         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14382         {
14383           is_ipv6 = 0;
14384           is_ip_any = 0;
14385         }
14386       else
14387         if (unformat
14388             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14389         {
14390           is_ipv6 = 1;
14391           is_ip_any = 0;
14392         }
14393       else
14394         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14395         {
14396           is_ipv6 = 1;
14397           is_ip_any = 0;
14398         }
14399       else
14400         if (unformat
14401             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14402         {
14403           is_ipv6 = 1;
14404           is_ip_any = 0;
14405         }
14406       else
14407         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14408         {
14409           is_ipv6 = 1;
14410           is_ip_any = 0;
14411         }
14412       else
14413         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14414         {
14415           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14416             {
14417               clib_warning ("unsupported action: 'resolve'");
14418               return -99;
14419             }
14420         }
14421       else
14422         {
14423           clib_warning ("parse error '%U'", format_unformat_error, i);
14424           return -99;
14425         }
14426
14427     }
14428
14429   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14430
14431   mp->spd_id = ntohl (spd_id);
14432   mp->priority = ntohl (priority);
14433   mp->is_outbound = is_outbound;
14434
14435   mp->is_ipv6 = is_ipv6;
14436   if (is_ipv6 || is_ip_any)
14437     {
14438       clib_memcpy (mp->remote_address_start, &raddr6_start,
14439                    sizeof (ip6_address_t));
14440       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14441                    sizeof (ip6_address_t));
14442       clib_memcpy (mp->local_address_start, &laddr6_start,
14443                    sizeof (ip6_address_t));
14444       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14445                    sizeof (ip6_address_t));
14446     }
14447   else
14448     {
14449       clib_memcpy (mp->remote_address_start, &raddr4_start,
14450                    sizeof (ip4_address_t));
14451       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14452                    sizeof (ip4_address_t));
14453       clib_memcpy (mp->local_address_start, &laddr4_start,
14454                    sizeof (ip4_address_t));
14455       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14456                    sizeof (ip4_address_t));
14457     }
14458   mp->protocol = (u8) protocol;
14459   mp->local_port_start = ntohs ((u16) lport_start);
14460   mp->local_port_stop = ntohs ((u16) lport_stop);
14461   mp->remote_port_start = ntohs ((u16) rport_start);
14462   mp->remote_port_stop = ntohs ((u16) rport_stop);
14463   mp->policy = (u8) policy;
14464   mp->sa_id = ntohl (sa_id);
14465   mp->is_add = is_add;
14466   mp->is_ip_any = is_ip_any;
14467   S (mp);
14468   W (ret);
14469   return ret;
14470 }
14471
14472 static int
14473 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14474 {
14475   unformat_input_t *i = vam->input;
14476   vl_api_ipsec_sad_add_del_entry_t *mp;
14477   u32 sad_id = 0, spi = 0;
14478   u8 *ck = 0, *ik = 0;
14479   u8 is_add = 1;
14480
14481   u8 protocol = IPSEC_PROTOCOL_AH;
14482   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14483   u32 crypto_alg = 0, integ_alg = 0;
14484   ip4_address_t tun_src4;
14485   ip4_address_t tun_dst4;
14486   ip6_address_t tun_src6;
14487   ip6_address_t tun_dst6;
14488   int ret;
14489
14490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14491     {
14492       if (unformat (i, "del"))
14493         is_add = 0;
14494       else if (unformat (i, "sad_id %d", &sad_id))
14495         ;
14496       else if (unformat (i, "spi %d", &spi))
14497         ;
14498       else if (unformat (i, "esp"))
14499         protocol = IPSEC_PROTOCOL_ESP;
14500       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14501         {
14502           is_tunnel = 1;
14503           is_tunnel_ipv6 = 0;
14504         }
14505       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14506         {
14507           is_tunnel = 1;
14508           is_tunnel_ipv6 = 0;
14509         }
14510       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14511         {
14512           is_tunnel = 1;
14513           is_tunnel_ipv6 = 1;
14514         }
14515       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14516         {
14517           is_tunnel = 1;
14518           is_tunnel_ipv6 = 1;
14519         }
14520       else
14521         if (unformat
14522             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14523         {
14524           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14525               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14526             {
14527               clib_warning ("unsupported crypto-alg: '%U'",
14528                             format_ipsec_crypto_alg, crypto_alg);
14529               return -99;
14530             }
14531         }
14532       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14533         ;
14534       else
14535         if (unformat
14536             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14537         {
14538           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14539               integ_alg >= IPSEC_INTEG_N_ALG)
14540             {
14541               clib_warning ("unsupported integ-alg: '%U'",
14542                             format_ipsec_integ_alg, integ_alg);
14543               return -99;
14544             }
14545         }
14546       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14547         ;
14548       else
14549         {
14550           clib_warning ("parse error '%U'", format_unformat_error, i);
14551           return -99;
14552         }
14553
14554     }
14555
14556   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14557
14558   mp->sad_id = ntohl (sad_id);
14559   mp->is_add = is_add;
14560   mp->protocol = protocol;
14561   mp->spi = ntohl (spi);
14562   mp->is_tunnel = is_tunnel;
14563   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14564   mp->crypto_algorithm = crypto_alg;
14565   mp->integrity_algorithm = integ_alg;
14566   mp->crypto_key_length = vec_len (ck);
14567   mp->integrity_key_length = vec_len (ik);
14568
14569   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14570     mp->crypto_key_length = sizeof (mp->crypto_key);
14571
14572   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14573     mp->integrity_key_length = sizeof (mp->integrity_key);
14574
14575   if (ck)
14576     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14577   if (ik)
14578     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14579
14580   if (is_tunnel)
14581     {
14582       if (is_tunnel_ipv6)
14583         {
14584           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14585                        sizeof (ip6_address_t));
14586           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14587                        sizeof (ip6_address_t));
14588         }
14589       else
14590         {
14591           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14592                        sizeof (ip4_address_t));
14593           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14594                        sizeof (ip4_address_t));
14595         }
14596     }
14597
14598   S (mp);
14599   W (ret);
14600   return ret;
14601 }
14602
14603 static int
14604 api_ipsec_sa_set_key (vat_main_t * vam)
14605 {
14606   unformat_input_t *i = vam->input;
14607   vl_api_ipsec_sa_set_key_t *mp;
14608   u32 sa_id;
14609   u8 *ck = 0, *ik = 0;
14610   int ret;
14611
14612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (i, "sa_id %d", &sa_id))
14615         ;
14616       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14617         ;
14618       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14619         ;
14620       else
14621         {
14622           clib_warning ("parse error '%U'", format_unformat_error, i);
14623           return -99;
14624         }
14625     }
14626
14627   M (IPSEC_SA_SET_KEY, mp);
14628
14629   mp->sa_id = ntohl (sa_id);
14630   mp->crypto_key_length = vec_len (ck);
14631   mp->integrity_key_length = vec_len (ik);
14632
14633   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14634     mp->crypto_key_length = sizeof (mp->crypto_key);
14635
14636   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14637     mp->integrity_key_length = sizeof (mp->integrity_key);
14638
14639   if (ck)
14640     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14641   if (ik)
14642     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14643
14644   S (mp);
14645   W (ret);
14646   return ret;
14647 }
14648
14649 static int
14650 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14651 {
14652   unformat_input_t *i = vam->input;
14653   vl_api_ipsec_tunnel_if_add_del_t *mp;
14654   u32 local_spi = 0, remote_spi = 0;
14655   u32 crypto_alg = 0, integ_alg = 0;
14656   u8 *lck = NULL, *rck = NULL;
14657   u8 *lik = NULL, *rik = NULL;
14658   ip4_address_t local_ip = { {0} };
14659   ip4_address_t remote_ip = { {0} };
14660   u8 is_add = 1;
14661   u8 esn = 0;
14662   u8 anti_replay = 0;
14663   int ret;
14664
14665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14666     {
14667       if (unformat (i, "del"))
14668         is_add = 0;
14669       else if (unformat (i, "esn"))
14670         esn = 1;
14671       else if (unformat (i, "anti_replay"))
14672         anti_replay = 1;
14673       else if (unformat (i, "local_spi %d", &local_spi))
14674         ;
14675       else if (unformat (i, "remote_spi %d", &remote_spi))
14676         ;
14677       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14678         ;
14679       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14680         ;
14681       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14682         ;
14683       else
14684         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14685         ;
14686       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14687         ;
14688       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14689         ;
14690       else
14691         if (unformat
14692             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14693         {
14694           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14695               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14696             {
14697               errmsg ("unsupported crypto-alg: '%U'\n",
14698                       format_ipsec_crypto_alg, crypto_alg);
14699               return -99;
14700             }
14701         }
14702       else
14703         if (unformat
14704             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14705         {
14706           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14707               integ_alg >= IPSEC_INTEG_N_ALG)
14708             {
14709               errmsg ("unsupported integ-alg: '%U'\n",
14710                       format_ipsec_integ_alg, integ_alg);
14711               return -99;
14712             }
14713         }
14714       else
14715         {
14716           errmsg ("parse error '%U'\n", format_unformat_error, i);
14717           return -99;
14718         }
14719     }
14720
14721   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14722
14723   mp->is_add = is_add;
14724   mp->esn = esn;
14725   mp->anti_replay = anti_replay;
14726
14727   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14728   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14729
14730   mp->local_spi = htonl (local_spi);
14731   mp->remote_spi = htonl (remote_spi);
14732   mp->crypto_alg = (u8) crypto_alg;
14733
14734   mp->local_crypto_key_len = 0;
14735   if (lck)
14736     {
14737       mp->local_crypto_key_len = vec_len (lck);
14738       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14739         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14740       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14741     }
14742
14743   mp->remote_crypto_key_len = 0;
14744   if (rck)
14745     {
14746       mp->remote_crypto_key_len = vec_len (rck);
14747       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14748         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14749       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14750     }
14751
14752   mp->integ_alg = (u8) integ_alg;
14753
14754   mp->local_integ_key_len = 0;
14755   if (lik)
14756     {
14757       mp->local_integ_key_len = vec_len (lik);
14758       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14759         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14760       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14761     }
14762
14763   mp->remote_integ_key_len = 0;
14764   if (rik)
14765     {
14766       mp->remote_integ_key_len = vec_len (rik);
14767       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14768         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14769       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14770     }
14771
14772   S (mp);
14773   W (ret);
14774   return ret;
14775 }
14776
14777 static void
14778 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14779 {
14780   vat_main_t *vam = &vat_main;
14781
14782   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14783          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14784          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14785          "tunnel_src_addr %U tunnel_dst_addr %U "
14786          "salt %u seq_outbound %lu last_seq_inbound %lu "
14787          "replay_window %lu total_data_size %lu\n",
14788          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14789          mp->protocol,
14790          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14791          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14792          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14793          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14794          mp->tunnel_src_addr,
14795          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14796          mp->tunnel_dst_addr,
14797          ntohl (mp->salt),
14798          clib_net_to_host_u64 (mp->seq_outbound),
14799          clib_net_to_host_u64 (mp->last_seq_inbound),
14800          clib_net_to_host_u64 (mp->replay_window),
14801          clib_net_to_host_u64 (mp->total_data_size));
14802 }
14803
14804 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14805 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14806
14807 static void vl_api_ipsec_sa_details_t_handler_json
14808   (vl_api_ipsec_sa_details_t * mp)
14809 {
14810   vat_main_t *vam = &vat_main;
14811   vat_json_node_t *node = NULL;
14812   struct in_addr src_ip4, dst_ip4;
14813   struct in6_addr src_ip6, dst_ip6;
14814
14815   if (VAT_JSON_ARRAY != vam->json_tree.type)
14816     {
14817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14818       vat_json_init_array (&vam->json_tree);
14819     }
14820   node = vat_json_array_add (&vam->json_tree);
14821
14822   vat_json_init_object (node);
14823   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14825   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14826   vat_json_object_add_uint (node, "proto", mp->protocol);
14827   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14828   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14829   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14830   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14831   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14832   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14833   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14834                              mp->crypto_key_len);
14835   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14836                              mp->integ_key_len);
14837   if (mp->is_tunnel_ip6)
14838     {
14839       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14840       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14841       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14842       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14843     }
14844   else
14845     {
14846       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14847       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14848       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14849       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14850     }
14851   vat_json_object_add_uint (node, "replay_window",
14852                             clib_net_to_host_u64 (mp->replay_window));
14853   vat_json_object_add_uint (node, "total_data_size",
14854                             clib_net_to_host_u64 (mp->total_data_size));
14855
14856 }
14857
14858 static int
14859 api_ipsec_sa_dump (vat_main_t * vam)
14860 {
14861   unformat_input_t *i = vam->input;
14862   vl_api_ipsec_sa_dump_t *mp;
14863   vl_api_control_ping_t *mp_ping;
14864   u32 sa_id = ~0;
14865   int ret;
14866
14867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14868     {
14869       if (unformat (i, "sa_id %d", &sa_id))
14870         ;
14871       else
14872         {
14873           clib_warning ("parse error '%U'", format_unformat_error, i);
14874           return -99;
14875         }
14876     }
14877
14878   M (IPSEC_SA_DUMP, mp);
14879
14880   mp->sa_id = ntohl (sa_id);
14881
14882   S (mp);
14883
14884   /* Use a control ping for synchronization */
14885   M (CONTROL_PING, mp_ping);
14886   S (mp_ping);
14887
14888   W (ret);
14889   return ret;
14890 }
14891
14892 static int
14893 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14894 {
14895   unformat_input_t *i = vam->input;
14896   vl_api_ipsec_tunnel_if_set_key_t *mp;
14897   u32 sw_if_index = ~0;
14898   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14899   u8 *key = 0;
14900   u32 alg = ~0;
14901   int ret;
14902
14903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14906         ;
14907       else
14908         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14909         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14910       else
14911         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14912         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14913       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14914         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14915       else
14916         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14917         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14918       else if (unformat (i, "%U", unformat_hex_string, &key))
14919         ;
14920       else
14921         {
14922           clib_warning ("parse error '%U'", format_unformat_error, i);
14923           return -99;
14924         }
14925     }
14926
14927   if (sw_if_index == ~0)
14928     {
14929       errmsg ("interface must be specified");
14930       return -99;
14931     }
14932
14933   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14934     {
14935       errmsg ("key type must be specified");
14936       return -99;
14937     }
14938
14939   if (alg == ~0)
14940     {
14941       errmsg ("algorithm must be specified");
14942       return -99;
14943     }
14944
14945   if (vec_len (key) == 0)
14946     {
14947       errmsg ("key must be specified");
14948       return -99;
14949     }
14950
14951   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14952
14953   mp->sw_if_index = htonl (sw_if_index);
14954   mp->alg = alg;
14955   mp->key_type = key_type;
14956   mp->key_len = vec_len (key);
14957   clib_memcpy (mp->key, key, vec_len (key));
14958
14959   S (mp);
14960   W (ret);
14961
14962   return ret;
14963 }
14964
14965 static int
14966 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14967 {
14968   unformat_input_t *i = vam->input;
14969   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14970   u32 sw_if_index = ~0;
14971   u32 sa_id = ~0;
14972   u8 is_outbound = (u8) ~ 0;
14973   int ret;
14974
14975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14978         ;
14979       else if (unformat (i, "sa_id %d", &sa_id))
14980         ;
14981       else if (unformat (i, "outbound"))
14982         is_outbound = 1;
14983       else if (unformat (i, "inbound"))
14984         is_outbound = 0;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990     }
14991
14992   if (sw_if_index == ~0)
14993     {
14994       errmsg ("interface must be specified");
14995       return -99;
14996     }
14997
14998   if (sa_id == ~0)
14999     {
15000       errmsg ("SA ID must be specified");
15001       return -99;
15002     }
15003
15004   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15005
15006   mp->sw_if_index = htonl (sw_if_index);
15007   mp->sa_id = htonl (sa_id);
15008   mp->is_outbound = is_outbound;
15009
15010   S (mp);
15011   W (ret);
15012
15013   return ret;
15014 }
15015
15016 static int
15017 api_ikev2_profile_add_del (vat_main_t * vam)
15018 {
15019   unformat_input_t *i = vam->input;
15020   vl_api_ikev2_profile_add_del_t *mp;
15021   u8 is_add = 1;
15022   u8 *name = 0;
15023   int ret;
15024
15025   const char *valid_chars = "a-zA-Z0-9_";
15026
15027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15028     {
15029       if (unformat (i, "del"))
15030         is_add = 0;
15031       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15032         vec_add1 (name, 0);
15033       else
15034         {
15035           errmsg ("parse error '%U'", format_unformat_error, i);
15036           return -99;
15037         }
15038     }
15039
15040   if (!vec_len (name))
15041     {
15042       errmsg ("profile name must be specified");
15043       return -99;
15044     }
15045
15046   if (vec_len (name) > 64)
15047     {
15048       errmsg ("profile name too long");
15049       return -99;
15050     }
15051
15052   M (IKEV2_PROFILE_ADD_DEL, mp);
15053
15054   clib_memcpy (mp->name, name, vec_len (name));
15055   mp->is_add = is_add;
15056   vec_free (name);
15057
15058   S (mp);
15059   W (ret);
15060   return ret;
15061 }
15062
15063 static int
15064 api_ikev2_profile_set_auth (vat_main_t * vam)
15065 {
15066   unformat_input_t *i = vam->input;
15067   vl_api_ikev2_profile_set_auth_t *mp;
15068   u8 *name = 0;
15069   u8 *data = 0;
15070   u32 auth_method = 0;
15071   u8 is_hex = 0;
15072   int ret;
15073
15074   const char *valid_chars = "a-zA-Z0-9_";
15075
15076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15079         vec_add1 (name, 0);
15080       else if (unformat (i, "auth_method %U",
15081                          unformat_ikev2_auth_method, &auth_method))
15082         ;
15083       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15084         is_hex = 1;
15085       else if (unformat (i, "auth_data %v", &data))
15086         ;
15087       else
15088         {
15089           errmsg ("parse error '%U'", format_unformat_error, i);
15090           return -99;
15091         }
15092     }
15093
15094   if (!vec_len (name))
15095     {
15096       errmsg ("profile name must be specified");
15097       return -99;
15098     }
15099
15100   if (vec_len (name) > 64)
15101     {
15102       errmsg ("profile name too long");
15103       return -99;
15104     }
15105
15106   if (!vec_len (data))
15107     {
15108       errmsg ("auth_data must be specified");
15109       return -99;
15110     }
15111
15112   if (!auth_method)
15113     {
15114       errmsg ("auth_method must be specified");
15115       return -99;
15116     }
15117
15118   M (IKEV2_PROFILE_SET_AUTH, mp);
15119
15120   mp->is_hex = is_hex;
15121   mp->auth_method = (u8) auth_method;
15122   mp->data_len = vec_len (data);
15123   clib_memcpy (mp->name, name, vec_len (name));
15124   clib_memcpy (mp->data, data, vec_len (data));
15125   vec_free (name);
15126   vec_free (data);
15127
15128   S (mp);
15129   W (ret);
15130   return ret;
15131 }
15132
15133 static int
15134 api_ikev2_profile_set_id (vat_main_t * vam)
15135 {
15136   unformat_input_t *i = vam->input;
15137   vl_api_ikev2_profile_set_id_t *mp;
15138   u8 *name = 0;
15139   u8 *data = 0;
15140   u8 is_local = 0;
15141   u32 id_type = 0;
15142   ip4_address_t ip4;
15143   int ret;
15144
15145   const char *valid_chars = "a-zA-Z0-9_";
15146
15147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15148     {
15149       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15150         vec_add1 (name, 0);
15151       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15152         ;
15153       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15154         {
15155           data = vec_new (u8, 4);
15156           clib_memcpy (data, ip4.as_u8, 4);
15157         }
15158       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15159         ;
15160       else if (unformat (i, "id_data %v", &data))
15161         ;
15162       else if (unformat (i, "local"))
15163         is_local = 1;
15164       else if (unformat (i, "remote"))
15165         is_local = 0;
15166       else
15167         {
15168           errmsg ("parse error '%U'", format_unformat_error, i);
15169           return -99;
15170         }
15171     }
15172
15173   if (!vec_len (name))
15174     {
15175       errmsg ("profile name must be specified");
15176       return -99;
15177     }
15178
15179   if (vec_len (name) > 64)
15180     {
15181       errmsg ("profile name too long");
15182       return -99;
15183     }
15184
15185   if (!vec_len (data))
15186     {
15187       errmsg ("id_data must be specified");
15188       return -99;
15189     }
15190
15191   if (!id_type)
15192     {
15193       errmsg ("id_type must be specified");
15194       return -99;
15195     }
15196
15197   M (IKEV2_PROFILE_SET_ID, mp);
15198
15199   mp->is_local = is_local;
15200   mp->id_type = (u8) id_type;
15201   mp->data_len = vec_len (data);
15202   clib_memcpy (mp->name, name, vec_len (name));
15203   clib_memcpy (mp->data, data, vec_len (data));
15204   vec_free (name);
15205   vec_free (data);
15206
15207   S (mp);
15208   W (ret);
15209   return ret;
15210 }
15211
15212 static int
15213 api_ikev2_profile_set_ts (vat_main_t * vam)
15214 {
15215   unformat_input_t *i = vam->input;
15216   vl_api_ikev2_profile_set_ts_t *mp;
15217   u8 *name = 0;
15218   u8 is_local = 0;
15219   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15220   ip4_address_t start_addr, end_addr;
15221
15222   const char *valid_chars = "a-zA-Z0-9_";
15223   int ret;
15224
15225   start_addr.as_u32 = 0;
15226   end_addr.as_u32 = (u32) ~ 0;
15227
15228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15231         vec_add1 (name, 0);
15232       else if (unformat (i, "protocol %d", &proto))
15233         ;
15234       else if (unformat (i, "start_port %d", &start_port))
15235         ;
15236       else if (unformat (i, "end_port %d", &end_port))
15237         ;
15238       else
15239         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15240         ;
15241       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15242         ;
15243       else if (unformat (i, "local"))
15244         is_local = 1;
15245       else if (unformat (i, "remote"))
15246         is_local = 0;
15247       else
15248         {
15249           errmsg ("parse error '%U'", format_unformat_error, i);
15250           return -99;
15251         }
15252     }
15253
15254   if (!vec_len (name))
15255     {
15256       errmsg ("profile name must be specified");
15257       return -99;
15258     }
15259
15260   if (vec_len (name) > 64)
15261     {
15262       errmsg ("profile name too long");
15263       return -99;
15264     }
15265
15266   M (IKEV2_PROFILE_SET_TS, mp);
15267
15268   mp->is_local = is_local;
15269   mp->proto = (u8) proto;
15270   mp->start_port = (u16) start_port;
15271   mp->end_port = (u16) end_port;
15272   mp->start_addr = start_addr.as_u32;
15273   mp->end_addr = end_addr.as_u32;
15274   clib_memcpy (mp->name, name, vec_len (name));
15275   vec_free (name);
15276
15277   S (mp);
15278   W (ret);
15279   return ret;
15280 }
15281
15282 static int
15283 api_ikev2_set_local_key (vat_main_t * vam)
15284 {
15285   unformat_input_t *i = vam->input;
15286   vl_api_ikev2_set_local_key_t *mp;
15287   u8 *file = 0;
15288   int ret;
15289
15290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15291     {
15292       if (unformat (i, "file %v", &file))
15293         vec_add1 (file, 0);
15294       else
15295         {
15296           errmsg ("parse error '%U'", format_unformat_error, i);
15297           return -99;
15298         }
15299     }
15300
15301   if (!vec_len (file))
15302     {
15303       errmsg ("RSA key file must be specified");
15304       return -99;
15305     }
15306
15307   if (vec_len (file) > 256)
15308     {
15309       errmsg ("file name too long");
15310       return -99;
15311     }
15312
15313   M (IKEV2_SET_LOCAL_KEY, mp);
15314
15315   clib_memcpy (mp->key_file, file, vec_len (file));
15316   vec_free (file);
15317
15318   S (mp);
15319   W (ret);
15320   return ret;
15321 }
15322
15323 static int
15324 api_ikev2_set_responder (vat_main_t * vam)
15325 {
15326   unformat_input_t *i = vam->input;
15327   vl_api_ikev2_set_responder_t *mp;
15328   int ret;
15329   u8 *name = 0;
15330   u32 sw_if_index = ~0;
15331   ip4_address_t address;
15332
15333   const char *valid_chars = "a-zA-Z0-9_";
15334
15335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15336     {
15337       if (unformat
15338           (i, "%U interface %d address %U", unformat_token, valid_chars,
15339            &name, &sw_if_index, unformat_ip4_address, &address))
15340         vec_add1 (name, 0);
15341       else
15342         {
15343           errmsg ("parse error '%U'", format_unformat_error, i);
15344           return -99;
15345         }
15346     }
15347
15348   if (!vec_len (name))
15349     {
15350       errmsg ("profile name must be specified");
15351       return -99;
15352     }
15353
15354   if (vec_len (name) > 64)
15355     {
15356       errmsg ("profile name too long");
15357       return -99;
15358     }
15359
15360   M (IKEV2_SET_RESPONDER, mp);
15361
15362   clib_memcpy (mp->name, name, vec_len (name));
15363   vec_free (name);
15364
15365   mp->sw_if_index = sw_if_index;
15366   clib_memcpy (mp->address, &address, sizeof (address));
15367
15368   S (mp);
15369   W (ret);
15370   return ret;
15371 }
15372
15373 static int
15374 api_ikev2_set_ike_transforms (vat_main_t * vam)
15375 {
15376   unformat_input_t *i = vam->input;
15377   vl_api_ikev2_set_ike_transforms_t *mp;
15378   int ret;
15379   u8 *name = 0;
15380   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15381
15382   const char *valid_chars = "a-zA-Z0-9_";
15383
15384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15387                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15388         vec_add1 (name, 0);
15389       else
15390         {
15391           errmsg ("parse error '%U'", format_unformat_error, i);
15392           return -99;
15393         }
15394     }
15395
15396   if (!vec_len (name))
15397     {
15398       errmsg ("profile name must be specified");
15399       return -99;
15400     }
15401
15402   if (vec_len (name) > 64)
15403     {
15404       errmsg ("profile name too long");
15405       return -99;
15406     }
15407
15408   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15409
15410   clib_memcpy (mp->name, name, vec_len (name));
15411   vec_free (name);
15412   mp->crypto_alg = crypto_alg;
15413   mp->crypto_key_size = crypto_key_size;
15414   mp->integ_alg = integ_alg;
15415   mp->dh_group = dh_group;
15416
15417   S (mp);
15418   W (ret);
15419   return ret;
15420 }
15421
15422
15423 static int
15424 api_ikev2_set_esp_transforms (vat_main_t * vam)
15425 {
15426   unformat_input_t *i = vam->input;
15427   vl_api_ikev2_set_esp_transforms_t *mp;
15428   int ret;
15429   u8 *name = 0;
15430   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15431
15432   const char *valid_chars = "a-zA-Z0-9_";
15433
15434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15435     {
15436       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15437                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15438         vec_add1 (name, 0);
15439       else
15440         {
15441           errmsg ("parse error '%U'", format_unformat_error, i);
15442           return -99;
15443         }
15444     }
15445
15446   if (!vec_len (name))
15447     {
15448       errmsg ("profile name must be specified");
15449       return -99;
15450     }
15451
15452   if (vec_len (name) > 64)
15453     {
15454       errmsg ("profile name too long");
15455       return -99;
15456     }
15457
15458   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15459
15460   clib_memcpy (mp->name, name, vec_len (name));
15461   vec_free (name);
15462   mp->crypto_alg = crypto_alg;
15463   mp->crypto_key_size = crypto_key_size;
15464   mp->integ_alg = integ_alg;
15465   mp->dh_group = dh_group;
15466
15467   S (mp);
15468   W (ret);
15469   return ret;
15470 }
15471
15472 static int
15473 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15474 {
15475   unformat_input_t *i = vam->input;
15476   vl_api_ikev2_set_sa_lifetime_t *mp;
15477   int ret;
15478   u8 *name = 0;
15479   u64 lifetime, lifetime_maxdata;
15480   u32 lifetime_jitter, handover;
15481
15482   const char *valid_chars = "a-zA-Z0-9_";
15483
15484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15485     {
15486       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15487                     &lifetime, &lifetime_jitter, &handover,
15488                     &lifetime_maxdata))
15489         vec_add1 (name, 0);
15490       else
15491         {
15492           errmsg ("parse error '%U'", format_unformat_error, i);
15493           return -99;
15494         }
15495     }
15496
15497   if (!vec_len (name))
15498     {
15499       errmsg ("profile name must be specified");
15500       return -99;
15501     }
15502
15503   if (vec_len (name) > 64)
15504     {
15505       errmsg ("profile name too long");
15506       return -99;
15507     }
15508
15509   M (IKEV2_SET_SA_LIFETIME, mp);
15510
15511   clib_memcpy (mp->name, name, vec_len (name));
15512   vec_free (name);
15513   mp->lifetime = lifetime;
15514   mp->lifetime_jitter = lifetime_jitter;
15515   mp->handover = handover;
15516   mp->lifetime_maxdata = lifetime_maxdata;
15517
15518   S (mp);
15519   W (ret);
15520   return ret;
15521 }
15522
15523 static int
15524 api_ikev2_initiate_sa_init (vat_main_t * vam)
15525 {
15526   unformat_input_t *i = vam->input;
15527   vl_api_ikev2_initiate_sa_init_t *mp;
15528   int ret;
15529   u8 *name = 0;
15530
15531   const char *valid_chars = "a-zA-Z0-9_";
15532
15533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15534     {
15535       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15536         vec_add1 (name, 0);
15537       else
15538         {
15539           errmsg ("parse error '%U'", format_unformat_error, i);
15540           return -99;
15541         }
15542     }
15543
15544   if (!vec_len (name))
15545     {
15546       errmsg ("profile name must be specified");
15547       return -99;
15548     }
15549
15550   if (vec_len (name) > 64)
15551     {
15552       errmsg ("profile name too long");
15553       return -99;
15554     }
15555
15556   M (IKEV2_INITIATE_SA_INIT, mp);
15557
15558   clib_memcpy (mp->name, name, vec_len (name));
15559   vec_free (name);
15560
15561   S (mp);
15562   W (ret);
15563   return ret;
15564 }
15565
15566 static int
15567 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15568 {
15569   unformat_input_t *i = vam->input;
15570   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15571   int ret;
15572   u64 ispi;
15573
15574
15575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15576     {
15577       if (unformat (i, "%lx", &ispi))
15578         ;
15579       else
15580         {
15581           errmsg ("parse error '%U'", format_unformat_error, i);
15582           return -99;
15583         }
15584     }
15585
15586   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15587
15588   mp->ispi = ispi;
15589
15590   S (mp);
15591   W (ret);
15592   return ret;
15593 }
15594
15595 static int
15596 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15597 {
15598   unformat_input_t *i = vam->input;
15599   vl_api_ikev2_initiate_del_child_sa_t *mp;
15600   int ret;
15601   u32 ispi;
15602
15603
15604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15605     {
15606       if (unformat (i, "%x", &ispi))
15607         ;
15608       else
15609         {
15610           errmsg ("parse error '%U'", format_unformat_error, i);
15611           return -99;
15612         }
15613     }
15614
15615   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15616
15617   mp->ispi = ispi;
15618
15619   S (mp);
15620   W (ret);
15621   return ret;
15622 }
15623
15624 static int
15625 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15626 {
15627   unformat_input_t *i = vam->input;
15628   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15629   int ret;
15630   u32 ispi;
15631
15632
15633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15634     {
15635       if (unformat (i, "%x", &ispi))
15636         ;
15637       else
15638         {
15639           errmsg ("parse error '%U'", format_unformat_error, i);
15640           return -99;
15641         }
15642     }
15643
15644   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15645
15646   mp->ispi = ispi;
15647
15648   S (mp);
15649   W (ret);
15650   return ret;
15651 }
15652
15653 /*
15654  * MAP
15655  */
15656 static int
15657 api_map_add_domain (vat_main_t * vam)
15658 {
15659   unformat_input_t *i = vam->input;
15660   vl_api_map_add_domain_t *mp;
15661
15662   ip4_address_t ip4_prefix;
15663   ip6_address_t ip6_prefix;
15664   ip6_address_t ip6_src;
15665   u32 num_m_args = 0;
15666   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15667     0, psid_length = 0;
15668   u8 is_translation = 0;
15669   u32 mtu = 0;
15670   u32 ip6_src_len = 128;
15671   int ret;
15672
15673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15674     {
15675       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15676                     &ip4_prefix, &ip4_prefix_len))
15677         num_m_args++;
15678       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15679                          &ip6_prefix, &ip6_prefix_len))
15680         num_m_args++;
15681       else
15682         if (unformat
15683             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15684              &ip6_src_len))
15685         num_m_args++;
15686       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15687         num_m_args++;
15688       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15689         num_m_args++;
15690       else if (unformat (i, "psid-offset %d", &psid_offset))
15691         num_m_args++;
15692       else if (unformat (i, "psid-len %d", &psid_length))
15693         num_m_args++;
15694       else if (unformat (i, "mtu %d", &mtu))
15695         num_m_args++;
15696       else if (unformat (i, "map-t"))
15697         is_translation = 1;
15698       else
15699         {
15700           clib_warning ("parse error '%U'", format_unformat_error, i);
15701           return -99;
15702         }
15703     }
15704
15705   if (num_m_args < 3)
15706     {
15707       errmsg ("mandatory argument(s) missing");
15708       return -99;
15709     }
15710
15711   /* Construct the API message */
15712   M (MAP_ADD_DOMAIN, mp);
15713
15714   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15715   mp->ip4_prefix_len = ip4_prefix_len;
15716
15717   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15718   mp->ip6_prefix_len = ip6_prefix_len;
15719
15720   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15721   mp->ip6_src_prefix_len = ip6_src_len;
15722
15723   mp->ea_bits_len = ea_bits_len;
15724   mp->psid_offset = psid_offset;
15725   mp->psid_length = psid_length;
15726   mp->is_translation = is_translation;
15727   mp->mtu = htons (mtu);
15728
15729   /* send it... */
15730   S (mp);
15731
15732   /* Wait for a reply, return good/bad news  */
15733   W (ret);
15734   return ret;
15735 }
15736
15737 static int
15738 api_map_del_domain (vat_main_t * vam)
15739 {
15740   unformat_input_t *i = vam->input;
15741   vl_api_map_del_domain_t *mp;
15742
15743   u32 num_m_args = 0;
15744   u32 index;
15745   int ret;
15746
15747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15748     {
15749       if (unformat (i, "index %d", &index))
15750         num_m_args++;
15751       else
15752         {
15753           clib_warning ("parse error '%U'", format_unformat_error, i);
15754           return -99;
15755         }
15756     }
15757
15758   if (num_m_args != 1)
15759     {
15760       errmsg ("mandatory argument(s) missing");
15761       return -99;
15762     }
15763
15764   /* Construct the API message */
15765   M (MAP_DEL_DOMAIN, mp);
15766
15767   mp->index = ntohl (index);
15768
15769   /* send it... */
15770   S (mp);
15771
15772   /* Wait for a reply, return good/bad news  */
15773   W (ret);
15774   return ret;
15775 }
15776
15777 static int
15778 api_map_add_del_rule (vat_main_t * vam)
15779 {
15780   unformat_input_t *i = vam->input;
15781   vl_api_map_add_del_rule_t *mp;
15782   u8 is_add = 1;
15783   ip6_address_t ip6_dst;
15784   u32 num_m_args = 0, index, psid = 0;
15785   int ret;
15786
15787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15788     {
15789       if (unformat (i, "index %d", &index))
15790         num_m_args++;
15791       else if (unformat (i, "psid %d", &psid))
15792         num_m_args++;
15793       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15794         num_m_args++;
15795       else if (unformat (i, "del"))
15796         {
15797           is_add = 0;
15798         }
15799       else
15800         {
15801           clib_warning ("parse error '%U'", format_unformat_error, i);
15802           return -99;
15803         }
15804     }
15805
15806   /* Construct the API message */
15807   M (MAP_ADD_DEL_RULE, mp);
15808
15809   mp->index = ntohl (index);
15810   mp->is_add = is_add;
15811   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15812   mp->psid = ntohs (psid);
15813
15814   /* send it... */
15815   S (mp);
15816
15817   /* Wait for a reply, return good/bad news  */
15818   W (ret);
15819   return ret;
15820 }
15821
15822 static int
15823 api_map_domain_dump (vat_main_t * vam)
15824 {
15825   vl_api_map_domain_dump_t *mp;
15826   vl_api_control_ping_t *mp_ping;
15827   int ret;
15828
15829   /* Construct the API message */
15830   M (MAP_DOMAIN_DUMP, mp);
15831
15832   /* send it... */
15833   S (mp);
15834
15835   /* Use a control ping for synchronization */
15836   MPING (CONTROL_PING, mp_ping);
15837   S (mp_ping);
15838
15839   W (ret);
15840   return ret;
15841 }
15842
15843 static int
15844 api_map_rule_dump (vat_main_t * vam)
15845 {
15846   unformat_input_t *i = vam->input;
15847   vl_api_map_rule_dump_t *mp;
15848   vl_api_control_ping_t *mp_ping;
15849   u32 domain_index = ~0;
15850   int ret;
15851
15852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15853     {
15854       if (unformat (i, "index %u", &domain_index))
15855         ;
15856       else
15857         break;
15858     }
15859
15860   if (domain_index == ~0)
15861     {
15862       clib_warning ("parse error: domain index expected");
15863       return -99;
15864     }
15865
15866   /* Construct the API message */
15867   M (MAP_RULE_DUMP, mp);
15868
15869   mp->domain_index = htonl (domain_index);
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Use a control ping for synchronization */
15875   MPING (CONTROL_PING, mp_ping);
15876   S (mp_ping);
15877
15878   W (ret);
15879   return ret;
15880 }
15881
15882 static void vl_api_map_add_domain_reply_t_handler
15883   (vl_api_map_add_domain_reply_t * mp)
15884 {
15885   vat_main_t *vam = &vat_main;
15886   i32 retval = ntohl (mp->retval);
15887
15888   if (vam->async_mode)
15889     {
15890       vam->async_errors += (retval < 0);
15891     }
15892   else
15893     {
15894       vam->retval = retval;
15895       vam->result_ready = 1;
15896     }
15897 }
15898
15899 static void vl_api_map_add_domain_reply_t_handler_json
15900   (vl_api_map_add_domain_reply_t * mp)
15901 {
15902   vat_main_t *vam = &vat_main;
15903   vat_json_node_t node;
15904
15905   vat_json_init_object (&node);
15906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15907   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15908
15909   vat_json_print (vam->ofp, &node);
15910   vat_json_free (&node);
15911
15912   vam->retval = ntohl (mp->retval);
15913   vam->result_ready = 1;
15914 }
15915
15916 static int
15917 api_get_first_msg_id (vat_main_t * vam)
15918 {
15919   vl_api_get_first_msg_id_t *mp;
15920   unformat_input_t *i = vam->input;
15921   u8 *name;
15922   u8 name_set = 0;
15923   int ret;
15924
15925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15926     {
15927       if (unformat (i, "client %s", &name))
15928         name_set = 1;
15929       else
15930         break;
15931     }
15932
15933   if (name_set == 0)
15934     {
15935       errmsg ("missing client name");
15936       return -99;
15937     }
15938   vec_add1 (name, 0);
15939
15940   if (vec_len (name) > 63)
15941     {
15942       errmsg ("client name too long");
15943       return -99;
15944     }
15945
15946   M (GET_FIRST_MSG_ID, mp);
15947   clib_memcpy (mp->name, name, vec_len (name));
15948   S (mp);
15949   W (ret);
15950   return ret;
15951 }
15952
15953 static int
15954 api_cop_interface_enable_disable (vat_main_t * vam)
15955 {
15956   unformat_input_t *line_input = vam->input;
15957   vl_api_cop_interface_enable_disable_t *mp;
15958   u32 sw_if_index = ~0;
15959   u8 enable_disable = 1;
15960   int ret;
15961
15962   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15963     {
15964       if (unformat (line_input, "disable"))
15965         enable_disable = 0;
15966       if (unformat (line_input, "enable"))
15967         enable_disable = 1;
15968       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15969                          vam, &sw_if_index))
15970         ;
15971       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15972         ;
15973       else
15974         break;
15975     }
15976
15977   if (sw_if_index == ~0)
15978     {
15979       errmsg ("missing interface name or sw_if_index");
15980       return -99;
15981     }
15982
15983   /* Construct the API message */
15984   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15985   mp->sw_if_index = ntohl (sw_if_index);
15986   mp->enable_disable = enable_disable;
15987
15988   /* send it... */
15989   S (mp);
15990   /* Wait for the reply */
15991   W (ret);
15992   return ret;
15993 }
15994
15995 static int
15996 api_cop_whitelist_enable_disable (vat_main_t * vam)
15997 {
15998   unformat_input_t *line_input = vam->input;
15999   vl_api_cop_whitelist_enable_disable_t *mp;
16000   u32 sw_if_index = ~0;
16001   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16002   u32 fib_id = 0;
16003   int ret;
16004
16005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16006     {
16007       if (unformat (line_input, "ip4"))
16008         ip4 = 1;
16009       else if (unformat (line_input, "ip6"))
16010         ip6 = 1;
16011       else if (unformat (line_input, "default"))
16012         default_cop = 1;
16013       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16014                          vam, &sw_if_index))
16015         ;
16016       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16017         ;
16018       else if (unformat (line_input, "fib-id %d", &fib_id))
16019         ;
16020       else
16021         break;
16022     }
16023
16024   if (sw_if_index == ~0)
16025     {
16026       errmsg ("missing interface name or sw_if_index");
16027       return -99;
16028     }
16029
16030   /* Construct the API message */
16031   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16032   mp->sw_if_index = ntohl (sw_if_index);
16033   mp->fib_id = ntohl (fib_id);
16034   mp->ip4 = ip4;
16035   mp->ip6 = ip6;
16036   mp->default_cop = default_cop;
16037
16038   /* send it... */
16039   S (mp);
16040   /* Wait for the reply */
16041   W (ret);
16042   return ret;
16043 }
16044
16045 static int
16046 api_get_node_graph (vat_main_t * vam)
16047 {
16048   vl_api_get_node_graph_t *mp;
16049   int ret;
16050
16051   M (GET_NODE_GRAPH, mp);
16052
16053   /* send it... */
16054   S (mp);
16055   /* Wait for the reply */
16056   W (ret);
16057   return ret;
16058 }
16059
16060 /* *INDENT-OFF* */
16061 /** Used for parsing LISP eids */
16062 typedef CLIB_PACKED(struct{
16063   u8 addr[16];   /**< eid address */
16064   u32 len;       /**< prefix length if IP */
16065   u8 type;      /**< type of eid */
16066 }) lisp_eid_vat_t;
16067 /* *INDENT-ON* */
16068
16069 static uword
16070 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16071 {
16072   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16073
16074   memset (a, 0, sizeof (a[0]));
16075
16076   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16077     {
16078       a->type = 0;              /* ipv4 type */
16079     }
16080   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16081     {
16082       a->type = 1;              /* ipv6 type */
16083     }
16084   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16085     {
16086       a->type = 2;              /* mac type */
16087     }
16088   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16089     {
16090       a->type = 3;              /* NSH type */
16091       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16092       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16093     }
16094   else
16095     {
16096       return 0;
16097     }
16098
16099   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16100     {
16101       return 0;
16102     }
16103
16104   return 1;
16105 }
16106
16107 static int
16108 lisp_eid_size_vat (u8 type)
16109 {
16110   switch (type)
16111     {
16112     case 0:
16113       return 4;
16114     case 1:
16115       return 16;
16116     case 2:
16117       return 6;
16118     case 3:
16119       return 5;
16120     }
16121   return 0;
16122 }
16123
16124 static void
16125 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16126 {
16127   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16128 }
16129
16130 static int
16131 api_one_add_del_locator_set (vat_main_t * vam)
16132 {
16133   unformat_input_t *input = vam->input;
16134   vl_api_one_add_del_locator_set_t *mp;
16135   u8 is_add = 1;
16136   u8 *locator_set_name = NULL;
16137   u8 locator_set_name_set = 0;
16138   vl_api_local_locator_t locator, *locators = 0;
16139   u32 sw_if_index, priority, weight;
16140   u32 data_len = 0;
16141
16142   int ret;
16143   /* Parse args required to build the message */
16144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (input, "del"))
16147         {
16148           is_add = 0;
16149         }
16150       else if (unformat (input, "locator-set %s", &locator_set_name))
16151         {
16152           locator_set_name_set = 1;
16153         }
16154       else if (unformat (input, "sw_if_index %u p %u w %u",
16155                          &sw_if_index, &priority, &weight))
16156         {
16157           locator.sw_if_index = htonl (sw_if_index);
16158           locator.priority = priority;
16159           locator.weight = weight;
16160           vec_add1 (locators, locator);
16161         }
16162       else
16163         if (unformat
16164             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16165              &sw_if_index, &priority, &weight))
16166         {
16167           locator.sw_if_index = htonl (sw_if_index);
16168           locator.priority = priority;
16169           locator.weight = weight;
16170           vec_add1 (locators, locator);
16171         }
16172       else
16173         break;
16174     }
16175
16176   if (locator_set_name_set == 0)
16177     {
16178       errmsg ("missing locator-set name");
16179       vec_free (locators);
16180       return -99;
16181     }
16182
16183   if (vec_len (locator_set_name) > 64)
16184     {
16185       errmsg ("locator-set name too long");
16186       vec_free (locator_set_name);
16187       vec_free (locators);
16188       return -99;
16189     }
16190   vec_add1 (locator_set_name, 0);
16191
16192   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16193
16194   /* Construct the API message */
16195   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16196
16197   mp->is_add = is_add;
16198   clib_memcpy (mp->locator_set_name, locator_set_name,
16199                vec_len (locator_set_name));
16200   vec_free (locator_set_name);
16201
16202   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16203   if (locators)
16204     clib_memcpy (mp->locators, locators, data_len);
16205   vec_free (locators);
16206
16207   /* send it... */
16208   S (mp);
16209
16210   /* Wait for a reply... */
16211   W (ret);
16212   return ret;
16213 }
16214
16215 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16216
16217 static int
16218 api_one_add_del_locator (vat_main_t * vam)
16219 {
16220   unformat_input_t *input = vam->input;
16221   vl_api_one_add_del_locator_t *mp;
16222   u32 tmp_if_index = ~0;
16223   u32 sw_if_index = ~0;
16224   u8 sw_if_index_set = 0;
16225   u8 sw_if_index_if_name_set = 0;
16226   u32 priority = ~0;
16227   u8 priority_set = 0;
16228   u32 weight = ~0;
16229   u8 weight_set = 0;
16230   u8 is_add = 1;
16231   u8 *locator_set_name = NULL;
16232   u8 locator_set_name_set = 0;
16233   int ret;
16234
16235   /* Parse args required to build the message */
16236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16237     {
16238       if (unformat (input, "del"))
16239         {
16240           is_add = 0;
16241         }
16242       else if (unformat (input, "locator-set %s", &locator_set_name))
16243         {
16244           locator_set_name_set = 1;
16245         }
16246       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16247                          &tmp_if_index))
16248         {
16249           sw_if_index_if_name_set = 1;
16250           sw_if_index = tmp_if_index;
16251         }
16252       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16253         {
16254           sw_if_index_set = 1;
16255           sw_if_index = tmp_if_index;
16256         }
16257       else if (unformat (input, "p %d", &priority))
16258         {
16259           priority_set = 1;
16260         }
16261       else if (unformat (input, "w %d", &weight))
16262         {
16263           weight_set = 1;
16264         }
16265       else
16266         break;
16267     }
16268
16269   if (locator_set_name_set == 0)
16270     {
16271       errmsg ("missing locator-set name");
16272       return -99;
16273     }
16274
16275   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16276     {
16277       errmsg ("missing sw_if_index");
16278       vec_free (locator_set_name);
16279       return -99;
16280     }
16281
16282   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16283     {
16284       errmsg ("cannot use both params interface name and sw_if_index");
16285       vec_free (locator_set_name);
16286       return -99;
16287     }
16288
16289   if (priority_set == 0)
16290     {
16291       errmsg ("missing locator-set priority");
16292       vec_free (locator_set_name);
16293       return -99;
16294     }
16295
16296   if (weight_set == 0)
16297     {
16298       errmsg ("missing locator-set weight");
16299       vec_free (locator_set_name);
16300       return -99;
16301     }
16302
16303   if (vec_len (locator_set_name) > 64)
16304     {
16305       errmsg ("locator-set name too long");
16306       vec_free (locator_set_name);
16307       return -99;
16308     }
16309   vec_add1 (locator_set_name, 0);
16310
16311   /* Construct the API message */
16312   M (ONE_ADD_DEL_LOCATOR, mp);
16313
16314   mp->is_add = is_add;
16315   mp->sw_if_index = ntohl (sw_if_index);
16316   mp->priority = priority;
16317   mp->weight = weight;
16318   clib_memcpy (mp->locator_set_name, locator_set_name,
16319                vec_len (locator_set_name));
16320   vec_free (locator_set_name);
16321
16322   /* send it... */
16323   S (mp);
16324
16325   /* Wait for a reply... */
16326   W (ret);
16327   return ret;
16328 }
16329
16330 #define api_lisp_add_del_locator api_one_add_del_locator
16331
16332 uword
16333 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16334 {
16335   u32 *key_id = va_arg (*args, u32 *);
16336   u8 *s = 0;
16337
16338   if (unformat (input, "%s", &s))
16339     {
16340       if (!strcmp ((char *) s, "sha1"))
16341         key_id[0] = HMAC_SHA_1_96;
16342       else if (!strcmp ((char *) s, "sha256"))
16343         key_id[0] = HMAC_SHA_256_128;
16344       else
16345         {
16346           clib_warning ("invalid key_id: '%s'", s);
16347           key_id[0] = HMAC_NO_KEY;
16348         }
16349     }
16350   else
16351     return 0;
16352
16353   vec_free (s);
16354   return 1;
16355 }
16356
16357 static int
16358 api_one_add_del_local_eid (vat_main_t * vam)
16359 {
16360   unformat_input_t *input = vam->input;
16361   vl_api_one_add_del_local_eid_t *mp;
16362   u8 is_add = 1;
16363   u8 eid_set = 0;
16364   lisp_eid_vat_t _eid, *eid = &_eid;
16365   u8 *locator_set_name = 0;
16366   u8 locator_set_name_set = 0;
16367   u32 vni = 0;
16368   u16 key_id = 0;
16369   u8 *key = 0;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "del"))
16376         {
16377           is_add = 0;
16378         }
16379       else if (unformat (input, "vni %d", &vni))
16380         {
16381           ;
16382         }
16383       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16384         {
16385           eid_set = 1;
16386         }
16387       else if (unformat (input, "locator-set %s", &locator_set_name))
16388         {
16389           locator_set_name_set = 1;
16390         }
16391       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16392         ;
16393       else if (unformat (input, "secret-key %_%v%_", &key))
16394         ;
16395       else
16396         break;
16397     }
16398
16399   if (locator_set_name_set == 0)
16400     {
16401       errmsg ("missing locator-set name");
16402       return -99;
16403     }
16404
16405   if (0 == eid_set)
16406     {
16407       errmsg ("EID address not set!");
16408       vec_free (locator_set_name);
16409       return -99;
16410     }
16411
16412   if (key && (0 == key_id))
16413     {
16414       errmsg ("invalid key_id!");
16415       return -99;
16416     }
16417
16418   if (vec_len (key) > 64)
16419     {
16420       errmsg ("key too long");
16421       vec_free (key);
16422       return -99;
16423     }
16424
16425   if (vec_len (locator_set_name) > 64)
16426     {
16427       errmsg ("locator-set name too long");
16428       vec_free (locator_set_name);
16429       return -99;
16430     }
16431   vec_add1 (locator_set_name, 0);
16432
16433   /* Construct the API message */
16434   M (ONE_ADD_DEL_LOCAL_EID, mp);
16435
16436   mp->is_add = is_add;
16437   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16438   mp->eid_type = eid->type;
16439   mp->prefix_len = eid->len;
16440   mp->vni = clib_host_to_net_u32 (vni);
16441   mp->key_id = clib_host_to_net_u16 (key_id);
16442   clib_memcpy (mp->locator_set_name, locator_set_name,
16443                vec_len (locator_set_name));
16444   clib_memcpy (mp->key, key, vec_len (key));
16445
16446   vec_free (locator_set_name);
16447   vec_free (key);
16448
16449   /* send it... */
16450   S (mp);
16451
16452   /* Wait for a reply... */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16458
16459 static int
16460 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16461 {
16462   u32 dp_table = 0, vni = 0;;
16463   unformat_input_t *input = vam->input;
16464   vl_api_gpe_add_del_fwd_entry_t *mp;
16465   u8 is_add = 1;
16466   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16467   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16468   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16469   u32 action = ~0, w;
16470   ip4_address_t rmt_rloc4, lcl_rloc4;
16471   ip6_address_t rmt_rloc6, lcl_rloc6;
16472   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16473   int ret;
16474
16475   memset (&rloc, 0, sizeof (rloc));
16476
16477   /* Parse args required to build the message */
16478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16479     {
16480       if (unformat (input, "del"))
16481         is_add = 0;
16482       else if (unformat (input, "add"))
16483         is_add = 1;
16484       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16485         {
16486           rmt_eid_set = 1;
16487         }
16488       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16489         {
16490           lcl_eid_set = 1;
16491         }
16492       else if (unformat (input, "vrf %d", &dp_table))
16493         ;
16494       else if (unformat (input, "bd %d", &dp_table))
16495         ;
16496       else if (unformat (input, "vni %d", &vni))
16497         ;
16498       else if (unformat (input, "w %d", &w))
16499         {
16500           if (!curr_rloc)
16501             {
16502               errmsg ("No RLOC configured for setting priority/weight!");
16503               return -99;
16504             }
16505           curr_rloc->weight = w;
16506         }
16507       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16508                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16509         {
16510           rloc.is_ip4 = 1;
16511
16512           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16513           rloc.weight = 0;
16514           vec_add1 (lcl_locs, rloc);
16515
16516           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16517           vec_add1 (rmt_locs, rloc);
16518           /* weight saved in rmt loc */
16519           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16520         }
16521       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16522                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16523         {
16524           rloc.is_ip4 = 0;
16525           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16526           rloc.weight = 0;
16527           vec_add1 (lcl_locs, rloc);
16528
16529           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16530           vec_add1 (rmt_locs, rloc);
16531           /* weight saved in rmt loc */
16532           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16533         }
16534       else if (unformat (input, "action %d", &action))
16535         {
16536           ;
16537         }
16538       else
16539         {
16540           clib_warning ("parse error '%U'", format_unformat_error, input);
16541           return -99;
16542         }
16543     }
16544
16545   if (!rmt_eid_set)
16546     {
16547       errmsg ("remote eid addresses not set");
16548       return -99;
16549     }
16550
16551   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16552     {
16553       errmsg ("eid types don't match");
16554       return -99;
16555     }
16556
16557   if (0 == rmt_locs && (u32) ~ 0 == action)
16558     {
16559       errmsg ("action not set for negative mapping");
16560       return -99;
16561     }
16562
16563   /* Construct the API message */
16564   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16565       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16566
16567   mp->is_add = is_add;
16568   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16569   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16570   mp->eid_type = rmt_eid->type;
16571   mp->dp_table = clib_host_to_net_u32 (dp_table);
16572   mp->vni = clib_host_to_net_u32 (vni);
16573   mp->rmt_len = rmt_eid->len;
16574   mp->lcl_len = lcl_eid->len;
16575   mp->action = action;
16576
16577   if (0 != rmt_locs && 0 != lcl_locs)
16578     {
16579       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16580       clib_memcpy (mp->locs, lcl_locs,
16581                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16582
16583       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16584       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16585                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16586     }
16587   vec_free (lcl_locs);
16588   vec_free (rmt_locs);
16589
16590   /* send it... */
16591   S (mp);
16592
16593   /* Wait for a reply... */
16594   W (ret);
16595   return ret;
16596 }
16597
16598 static int
16599 api_one_add_del_map_server (vat_main_t * vam)
16600 {
16601   unformat_input_t *input = vam->input;
16602   vl_api_one_add_del_map_server_t *mp;
16603   u8 is_add = 1;
16604   u8 ipv4_set = 0;
16605   u8 ipv6_set = 0;
16606   ip4_address_t ipv4;
16607   ip6_address_t ipv6;
16608   int ret;
16609
16610   /* Parse args required to build the message */
16611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16612     {
16613       if (unformat (input, "del"))
16614         {
16615           is_add = 0;
16616         }
16617       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16618         {
16619           ipv4_set = 1;
16620         }
16621       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16622         {
16623           ipv6_set = 1;
16624         }
16625       else
16626         break;
16627     }
16628
16629   if (ipv4_set && ipv6_set)
16630     {
16631       errmsg ("both eid v4 and v6 addresses set");
16632       return -99;
16633     }
16634
16635   if (!ipv4_set && !ipv6_set)
16636     {
16637       errmsg ("eid addresses not set");
16638       return -99;
16639     }
16640
16641   /* Construct the API message */
16642   M (ONE_ADD_DEL_MAP_SERVER, mp);
16643
16644   mp->is_add = is_add;
16645   if (ipv6_set)
16646     {
16647       mp->is_ipv6 = 1;
16648       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16649     }
16650   else
16651     {
16652       mp->is_ipv6 = 0;
16653       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16654     }
16655
16656   /* send it... */
16657   S (mp);
16658
16659   /* Wait for a reply... */
16660   W (ret);
16661   return ret;
16662 }
16663
16664 #define api_lisp_add_del_map_server api_one_add_del_map_server
16665
16666 static int
16667 api_one_add_del_map_resolver (vat_main_t * vam)
16668 {
16669   unformat_input_t *input = vam->input;
16670   vl_api_one_add_del_map_resolver_t *mp;
16671   u8 is_add = 1;
16672   u8 ipv4_set = 0;
16673   u8 ipv6_set = 0;
16674   ip4_address_t ipv4;
16675   ip6_address_t ipv6;
16676   int ret;
16677
16678   /* Parse args required to build the message */
16679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16680     {
16681       if (unformat (input, "del"))
16682         {
16683           is_add = 0;
16684         }
16685       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16686         {
16687           ipv4_set = 1;
16688         }
16689       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16690         {
16691           ipv6_set = 1;
16692         }
16693       else
16694         break;
16695     }
16696
16697   if (ipv4_set && ipv6_set)
16698     {
16699       errmsg ("both eid v4 and v6 addresses set");
16700       return -99;
16701     }
16702
16703   if (!ipv4_set && !ipv6_set)
16704     {
16705       errmsg ("eid addresses not set");
16706       return -99;
16707     }
16708
16709   /* Construct the API message */
16710   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16711
16712   mp->is_add = is_add;
16713   if (ipv6_set)
16714     {
16715       mp->is_ipv6 = 1;
16716       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16717     }
16718   else
16719     {
16720       mp->is_ipv6 = 0;
16721       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16722     }
16723
16724   /* send it... */
16725   S (mp);
16726
16727   /* Wait for a reply... */
16728   W (ret);
16729   return ret;
16730 }
16731
16732 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16733
16734 static int
16735 api_lisp_gpe_enable_disable (vat_main_t * vam)
16736 {
16737   unformat_input_t *input = vam->input;
16738   vl_api_gpe_enable_disable_t *mp;
16739   u8 is_set = 0;
16740   u8 is_en = 1;
16741   int ret;
16742
16743   /* Parse args required to build the message */
16744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16745     {
16746       if (unformat (input, "enable"))
16747         {
16748           is_set = 1;
16749           is_en = 1;
16750         }
16751       else if (unformat (input, "disable"))
16752         {
16753           is_set = 1;
16754           is_en = 0;
16755         }
16756       else
16757         break;
16758     }
16759
16760   if (is_set == 0)
16761     {
16762       errmsg ("Value not set");
16763       return -99;
16764     }
16765
16766   /* Construct the API message */
16767   M (GPE_ENABLE_DISABLE, mp);
16768
16769   mp->is_en = is_en;
16770
16771   /* send it... */
16772   S (mp);
16773
16774   /* Wait for a reply... */
16775   W (ret);
16776   return ret;
16777 }
16778
16779 static int
16780 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16781 {
16782   unformat_input_t *input = vam->input;
16783   vl_api_one_rloc_probe_enable_disable_t *mp;
16784   u8 is_set = 0;
16785   u8 is_en = 0;
16786   int ret;
16787
16788   /* Parse args required to build the message */
16789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16790     {
16791       if (unformat (input, "enable"))
16792         {
16793           is_set = 1;
16794           is_en = 1;
16795         }
16796       else if (unformat (input, "disable"))
16797         is_set = 1;
16798       else
16799         break;
16800     }
16801
16802   if (!is_set)
16803     {
16804       errmsg ("Value not set");
16805       return -99;
16806     }
16807
16808   /* Construct the API message */
16809   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16810
16811   mp->is_enabled = is_en;
16812
16813   /* send it... */
16814   S (mp);
16815
16816   /* Wait for a reply... */
16817   W (ret);
16818   return ret;
16819 }
16820
16821 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16822
16823 static int
16824 api_one_map_register_enable_disable (vat_main_t * vam)
16825 {
16826   unformat_input_t *input = vam->input;
16827   vl_api_one_map_register_enable_disable_t *mp;
16828   u8 is_set = 0;
16829   u8 is_en = 0;
16830   int ret;
16831
16832   /* Parse args required to build the message */
16833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16834     {
16835       if (unformat (input, "enable"))
16836         {
16837           is_set = 1;
16838           is_en = 1;
16839         }
16840       else if (unformat (input, "disable"))
16841         is_set = 1;
16842       else
16843         break;
16844     }
16845
16846   if (!is_set)
16847     {
16848       errmsg ("Value not set");
16849       return -99;
16850     }
16851
16852   /* Construct the API message */
16853   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16854
16855   mp->is_enabled = is_en;
16856
16857   /* send it... */
16858   S (mp);
16859
16860   /* Wait for a reply... */
16861   W (ret);
16862   return ret;
16863 }
16864
16865 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16866
16867 static int
16868 api_one_enable_disable (vat_main_t * vam)
16869 {
16870   unformat_input_t *input = vam->input;
16871   vl_api_one_enable_disable_t *mp;
16872   u8 is_set = 0;
16873   u8 is_en = 0;
16874   int ret;
16875
16876   /* Parse args required to build the message */
16877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16878     {
16879       if (unformat (input, "enable"))
16880         {
16881           is_set = 1;
16882           is_en = 1;
16883         }
16884       else if (unformat (input, "disable"))
16885         {
16886           is_set = 1;
16887         }
16888       else
16889         break;
16890     }
16891
16892   if (!is_set)
16893     {
16894       errmsg ("Value not set");
16895       return -99;
16896     }
16897
16898   /* Construct the API message */
16899   M (ONE_ENABLE_DISABLE, mp);
16900
16901   mp->is_en = is_en;
16902
16903   /* send it... */
16904   S (mp);
16905
16906   /* Wait for a reply... */
16907   W (ret);
16908   return ret;
16909 }
16910
16911 #define api_lisp_enable_disable api_one_enable_disable
16912
16913 static int
16914 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16915 {
16916   unformat_input_t *input = vam->input;
16917   vl_api_one_enable_disable_xtr_mode_t *mp;
16918   u8 is_set = 0;
16919   u8 is_en = 0;
16920   int ret;
16921
16922   /* Parse args required to build the message */
16923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16924     {
16925       if (unformat (input, "enable"))
16926         {
16927           is_set = 1;
16928           is_en = 1;
16929         }
16930       else if (unformat (input, "disable"))
16931         {
16932           is_set = 1;
16933         }
16934       else
16935         break;
16936     }
16937
16938   if (!is_set)
16939     {
16940       errmsg ("Value not set");
16941       return -99;
16942     }
16943
16944   /* Construct the API message */
16945   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16946
16947   mp->is_en = is_en;
16948
16949   /* send it... */
16950   S (mp);
16951
16952   /* Wait for a reply... */
16953   W (ret);
16954   return ret;
16955 }
16956
16957 static int
16958 api_one_show_xtr_mode (vat_main_t * vam)
16959 {
16960   vl_api_one_show_xtr_mode_t *mp;
16961   int ret;
16962
16963   /* Construct the API message */
16964   M (ONE_SHOW_XTR_MODE, mp);
16965
16966   /* send it... */
16967   S (mp);
16968
16969   /* Wait for a reply... */
16970   W (ret);
16971   return ret;
16972 }
16973
16974 static int
16975 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16976 {
16977   unformat_input_t *input = vam->input;
16978   vl_api_one_enable_disable_pitr_mode_t *mp;
16979   u8 is_set = 0;
16980   u8 is_en = 0;
16981   int ret;
16982
16983   /* Parse args required to build the message */
16984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16985     {
16986       if (unformat (input, "enable"))
16987         {
16988           is_set = 1;
16989           is_en = 1;
16990         }
16991       else if (unformat (input, "disable"))
16992         {
16993           is_set = 1;
16994         }
16995       else
16996         break;
16997     }
16998
16999   if (!is_set)
17000     {
17001       errmsg ("Value not set");
17002       return -99;
17003     }
17004
17005   /* Construct the API message */
17006   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17007
17008   mp->is_en = is_en;
17009
17010   /* send it... */
17011   S (mp);
17012
17013   /* Wait for a reply... */
17014   W (ret);
17015   return ret;
17016 }
17017
17018 static int
17019 api_one_show_pitr_mode (vat_main_t * vam)
17020 {
17021   vl_api_one_show_pitr_mode_t *mp;
17022   int ret;
17023
17024   /* Construct the API message */
17025   M (ONE_SHOW_PITR_MODE, mp);
17026
17027   /* send it... */
17028   S (mp);
17029
17030   /* Wait for a reply... */
17031   W (ret);
17032   return ret;
17033 }
17034
17035 static int
17036 api_one_enable_disable_petr_mode (vat_main_t * vam)
17037 {
17038   unformat_input_t *input = vam->input;
17039   vl_api_one_enable_disable_petr_mode_t *mp;
17040   u8 is_set = 0;
17041   u8 is_en = 0;
17042   int ret;
17043
17044   /* Parse args required to build the message */
17045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17046     {
17047       if (unformat (input, "enable"))
17048         {
17049           is_set = 1;
17050           is_en = 1;
17051         }
17052       else if (unformat (input, "disable"))
17053         {
17054           is_set = 1;
17055         }
17056       else
17057         break;
17058     }
17059
17060   if (!is_set)
17061     {
17062       errmsg ("Value not set");
17063       return -99;
17064     }
17065
17066   /* Construct the API message */
17067   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17068
17069   mp->is_en = is_en;
17070
17071   /* send it... */
17072   S (mp);
17073
17074   /* Wait for a reply... */
17075   W (ret);
17076   return ret;
17077 }
17078
17079 static int
17080 api_one_show_petr_mode (vat_main_t * vam)
17081 {
17082   vl_api_one_show_petr_mode_t *mp;
17083   int ret;
17084
17085   /* Construct the API message */
17086   M (ONE_SHOW_PETR_MODE, mp);
17087
17088   /* send it... */
17089   S (mp);
17090
17091   /* Wait for a reply... */
17092   W (ret);
17093   return ret;
17094 }
17095
17096 static int
17097 api_show_one_map_register_state (vat_main_t * vam)
17098 {
17099   vl_api_show_one_map_register_state_t *mp;
17100   int ret;
17101
17102   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17103
17104   /* send */
17105   S (mp);
17106
17107   /* wait for reply */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 #define api_show_lisp_map_register_state api_show_one_map_register_state
17113
17114 static int
17115 api_show_one_rloc_probe_state (vat_main_t * vam)
17116 {
17117   vl_api_show_one_rloc_probe_state_t *mp;
17118   int ret;
17119
17120   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17121
17122   /* send */
17123   S (mp);
17124
17125   /* wait for reply */
17126   W (ret);
17127   return ret;
17128 }
17129
17130 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17131
17132 static int
17133 api_one_add_del_ndp_entry (vat_main_t * vam)
17134 {
17135   vl_api_one_add_del_ndp_entry_t *mp;
17136   unformat_input_t *input = vam->input;
17137   u8 is_add = 1;
17138   u8 mac_set = 0;
17139   u8 bd_set = 0;
17140   u8 ip_set = 0;
17141   u8 mac[6] = { 0, };
17142   u8 ip6[16] = { 0, };
17143   u32 bd = ~0;
17144   int ret;
17145
17146   /* Parse args required to build the message */
17147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17148     {
17149       if (unformat (input, "del"))
17150         is_add = 0;
17151       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17152         mac_set = 1;
17153       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17154         ip_set = 1;
17155       else if (unformat (input, "bd %d", &bd))
17156         bd_set = 1;
17157       else
17158         {
17159           errmsg ("parse error '%U'", format_unformat_error, input);
17160           return -99;
17161         }
17162     }
17163
17164   if (!bd_set || !ip_set || (!mac_set && is_add))
17165     {
17166       errmsg ("Missing BD, IP or MAC!");
17167       return -99;
17168     }
17169
17170   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17171   mp->is_add = is_add;
17172   clib_memcpy (mp->mac, mac, 6);
17173   mp->bd = clib_host_to_net_u32 (bd);
17174   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17175
17176   /* send */
17177   S (mp);
17178
17179   /* wait for reply */
17180   W (ret);
17181   return ret;
17182 }
17183
17184 static int
17185 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17186 {
17187   vl_api_one_add_del_l2_arp_entry_t *mp;
17188   unformat_input_t *input = vam->input;
17189   u8 is_add = 1;
17190   u8 mac_set = 0;
17191   u8 bd_set = 0;
17192   u8 ip_set = 0;
17193   u8 mac[6] = { 0, };
17194   u32 ip4 = 0, bd = ~0;
17195   int ret;
17196
17197   /* Parse args required to build the message */
17198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17199     {
17200       if (unformat (input, "del"))
17201         is_add = 0;
17202       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17203         mac_set = 1;
17204       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17205         ip_set = 1;
17206       else if (unformat (input, "bd %d", &bd))
17207         bd_set = 1;
17208       else
17209         {
17210           errmsg ("parse error '%U'", format_unformat_error, input);
17211           return -99;
17212         }
17213     }
17214
17215   if (!bd_set || !ip_set || (!mac_set && is_add))
17216     {
17217       errmsg ("Missing BD, IP or MAC!");
17218       return -99;
17219     }
17220
17221   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17222   mp->is_add = is_add;
17223   clib_memcpy (mp->mac, mac, 6);
17224   mp->bd = clib_host_to_net_u32 (bd);
17225   mp->ip4 = ip4;
17226
17227   /* send */
17228   S (mp);
17229
17230   /* wait for reply */
17231   W (ret);
17232   return ret;
17233 }
17234
17235 static int
17236 api_one_ndp_bd_get (vat_main_t * vam)
17237 {
17238   vl_api_one_ndp_bd_get_t *mp;
17239   int ret;
17240
17241   M (ONE_NDP_BD_GET, mp);
17242
17243   /* send */
17244   S (mp);
17245
17246   /* wait for reply */
17247   W (ret);
17248   return ret;
17249 }
17250
17251 static int
17252 api_one_ndp_entries_get (vat_main_t * vam)
17253 {
17254   vl_api_one_ndp_entries_get_t *mp;
17255   unformat_input_t *input = vam->input;
17256   u8 bd_set = 0;
17257   u32 bd = ~0;
17258   int ret;
17259
17260   /* Parse args required to build the message */
17261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17262     {
17263       if (unformat (input, "bd %d", &bd))
17264         bd_set = 1;
17265       else
17266         {
17267           errmsg ("parse error '%U'", format_unformat_error, input);
17268           return -99;
17269         }
17270     }
17271
17272   if (!bd_set)
17273     {
17274       errmsg ("Expected bridge domain!");
17275       return -99;
17276     }
17277
17278   M (ONE_NDP_ENTRIES_GET, mp);
17279   mp->bd = clib_host_to_net_u32 (bd);
17280
17281   /* send */
17282   S (mp);
17283
17284   /* wait for reply */
17285   W (ret);
17286   return ret;
17287 }
17288
17289 static int
17290 api_one_l2_arp_bd_get (vat_main_t * vam)
17291 {
17292   vl_api_one_l2_arp_bd_get_t *mp;
17293   int ret;
17294
17295   M (ONE_L2_ARP_BD_GET, mp);
17296
17297   /* send */
17298   S (mp);
17299
17300   /* wait for reply */
17301   W (ret);
17302   return ret;
17303 }
17304
17305 static int
17306 api_one_l2_arp_entries_get (vat_main_t * vam)
17307 {
17308   vl_api_one_l2_arp_entries_get_t *mp;
17309   unformat_input_t *input = vam->input;
17310   u8 bd_set = 0;
17311   u32 bd = ~0;
17312   int ret;
17313
17314   /* Parse args required to build the message */
17315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17316     {
17317       if (unformat (input, "bd %d", &bd))
17318         bd_set = 1;
17319       else
17320         {
17321           errmsg ("parse error '%U'", format_unformat_error, input);
17322           return -99;
17323         }
17324     }
17325
17326   if (!bd_set)
17327     {
17328       errmsg ("Expected bridge domain!");
17329       return -99;
17330     }
17331
17332   M (ONE_L2_ARP_ENTRIES_GET, mp);
17333   mp->bd = clib_host_to_net_u32 (bd);
17334
17335   /* send */
17336   S (mp);
17337
17338   /* wait for reply */
17339   W (ret);
17340   return ret;
17341 }
17342
17343 static int
17344 api_one_stats_enable_disable (vat_main_t * vam)
17345 {
17346   vl_api_one_stats_enable_disable_t *mp;
17347   unformat_input_t *input = vam->input;
17348   u8 is_set = 0;
17349   u8 is_en = 0;
17350   int ret;
17351
17352   /* Parse args required to build the message */
17353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17354     {
17355       if (unformat (input, "enable"))
17356         {
17357           is_set = 1;
17358           is_en = 1;
17359         }
17360       else if (unformat (input, "disable"))
17361         {
17362           is_set = 1;
17363         }
17364       else
17365         break;
17366     }
17367
17368   if (!is_set)
17369     {
17370       errmsg ("Value not set");
17371       return -99;
17372     }
17373
17374   M (ONE_STATS_ENABLE_DISABLE, mp);
17375   mp->is_en = is_en;
17376
17377   /* send */
17378   S (mp);
17379
17380   /* wait for reply */
17381   W (ret);
17382   return ret;
17383 }
17384
17385 static int
17386 api_show_one_stats_enable_disable (vat_main_t * vam)
17387 {
17388   vl_api_show_one_stats_enable_disable_t *mp;
17389   int ret;
17390
17391   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17392
17393   /* send */
17394   S (mp);
17395
17396   /* wait for reply */
17397   W (ret);
17398   return ret;
17399 }
17400
17401 static int
17402 api_show_one_map_request_mode (vat_main_t * vam)
17403 {
17404   vl_api_show_one_map_request_mode_t *mp;
17405   int ret;
17406
17407   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17408
17409   /* send */
17410   S (mp);
17411
17412   /* wait for reply */
17413   W (ret);
17414   return ret;
17415 }
17416
17417 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17418
17419 static int
17420 api_one_map_request_mode (vat_main_t * vam)
17421 {
17422   unformat_input_t *input = vam->input;
17423   vl_api_one_map_request_mode_t *mp;
17424   u8 mode = 0;
17425   int ret;
17426
17427   /* Parse args required to build the message */
17428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (input, "dst-only"))
17431         mode = 0;
17432       else if (unformat (input, "src-dst"))
17433         mode = 1;
17434       else
17435         {
17436           errmsg ("parse error '%U'", format_unformat_error, input);
17437           return -99;
17438         }
17439     }
17440
17441   M (ONE_MAP_REQUEST_MODE, mp);
17442
17443   mp->mode = mode;
17444
17445   /* send */
17446   S (mp);
17447
17448   /* wait for reply */
17449   W (ret);
17450   return ret;
17451 }
17452
17453 #define api_lisp_map_request_mode api_one_map_request_mode
17454
17455 /**
17456  * Enable/disable ONE proxy ITR.
17457  *
17458  * @param vam vpp API test context
17459  * @return return code
17460  */
17461 static int
17462 api_one_pitr_set_locator_set (vat_main_t * vam)
17463 {
17464   u8 ls_name_set = 0;
17465   unformat_input_t *input = vam->input;
17466   vl_api_one_pitr_set_locator_set_t *mp;
17467   u8 is_add = 1;
17468   u8 *ls_name = 0;
17469   int ret;
17470
17471   /* Parse args required to build the message */
17472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17473     {
17474       if (unformat (input, "del"))
17475         is_add = 0;
17476       else if (unformat (input, "locator-set %s", &ls_name))
17477         ls_name_set = 1;
17478       else
17479         {
17480           errmsg ("parse error '%U'", format_unformat_error, input);
17481           return -99;
17482         }
17483     }
17484
17485   if (!ls_name_set)
17486     {
17487       errmsg ("locator-set name not set!");
17488       return -99;
17489     }
17490
17491   M (ONE_PITR_SET_LOCATOR_SET, mp);
17492
17493   mp->is_add = is_add;
17494   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17495   vec_free (ls_name);
17496
17497   /* send */
17498   S (mp);
17499
17500   /* wait for reply */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17506
17507 static int
17508 api_one_nsh_set_locator_set (vat_main_t * vam)
17509 {
17510   u8 ls_name_set = 0;
17511   unformat_input_t *input = vam->input;
17512   vl_api_one_nsh_set_locator_set_t *mp;
17513   u8 is_add = 1;
17514   u8 *ls_name = 0;
17515   int ret;
17516
17517   /* Parse args required to build the message */
17518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17519     {
17520       if (unformat (input, "del"))
17521         is_add = 0;
17522       else if (unformat (input, "ls %s", &ls_name))
17523         ls_name_set = 1;
17524       else
17525         {
17526           errmsg ("parse error '%U'", format_unformat_error, input);
17527           return -99;
17528         }
17529     }
17530
17531   if (!ls_name_set && is_add)
17532     {
17533       errmsg ("locator-set name not set!");
17534       return -99;
17535     }
17536
17537   M (ONE_NSH_SET_LOCATOR_SET, mp);
17538
17539   mp->is_add = is_add;
17540   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17541   vec_free (ls_name);
17542
17543   /* send */
17544   S (mp);
17545
17546   /* wait for reply */
17547   W (ret);
17548   return ret;
17549 }
17550
17551 static int
17552 api_show_one_pitr (vat_main_t * vam)
17553 {
17554   vl_api_show_one_pitr_t *mp;
17555   int ret;
17556
17557   if (!vam->json_output)
17558     {
17559       print (vam->ofp, "%=20s", "lisp status:");
17560     }
17561
17562   M (SHOW_ONE_PITR, mp);
17563   /* send it... */
17564   S (mp);
17565
17566   /* Wait for a reply... */
17567   W (ret);
17568   return ret;
17569 }
17570
17571 #define api_show_lisp_pitr api_show_one_pitr
17572
17573 static int
17574 api_one_use_petr (vat_main_t * vam)
17575 {
17576   unformat_input_t *input = vam->input;
17577   vl_api_one_use_petr_t *mp;
17578   u8 is_add = 0;
17579   ip_address_t ip;
17580   int ret;
17581
17582   memset (&ip, 0, sizeof (ip));
17583
17584   /* Parse args required to build the message */
17585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17586     {
17587       if (unformat (input, "disable"))
17588         is_add = 0;
17589       else
17590         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17591         {
17592           is_add = 1;
17593           ip_addr_version (&ip) = IP4;
17594         }
17595       else
17596         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17597         {
17598           is_add = 1;
17599           ip_addr_version (&ip) = IP6;
17600         }
17601       else
17602         {
17603           errmsg ("parse error '%U'", format_unformat_error, input);
17604           return -99;
17605         }
17606     }
17607
17608   M (ONE_USE_PETR, mp);
17609
17610   mp->is_add = is_add;
17611   if (is_add)
17612     {
17613       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17614       if (mp->is_ip4)
17615         clib_memcpy (mp->address, &ip, 4);
17616       else
17617         clib_memcpy (mp->address, &ip, 16);
17618     }
17619
17620   /* send */
17621   S (mp);
17622
17623   /* wait for reply */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 #define api_lisp_use_petr api_one_use_petr
17629
17630 static int
17631 api_show_one_nsh_mapping (vat_main_t * vam)
17632 {
17633   vl_api_show_one_use_petr_t *mp;
17634   int ret;
17635
17636   if (!vam->json_output)
17637     {
17638       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17639     }
17640
17641   M (SHOW_ONE_NSH_MAPPING, mp);
17642   /* send it... */
17643   S (mp);
17644
17645   /* Wait for a reply... */
17646   W (ret);
17647   return ret;
17648 }
17649
17650 static int
17651 api_show_one_use_petr (vat_main_t * vam)
17652 {
17653   vl_api_show_one_use_petr_t *mp;
17654   int ret;
17655
17656   if (!vam->json_output)
17657     {
17658       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17659     }
17660
17661   M (SHOW_ONE_USE_PETR, mp);
17662   /* send it... */
17663   S (mp);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 #define api_show_lisp_use_petr api_show_one_use_petr
17671
17672 /**
17673  * Add/delete mapping between vni and vrf
17674  */
17675 static int
17676 api_one_eid_table_add_del_map (vat_main_t * vam)
17677 {
17678   unformat_input_t *input = vam->input;
17679   vl_api_one_eid_table_add_del_map_t *mp;
17680   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17681   u32 vni, vrf, bd_index;
17682   int ret;
17683
17684   /* Parse args required to build the message */
17685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17686     {
17687       if (unformat (input, "del"))
17688         is_add = 0;
17689       else if (unformat (input, "vrf %d", &vrf))
17690         vrf_set = 1;
17691       else if (unformat (input, "bd_index %d", &bd_index))
17692         bd_index_set = 1;
17693       else if (unformat (input, "vni %d", &vni))
17694         vni_set = 1;
17695       else
17696         break;
17697     }
17698
17699   if (!vni_set || (!vrf_set && !bd_index_set))
17700     {
17701       errmsg ("missing arguments!");
17702       return -99;
17703     }
17704
17705   if (vrf_set && bd_index_set)
17706     {
17707       errmsg ("error: both vrf and bd entered!");
17708       return -99;
17709     }
17710
17711   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17712
17713   mp->is_add = is_add;
17714   mp->vni = htonl (vni);
17715   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17716   mp->is_l2 = bd_index_set;
17717
17718   /* send */
17719   S (mp);
17720
17721   /* wait for reply */
17722   W (ret);
17723   return ret;
17724 }
17725
17726 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17727
17728 uword
17729 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17730 {
17731   u32 *action = va_arg (*args, u32 *);
17732   u8 *s = 0;
17733
17734   if (unformat (input, "%s", &s))
17735     {
17736       if (!strcmp ((char *) s, "no-action"))
17737         action[0] = 0;
17738       else if (!strcmp ((char *) s, "natively-forward"))
17739         action[0] = 1;
17740       else if (!strcmp ((char *) s, "send-map-request"))
17741         action[0] = 2;
17742       else if (!strcmp ((char *) s, "drop"))
17743         action[0] = 3;
17744       else
17745         {
17746           clib_warning ("invalid action: '%s'", s);
17747           action[0] = 3;
17748         }
17749     }
17750   else
17751     return 0;
17752
17753   vec_free (s);
17754   return 1;
17755 }
17756
17757 /**
17758  * Add/del remote mapping to/from ONE control plane
17759  *
17760  * @param vam vpp API test context
17761  * @return return code
17762  */
17763 static int
17764 api_one_add_del_remote_mapping (vat_main_t * vam)
17765 {
17766   unformat_input_t *input = vam->input;
17767   vl_api_one_add_del_remote_mapping_t *mp;
17768   u32 vni = 0;
17769   lisp_eid_vat_t _eid, *eid = &_eid;
17770   lisp_eid_vat_t _seid, *seid = &_seid;
17771   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17772   u32 action = ~0, p, w, data_len;
17773   ip4_address_t rloc4;
17774   ip6_address_t rloc6;
17775   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17776   int ret;
17777
17778   memset (&rloc, 0, sizeof (rloc));
17779
17780   /* Parse args required to build the message */
17781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17782     {
17783       if (unformat (input, "del-all"))
17784         {
17785           del_all = 1;
17786         }
17787       else if (unformat (input, "del"))
17788         {
17789           is_add = 0;
17790         }
17791       else if (unformat (input, "add"))
17792         {
17793           is_add = 1;
17794         }
17795       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17796         {
17797           eid_set = 1;
17798         }
17799       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17800         {
17801           seid_set = 1;
17802         }
17803       else if (unformat (input, "vni %d", &vni))
17804         {
17805           ;
17806         }
17807       else if (unformat (input, "p %d w %d", &p, &w))
17808         {
17809           if (!curr_rloc)
17810             {
17811               errmsg ("No RLOC configured for setting priority/weight!");
17812               return -99;
17813             }
17814           curr_rloc->priority = p;
17815           curr_rloc->weight = w;
17816         }
17817       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17818         {
17819           rloc.is_ip4 = 1;
17820           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17821           vec_add1 (rlocs, rloc);
17822           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17823         }
17824       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17825         {
17826           rloc.is_ip4 = 0;
17827           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17828           vec_add1 (rlocs, rloc);
17829           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17830         }
17831       else if (unformat (input, "action %U",
17832                          unformat_negative_mapping_action, &action))
17833         {
17834           ;
17835         }
17836       else
17837         {
17838           clib_warning ("parse error '%U'", format_unformat_error, input);
17839           return -99;
17840         }
17841     }
17842
17843   if (0 == eid_set)
17844     {
17845       errmsg ("missing params!");
17846       return -99;
17847     }
17848
17849   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17850     {
17851       errmsg ("no action set for negative map-reply!");
17852       return -99;
17853     }
17854
17855   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17856
17857   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17858   mp->is_add = is_add;
17859   mp->vni = htonl (vni);
17860   mp->action = (u8) action;
17861   mp->is_src_dst = seid_set;
17862   mp->eid_len = eid->len;
17863   mp->seid_len = seid->len;
17864   mp->del_all = del_all;
17865   mp->eid_type = eid->type;
17866   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17867   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17868
17869   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17870   clib_memcpy (mp->rlocs, rlocs, data_len);
17871   vec_free (rlocs);
17872
17873   /* send it... */
17874   S (mp);
17875
17876   /* Wait for a reply... */
17877   W (ret);
17878   return ret;
17879 }
17880
17881 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17882
17883 /**
17884  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17885  * forwarding entries in data-plane accordingly.
17886  *
17887  * @param vam vpp API test context
17888  * @return return code
17889  */
17890 static int
17891 api_one_add_del_adjacency (vat_main_t * vam)
17892 {
17893   unformat_input_t *input = vam->input;
17894   vl_api_one_add_del_adjacency_t *mp;
17895   u32 vni = 0;
17896   ip4_address_t leid4, reid4;
17897   ip6_address_t leid6, reid6;
17898   u8 reid_mac[6] = { 0 };
17899   u8 leid_mac[6] = { 0 };
17900   u8 reid_type, leid_type;
17901   u32 leid_len = 0, reid_len = 0, len;
17902   u8 is_add = 1;
17903   int ret;
17904
17905   leid_type = reid_type = (u8) ~ 0;
17906
17907   /* Parse args required to build the message */
17908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17909     {
17910       if (unformat (input, "del"))
17911         {
17912           is_add = 0;
17913         }
17914       else if (unformat (input, "add"))
17915         {
17916           is_add = 1;
17917         }
17918       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17919                          &reid4, &len))
17920         {
17921           reid_type = 0;        /* ipv4 */
17922           reid_len = len;
17923         }
17924       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17925                          &reid6, &len))
17926         {
17927           reid_type = 1;        /* ipv6 */
17928           reid_len = len;
17929         }
17930       else if (unformat (input, "reid %U", unformat_ethernet_address,
17931                          reid_mac))
17932         {
17933           reid_type = 2;        /* mac */
17934         }
17935       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17936                          &leid4, &len))
17937         {
17938           leid_type = 0;        /* ipv4 */
17939           leid_len = len;
17940         }
17941       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17942                          &leid6, &len))
17943         {
17944           leid_type = 1;        /* ipv6 */
17945           leid_len = len;
17946         }
17947       else if (unformat (input, "leid %U", unformat_ethernet_address,
17948                          leid_mac))
17949         {
17950           leid_type = 2;        /* mac */
17951         }
17952       else if (unformat (input, "vni %d", &vni))
17953         {
17954           ;
17955         }
17956       else
17957         {
17958           errmsg ("parse error '%U'", format_unformat_error, input);
17959           return -99;
17960         }
17961     }
17962
17963   if ((u8) ~ 0 == reid_type)
17964     {
17965       errmsg ("missing params!");
17966       return -99;
17967     }
17968
17969   if (leid_type != reid_type)
17970     {
17971       errmsg ("remote and local EIDs are of different types!");
17972       return -99;
17973     }
17974
17975   M (ONE_ADD_DEL_ADJACENCY, mp);
17976   mp->is_add = is_add;
17977   mp->vni = htonl (vni);
17978   mp->leid_len = leid_len;
17979   mp->reid_len = reid_len;
17980   mp->eid_type = reid_type;
17981
17982   switch (mp->eid_type)
17983     {
17984     case 0:
17985       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17986       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17987       break;
17988     case 1:
17989       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17990       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17991       break;
17992     case 2:
17993       clib_memcpy (mp->leid, leid_mac, 6);
17994       clib_memcpy (mp->reid, reid_mac, 6);
17995       break;
17996     default:
17997       errmsg ("unknown EID type %d!", mp->eid_type);
17998       return 0;
17999     }
18000
18001   /* send it... */
18002   S (mp);
18003
18004   /* Wait for a reply... */
18005   W (ret);
18006   return ret;
18007 }
18008
18009 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18010
18011 uword
18012 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18013 {
18014   u32 *mode = va_arg (*args, u32 *);
18015
18016   if (unformat (input, "lisp"))
18017     *mode = 0;
18018   else if (unformat (input, "vxlan"))
18019     *mode = 1;
18020   else
18021     return 0;
18022
18023   return 1;
18024 }
18025
18026 static int
18027 api_gpe_get_encap_mode (vat_main_t * vam)
18028 {
18029   vl_api_gpe_get_encap_mode_t *mp;
18030   int ret;
18031
18032   /* Construct the API message */
18033   M (GPE_GET_ENCAP_MODE, mp);
18034
18035   /* send it... */
18036   S (mp);
18037
18038   /* Wait for a reply... */
18039   W (ret);
18040   return ret;
18041 }
18042
18043 static int
18044 api_gpe_set_encap_mode (vat_main_t * vam)
18045 {
18046   unformat_input_t *input = vam->input;
18047   vl_api_gpe_set_encap_mode_t *mp;
18048   int ret;
18049   u32 mode = 0;
18050
18051   /* Parse args required to build the message */
18052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18055         ;
18056       else
18057         break;
18058     }
18059
18060   /* Construct the API message */
18061   M (GPE_SET_ENCAP_MODE, mp);
18062
18063   mp->mode = mode;
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_lisp_gpe_add_del_iface (vat_main_t * vam)
18075 {
18076   unformat_input_t *input = vam->input;
18077   vl_api_gpe_add_del_iface_t *mp;
18078   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18079   u32 dp_table = 0, vni = 0;
18080   int ret;
18081
18082   /* Parse args required to build the message */
18083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18084     {
18085       if (unformat (input, "up"))
18086         {
18087           action_set = 1;
18088           is_add = 1;
18089         }
18090       else if (unformat (input, "down"))
18091         {
18092           action_set = 1;
18093           is_add = 0;
18094         }
18095       else if (unformat (input, "table_id %d", &dp_table))
18096         {
18097           dp_table_set = 1;
18098         }
18099       else if (unformat (input, "bd_id %d", &dp_table))
18100         {
18101           dp_table_set = 1;
18102           is_l2 = 1;
18103         }
18104       else if (unformat (input, "vni %d", &vni))
18105         {
18106           vni_set = 1;
18107         }
18108       else
18109         break;
18110     }
18111
18112   if (action_set == 0)
18113     {
18114       errmsg ("Action not set");
18115       return -99;
18116     }
18117   if (dp_table_set == 0 || vni_set == 0)
18118     {
18119       errmsg ("vni and dp_table must be set");
18120       return -99;
18121     }
18122
18123   /* Construct the API message */
18124   M (GPE_ADD_DEL_IFACE, mp);
18125
18126   mp->is_add = is_add;
18127   mp->dp_table = clib_host_to_net_u32 (dp_table);
18128   mp->is_l2 = is_l2;
18129   mp->vni = clib_host_to_net_u32 (vni);
18130
18131   /* send it... */
18132   S (mp);
18133
18134   /* Wait for a reply... */
18135   W (ret);
18136   return ret;
18137 }
18138
18139 static int
18140 api_one_map_register_fallback_threshold (vat_main_t * vam)
18141 {
18142   unformat_input_t *input = vam->input;
18143   vl_api_one_map_register_fallback_threshold_t *mp;
18144   u32 value = 0;
18145   u8 is_set = 0;
18146   int ret;
18147
18148   /* Parse args required to build the message */
18149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18150     {
18151       if (unformat (input, "%u", &value))
18152         is_set = 1;
18153       else
18154         {
18155           clib_warning ("parse error '%U'", format_unformat_error, input);
18156           return -99;
18157         }
18158     }
18159
18160   if (!is_set)
18161     {
18162       errmsg ("fallback threshold value is missing!");
18163       return -99;
18164     }
18165
18166   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18167   mp->value = clib_host_to_net_u32 (value);
18168
18169   /* send it... */
18170   S (mp);
18171
18172   /* Wait for a reply... */
18173   W (ret);
18174   return ret;
18175 }
18176
18177 static int
18178 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18179 {
18180   vl_api_show_one_map_register_fallback_threshold_t *mp;
18181   int ret;
18182
18183   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18184
18185   /* send it... */
18186   S (mp);
18187
18188   /* Wait for a reply... */
18189   W (ret);
18190   return ret;
18191 }
18192
18193 uword
18194 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18195 {
18196   u32 *proto = va_arg (*args, u32 *);
18197
18198   if (unformat (input, "udp"))
18199     *proto = 1;
18200   else if (unformat (input, "api"))
18201     *proto = 2;
18202   else
18203     return 0;
18204
18205   return 1;
18206 }
18207
18208 static int
18209 api_one_set_transport_protocol (vat_main_t * vam)
18210 {
18211   unformat_input_t *input = vam->input;
18212   vl_api_one_set_transport_protocol_t *mp;
18213   u8 is_set = 0;
18214   u32 protocol = 0;
18215   int ret;
18216
18217   /* Parse args required to build the message */
18218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18219     {
18220       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18221         is_set = 1;
18222       else
18223         {
18224           clib_warning ("parse error '%U'", format_unformat_error, input);
18225           return -99;
18226         }
18227     }
18228
18229   if (!is_set)
18230     {
18231       errmsg ("Transport protocol missing!");
18232       return -99;
18233     }
18234
18235   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18236   mp->protocol = (u8) protocol;
18237
18238   /* send it... */
18239   S (mp);
18240
18241   /* Wait for a reply... */
18242   W (ret);
18243   return ret;
18244 }
18245
18246 static int
18247 api_one_get_transport_protocol (vat_main_t * vam)
18248 {
18249   vl_api_one_get_transport_protocol_t *mp;
18250   int ret;
18251
18252   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18253
18254   /* send it... */
18255   S (mp);
18256
18257   /* Wait for a reply... */
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static int
18263 api_one_map_register_set_ttl (vat_main_t * vam)
18264 {
18265   unformat_input_t *input = vam->input;
18266   vl_api_one_map_register_set_ttl_t *mp;
18267   u32 ttl = 0;
18268   u8 is_set = 0;
18269   int ret;
18270
18271   /* Parse args required to build the message */
18272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18273     {
18274       if (unformat (input, "%u", &ttl))
18275         is_set = 1;
18276       else
18277         {
18278           clib_warning ("parse error '%U'", format_unformat_error, input);
18279           return -99;
18280         }
18281     }
18282
18283   if (!is_set)
18284     {
18285       errmsg ("TTL value missing!");
18286       return -99;
18287     }
18288
18289   M (ONE_MAP_REGISTER_SET_TTL, mp);
18290   mp->ttl = clib_host_to_net_u32 (ttl);
18291
18292   /* send it... */
18293   S (mp);
18294
18295   /* Wait for a reply... */
18296   W (ret);
18297   return ret;
18298 }
18299
18300 static int
18301 api_show_one_map_register_ttl (vat_main_t * vam)
18302 {
18303   vl_api_show_one_map_register_ttl_t *mp;
18304   int ret;
18305
18306   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18307
18308   /* send it... */
18309   S (mp);
18310
18311   /* Wait for a reply... */
18312   W (ret);
18313   return ret;
18314 }
18315
18316 /**
18317  * Add/del map request itr rlocs from ONE control plane and updates
18318  *
18319  * @param vam vpp API test context
18320  * @return return code
18321  */
18322 static int
18323 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18324 {
18325   unformat_input_t *input = vam->input;
18326   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18327   u8 *locator_set_name = 0;
18328   u8 locator_set_name_set = 0;
18329   u8 is_add = 1;
18330   int ret;
18331
18332   /* Parse args required to build the message */
18333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18334     {
18335       if (unformat (input, "del"))
18336         {
18337           is_add = 0;
18338         }
18339       else if (unformat (input, "%_%v%_", &locator_set_name))
18340         {
18341           locator_set_name_set = 1;
18342         }
18343       else
18344         {
18345           clib_warning ("parse error '%U'", format_unformat_error, input);
18346           return -99;
18347         }
18348     }
18349
18350   if (is_add && !locator_set_name_set)
18351     {
18352       errmsg ("itr-rloc is not set!");
18353       return -99;
18354     }
18355
18356   if (is_add && vec_len (locator_set_name) > 64)
18357     {
18358       errmsg ("itr-rloc locator-set name too long");
18359       vec_free (locator_set_name);
18360       return -99;
18361     }
18362
18363   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18364   mp->is_add = is_add;
18365   if (is_add)
18366     {
18367       clib_memcpy (mp->locator_set_name, locator_set_name,
18368                    vec_len (locator_set_name));
18369     }
18370   else
18371     {
18372       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18373     }
18374   vec_free (locator_set_name);
18375
18376   /* send it... */
18377   S (mp);
18378
18379   /* Wait for a reply... */
18380   W (ret);
18381   return ret;
18382 }
18383
18384 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18385
18386 static int
18387 api_one_locator_dump (vat_main_t * vam)
18388 {
18389   unformat_input_t *input = vam->input;
18390   vl_api_one_locator_dump_t *mp;
18391   vl_api_control_ping_t *mp_ping;
18392   u8 is_index_set = 0, is_name_set = 0;
18393   u8 *ls_name = 0;
18394   u32 ls_index = ~0;
18395   int ret;
18396
18397   /* Parse args required to build the message */
18398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18399     {
18400       if (unformat (input, "ls_name %_%v%_", &ls_name))
18401         {
18402           is_name_set = 1;
18403         }
18404       else if (unformat (input, "ls_index %d", &ls_index))
18405         {
18406           is_index_set = 1;
18407         }
18408       else
18409         {
18410           errmsg ("parse error '%U'", format_unformat_error, input);
18411           return -99;
18412         }
18413     }
18414
18415   if (!is_index_set && !is_name_set)
18416     {
18417       errmsg ("error: expected one of index or name!");
18418       return -99;
18419     }
18420
18421   if (is_index_set && is_name_set)
18422     {
18423       errmsg ("error: only one param expected!");
18424       return -99;
18425     }
18426
18427   if (vec_len (ls_name) > 62)
18428     {
18429       errmsg ("error: locator set name too long!");
18430       return -99;
18431     }
18432
18433   if (!vam->json_output)
18434     {
18435       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18436     }
18437
18438   M (ONE_LOCATOR_DUMP, mp);
18439   mp->is_index_set = is_index_set;
18440
18441   if (is_index_set)
18442     mp->ls_index = clib_host_to_net_u32 (ls_index);
18443   else
18444     {
18445       vec_add1 (ls_name, 0);
18446       strncpy ((char *) mp->ls_name, (char *) ls_name,
18447                sizeof (mp->ls_name) - 1);
18448     }
18449
18450   /* send it... */
18451   S (mp);
18452
18453   /* Use a control ping for synchronization */
18454   MPING (CONTROL_PING, mp_ping);
18455   S (mp_ping);
18456
18457   /* Wait for a reply... */
18458   W (ret);
18459   return ret;
18460 }
18461
18462 #define api_lisp_locator_dump api_one_locator_dump
18463
18464 static int
18465 api_one_locator_set_dump (vat_main_t * vam)
18466 {
18467   vl_api_one_locator_set_dump_t *mp;
18468   vl_api_control_ping_t *mp_ping;
18469   unformat_input_t *input = vam->input;
18470   u8 filter = 0;
18471   int ret;
18472
18473   /* Parse args required to build the message */
18474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18475     {
18476       if (unformat (input, "local"))
18477         {
18478           filter = 1;
18479         }
18480       else if (unformat (input, "remote"))
18481         {
18482           filter = 2;
18483         }
18484       else
18485         {
18486           errmsg ("parse error '%U'", format_unformat_error, input);
18487           return -99;
18488         }
18489     }
18490
18491   if (!vam->json_output)
18492     {
18493       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18494     }
18495
18496   M (ONE_LOCATOR_SET_DUMP, mp);
18497
18498   mp->filter = filter;
18499
18500   /* send it... */
18501   S (mp);
18502
18503   /* Use a control ping for synchronization */
18504   MPING (CONTROL_PING, mp_ping);
18505   S (mp_ping);
18506
18507   /* Wait for a reply... */
18508   W (ret);
18509   return ret;
18510 }
18511
18512 #define api_lisp_locator_set_dump api_one_locator_set_dump
18513
18514 static int
18515 api_one_eid_table_map_dump (vat_main_t * vam)
18516 {
18517   u8 is_l2 = 0;
18518   u8 mode_set = 0;
18519   unformat_input_t *input = vam->input;
18520   vl_api_one_eid_table_map_dump_t *mp;
18521   vl_api_control_ping_t *mp_ping;
18522   int ret;
18523
18524   /* Parse args required to build the message */
18525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18526     {
18527       if (unformat (input, "l2"))
18528         {
18529           is_l2 = 1;
18530           mode_set = 1;
18531         }
18532       else if (unformat (input, "l3"))
18533         {
18534           is_l2 = 0;
18535           mode_set = 1;
18536         }
18537       else
18538         {
18539           errmsg ("parse error '%U'", format_unformat_error, input);
18540           return -99;
18541         }
18542     }
18543
18544   if (!mode_set)
18545     {
18546       errmsg ("expected one of 'l2' or 'l3' parameter!");
18547       return -99;
18548     }
18549
18550   if (!vam->json_output)
18551     {
18552       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18553     }
18554
18555   M (ONE_EID_TABLE_MAP_DUMP, mp);
18556   mp->is_l2 = is_l2;
18557
18558   /* send it... */
18559   S (mp);
18560
18561   /* Use a control ping for synchronization */
18562   MPING (CONTROL_PING, mp_ping);
18563   S (mp_ping);
18564
18565   /* Wait for a reply... */
18566   W (ret);
18567   return ret;
18568 }
18569
18570 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18571
18572 static int
18573 api_one_eid_table_vni_dump (vat_main_t * vam)
18574 {
18575   vl_api_one_eid_table_vni_dump_t *mp;
18576   vl_api_control_ping_t *mp_ping;
18577   int ret;
18578
18579   if (!vam->json_output)
18580     {
18581       print (vam->ofp, "VNI");
18582     }
18583
18584   M (ONE_EID_TABLE_VNI_DUMP, mp);
18585
18586   /* send it... */
18587   S (mp);
18588
18589   /* Use a control ping for synchronization */
18590   MPING (CONTROL_PING, mp_ping);
18591   S (mp_ping);
18592
18593   /* Wait for a reply... */
18594   W (ret);
18595   return ret;
18596 }
18597
18598 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18599
18600 static int
18601 api_one_eid_table_dump (vat_main_t * vam)
18602 {
18603   unformat_input_t *i = vam->input;
18604   vl_api_one_eid_table_dump_t *mp;
18605   vl_api_control_ping_t *mp_ping;
18606   struct in_addr ip4;
18607   struct in6_addr ip6;
18608   u8 mac[6];
18609   u8 eid_type = ~0, eid_set = 0;
18610   u32 prefix_length = ~0, t, vni = 0;
18611   u8 filter = 0;
18612   int ret;
18613   lisp_nsh_api_t nsh;
18614
18615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18616     {
18617       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18618         {
18619           eid_set = 1;
18620           eid_type = 0;
18621           prefix_length = t;
18622         }
18623       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18624         {
18625           eid_set = 1;
18626           eid_type = 1;
18627           prefix_length = t;
18628         }
18629       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18630         {
18631           eid_set = 1;
18632           eid_type = 2;
18633         }
18634       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18635         {
18636           eid_set = 1;
18637           eid_type = 3;
18638         }
18639       else if (unformat (i, "vni %d", &t))
18640         {
18641           vni = t;
18642         }
18643       else if (unformat (i, "local"))
18644         {
18645           filter = 1;
18646         }
18647       else if (unformat (i, "remote"))
18648         {
18649           filter = 2;
18650         }
18651       else
18652         {
18653           errmsg ("parse error '%U'", format_unformat_error, i);
18654           return -99;
18655         }
18656     }
18657
18658   if (!vam->json_output)
18659     {
18660       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18661              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18662     }
18663
18664   M (ONE_EID_TABLE_DUMP, mp);
18665
18666   mp->filter = filter;
18667   if (eid_set)
18668     {
18669       mp->eid_set = 1;
18670       mp->vni = htonl (vni);
18671       mp->eid_type = eid_type;
18672       switch (eid_type)
18673         {
18674         case 0:
18675           mp->prefix_length = prefix_length;
18676           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18677           break;
18678         case 1:
18679           mp->prefix_length = prefix_length;
18680           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18681           break;
18682         case 2:
18683           clib_memcpy (mp->eid, mac, sizeof (mac));
18684           break;
18685         case 3:
18686           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18687           break;
18688         default:
18689           errmsg ("unknown EID type %d!", eid_type);
18690           return -99;
18691         }
18692     }
18693
18694   /* send it... */
18695   S (mp);
18696
18697   /* Use a control ping for synchronization */
18698   MPING (CONTROL_PING, mp_ping);
18699   S (mp_ping);
18700
18701   /* Wait for a reply... */
18702   W (ret);
18703   return ret;
18704 }
18705
18706 #define api_lisp_eid_table_dump api_one_eid_table_dump
18707
18708 static int
18709 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18710 {
18711   unformat_input_t *i = vam->input;
18712   vl_api_gpe_fwd_entries_get_t *mp;
18713   u8 vni_set = 0;
18714   u32 vni = ~0;
18715   int ret;
18716
18717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18718     {
18719       if (unformat (i, "vni %d", &vni))
18720         {
18721           vni_set = 1;
18722         }
18723       else
18724         {
18725           errmsg ("parse error '%U'", format_unformat_error, i);
18726           return -99;
18727         }
18728     }
18729
18730   if (!vni_set)
18731     {
18732       errmsg ("vni not set!");
18733       return -99;
18734     }
18735
18736   if (!vam->json_output)
18737     {
18738       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18739              "leid", "reid");
18740     }
18741
18742   M (GPE_FWD_ENTRIES_GET, mp);
18743   mp->vni = clib_host_to_net_u32 (vni);
18744
18745   /* send it... */
18746   S (mp);
18747
18748   /* Wait for a reply... */
18749   W (ret);
18750   return ret;
18751 }
18752
18753 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18754 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18755 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18756 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18757 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18758 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18759 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18760 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18761
18762 static int
18763 api_one_adjacencies_get (vat_main_t * vam)
18764 {
18765   unformat_input_t *i = vam->input;
18766   vl_api_one_adjacencies_get_t *mp;
18767   u8 vni_set = 0;
18768   u32 vni = ~0;
18769   int ret;
18770
18771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18772     {
18773       if (unformat (i, "vni %d", &vni))
18774         {
18775           vni_set = 1;
18776         }
18777       else
18778         {
18779           errmsg ("parse error '%U'", format_unformat_error, i);
18780           return -99;
18781         }
18782     }
18783
18784   if (!vni_set)
18785     {
18786       errmsg ("vni not set!");
18787       return -99;
18788     }
18789
18790   if (!vam->json_output)
18791     {
18792       print (vam->ofp, "%s %40s", "leid", "reid");
18793     }
18794
18795   M (ONE_ADJACENCIES_GET, mp);
18796   mp->vni = clib_host_to_net_u32 (vni);
18797
18798   /* send it... */
18799   S (mp);
18800
18801   /* Wait for a reply... */
18802   W (ret);
18803   return ret;
18804 }
18805
18806 #define api_lisp_adjacencies_get api_one_adjacencies_get
18807
18808 static int
18809 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18810 {
18811   unformat_input_t *i = vam->input;
18812   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18813   int ret;
18814   u8 ip_family_set = 0, is_ip4 = 1;
18815
18816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18817     {
18818       if (unformat (i, "ip4"))
18819         {
18820           ip_family_set = 1;
18821           is_ip4 = 1;
18822         }
18823       else if (unformat (i, "ip6"))
18824         {
18825           ip_family_set = 1;
18826           is_ip4 = 0;
18827         }
18828       else
18829         {
18830           errmsg ("parse error '%U'", format_unformat_error, i);
18831           return -99;
18832         }
18833     }
18834
18835   if (!ip_family_set)
18836     {
18837       errmsg ("ip family not set!");
18838       return -99;
18839     }
18840
18841   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18842   mp->is_ip4 = is_ip4;
18843
18844   /* send it... */
18845   S (mp);
18846
18847   /* Wait for a reply... */
18848   W (ret);
18849   return ret;
18850 }
18851
18852 static int
18853 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18854 {
18855   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18856   int ret;
18857
18858   if (!vam->json_output)
18859     {
18860       print (vam->ofp, "VNIs");
18861     }
18862
18863   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18864
18865   /* send it... */
18866   S (mp);
18867
18868   /* Wait for a reply... */
18869   W (ret);
18870   return ret;
18871 }
18872
18873 static int
18874 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18875 {
18876   unformat_input_t *i = vam->input;
18877   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18878   int ret = 0;
18879   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18880   struct in_addr ip4;
18881   struct in6_addr ip6;
18882   u32 table_id = 0, nh_sw_if_index = ~0;
18883
18884   memset (&ip4, 0, sizeof (ip4));
18885   memset (&ip6, 0, sizeof (ip6));
18886
18887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18888     {
18889       if (unformat (i, "del"))
18890         is_add = 0;
18891       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18892                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18893         {
18894           ip_set = 1;
18895           is_ip4 = 1;
18896         }
18897       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18898                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18899         {
18900           ip_set = 1;
18901           is_ip4 = 0;
18902         }
18903       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18904         {
18905           ip_set = 1;
18906           is_ip4 = 1;
18907           nh_sw_if_index = ~0;
18908         }
18909       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18910         {
18911           ip_set = 1;
18912           is_ip4 = 0;
18913           nh_sw_if_index = ~0;
18914         }
18915       else if (unformat (i, "table %d", &table_id))
18916         ;
18917       else
18918         {
18919           errmsg ("parse error '%U'", format_unformat_error, i);
18920           return -99;
18921         }
18922     }
18923
18924   if (!ip_set)
18925     {
18926       errmsg ("nh addr not set!");
18927       return -99;
18928     }
18929
18930   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18931   mp->is_add = is_add;
18932   mp->table_id = clib_host_to_net_u32 (table_id);
18933   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18934   mp->is_ip4 = is_ip4;
18935   if (is_ip4)
18936     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18937   else
18938     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18939
18940   /* send it... */
18941   S (mp);
18942
18943   /* Wait for a reply... */
18944   W (ret);
18945   return ret;
18946 }
18947
18948 static int
18949 api_one_map_server_dump (vat_main_t * vam)
18950 {
18951   vl_api_one_map_server_dump_t *mp;
18952   vl_api_control_ping_t *mp_ping;
18953   int ret;
18954
18955   if (!vam->json_output)
18956     {
18957       print (vam->ofp, "%=20s", "Map server");
18958     }
18959
18960   M (ONE_MAP_SERVER_DUMP, mp);
18961   /* send it... */
18962   S (mp);
18963
18964   /* Use a control ping for synchronization */
18965   MPING (CONTROL_PING, mp_ping);
18966   S (mp_ping);
18967
18968   /* Wait for a reply... */
18969   W (ret);
18970   return ret;
18971 }
18972
18973 #define api_lisp_map_server_dump api_one_map_server_dump
18974
18975 static int
18976 api_one_map_resolver_dump (vat_main_t * vam)
18977 {
18978   vl_api_one_map_resolver_dump_t *mp;
18979   vl_api_control_ping_t *mp_ping;
18980   int ret;
18981
18982   if (!vam->json_output)
18983     {
18984       print (vam->ofp, "%=20s", "Map resolver");
18985     }
18986
18987   M (ONE_MAP_RESOLVER_DUMP, mp);
18988   /* send it... */
18989   S (mp);
18990
18991   /* Use a control ping for synchronization */
18992   MPING (CONTROL_PING, mp_ping);
18993   S (mp_ping);
18994
18995   /* Wait for a reply... */
18996   W (ret);
18997   return ret;
18998 }
18999
19000 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19001
19002 static int
19003 api_one_stats_flush (vat_main_t * vam)
19004 {
19005   vl_api_one_stats_flush_t *mp;
19006   int ret = 0;
19007
19008   M (ONE_STATS_FLUSH, mp);
19009   S (mp);
19010   W (ret);
19011   return ret;
19012 }
19013
19014 static int
19015 api_one_stats_dump (vat_main_t * vam)
19016 {
19017   vl_api_one_stats_dump_t *mp;
19018   vl_api_control_ping_t *mp_ping;
19019   int ret;
19020
19021   M (ONE_STATS_DUMP, mp);
19022   /* send it... */
19023   S (mp);
19024
19025   /* Use a control ping for synchronization */
19026   MPING (CONTROL_PING, mp_ping);
19027   S (mp_ping);
19028
19029   /* Wait for a reply... */
19030   W (ret);
19031   return ret;
19032 }
19033
19034 static int
19035 api_show_one_status (vat_main_t * vam)
19036 {
19037   vl_api_show_one_status_t *mp;
19038   int ret;
19039
19040   if (!vam->json_output)
19041     {
19042       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19043     }
19044
19045   M (SHOW_ONE_STATUS, mp);
19046   /* send it... */
19047   S (mp);
19048   /* Wait for a reply... */
19049   W (ret);
19050   return ret;
19051 }
19052
19053 #define api_show_lisp_status api_show_one_status
19054
19055 static int
19056 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19057 {
19058   vl_api_gpe_fwd_entry_path_dump_t *mp;
19059   vl_api_control_ping_t *mp_ping;
19060   unformat_input_t *i = vam->input;
19061   u32 fwd_entry_index = ~0;
19062   int ret;
19063
19064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19065     {
19066       if (unformat (i, "index %d", &fwd_entry_index))
19067         ;
19068       else
19069         break;
19070     }
19071
19072   if (~0 == fwd_entry_index)
19073     {
19074       errmsg ("no index specified!");
19075       return -99;
19076     }
19077
19078   if (!vam->json_output)
19079     {
19080       print (vam->ofp, "first line");
19081     }
19082
19083   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19084
19085   /* send it... */
19086   S (mp);
19087   /* Use a control ping for synchronization */
19088   MPING (CONTROL_PING, mp_ping);
19089   S (mp_ping);
19090
19091   /* Wait for a reply... */
19092   W (ret);
19093   return ret;
19094 }
19095
19096 static int
19097 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19098 {
19099   vl_api_one_get_map_request_itr_rlocs_t *mp;
19100   int ret;
19101
19102   if (!vam->json_output)
19103     {
19104       print (vam->ofp, "%=20s", "itr-rlocs:");
19105     }
19106
19107   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19108   /* send it... */
19109   S (mp);
19110   /* Wait for a reply... */
19111   W (ret);
19112   return ret;
19113 }
19114
19115 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19116
19117 static int
19118 api_af_packet_create (vat_main_t * vam)
19119 {
19120   unformat_input_t *i = vam->input;
19121   vl_api_af_packet_create_t *mp;
19122   u8 *host_if_name = 0;
19123   u8 hw_addr[6];
19124   u8 random_hw_addr = 1;
19125   int ret;
19126
19127   memset (hw_addr, 0, sizeof (hw_addr));
19128
19129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19130     {
19131       if (unformat (i, "name %s", &host_if_name))
19132         vec_add1 (host_if_name, 0);
19133       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19134         random_hw_addr = 0;
19135       else
19136         break;
19137     }
19138
19139   if (!vec_len (host_if_name))
19140     {
19141       errmsg ("host-interface name must be specified");
19142       return -99;
19143     }
19144
19145   if (vec_len (host_if_name) > 64)
19146     {
19147       errmsg ("host-interface name too long");
19148       return -99;
19149     }
19150
19151   M (AF_PACKET_CREATE, mp);
19152
19153   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19154   clib_memcpy (mp->hw_addr, hw_addr, 6);
19155   mp->use_random_hw_addr = random_hw_addr;
19156   vec_free (host_if_name);
19157
19158   S (mp);
19159
19160   /* *INDENT-OFF* */
19161   W2 (ret,
19162       ({
19163         if (ret == 0)
19164           fprintf (vam->ofp ? vam->ofp : stderr,
19165                    " new sw_if_index = %d\n", vam->sw_if_index);
19166       }));
19167   /* *INDENT-ON* */
19168   return ret;
19169 }
19170
19171 static int
19172 api_af_packet_delete (vat_main_t * vam)
19173 {
19174   unformat_input_t *i = vam->input;
19175   vl_api_af_packet_delete_t *mp;
19176   u8 *host_if_name = 0;
19177   int ret;
19178
19179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19180     {
19181       if (unformat (i, "name %s", &host_if_name))
19182         vec_add1 (host_if_name, 0);
19183       else
19184         break;
19185     }
19186
19187   if (!vec_len (host_if_name))
19188     {
19189       errmsg ("host-interface name must be specified");
19190       return -99;
19191     }
19192
19193   if (vec_len (host_if_name) > 64)
19194     {
19195       errmsg ("host-interface name too long");
19196       return -99;
19197     }
19198
19199   M (AF_PACKET_DELETE, mp);
19200
19201   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19202   vec_free (host_if_name);
19203
19204   S (mp);
19205   W (ret);
19206   return ret;
19207 }
19208
19209 static int
19210 api_policer_add_del (vat_main_t * vam)
19211 {
19212   unformat_input_t *i = vam->input;
19213   vl_api_policer_add_del_t *mp;
19214   u8 is_add = 1;
19215   u8 *name = 0;
19216   u32 cir = 0;
19217   u32 eir = 0;
19218   u64 cb = 0;
19219   u64 eb = 0;
19220   u8 rate_type = 0;
19221   u8 round_type = 0;
19222   u8 type = 0;
19223   u8 color_aware = 0;
19224   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19225   int ret;
19226
19227   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19228   conform_action.dscp = 0;
19229   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19230   exceed_action.dscp = 0;
19231   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19232   violate_action.dscp = 0;
19233
19234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19235     {
19236       if (unformat (i, "del"))
19237         is_add = 0;
19238       else if (unformat (i, "name %s", &name))
19239         vec_add1 (name, 0);
19240       else if (unformat (i, "cir %u", &cir))
19241         ;
19242       else if (unformat (i, "eir %u", &eir))
19243         ;
19244       else if (unformat (i, "cb %u", &cb))
19245         ;
19246       else if (unformat (i, "eb %u", &eb))
19247         ;
19248       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19249                          &rate_type))
19250         ;
19251       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19252                          &round_type))
19253         ;
19254       else if (unformat (i, "type %U", unformat_policer_type, &type))
19255         ;
19256       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19257                          &conform_action))
19258         ;
19259       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19260                          &exceed_action))
19261         ;
19262       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19263                          &violate_action))
19264         ;
19265       else if (unformat (i, "color-aware"))
19266         color_aware = 1;
19267       else
19268         break;
19269     }
19270
19271   if (!vec_len (name))
19272     {
19273       errmsg ("policer name must be specified");
19274       return -99;
19275     }
19276
19277   if (vec_len (name) > 64)
19278     {
19279       errmsg ("policer name too long");
19280       return -99;
19281     }
19282
19283   M (POLICER_ADD_DEL, mp);
19284
19285   clib_memcpy (mp->name, name, vec_len (name));
19286   vec_free (name);
19287   mp->is_add = is_add;
19288   mp->cir = ntohl (cir);
19289   mp->eir = ntohl (eir);
19290   mp->cb = clib_net_to_host_u64 (cb);
19291   mp->eb = clib_net_to_host_u64 (eb);
19292   mp->rate_type = rate_type;
19293   mp->round_type = round_type;
19294   mp->type = type;
19295   mp->conform_action_type = conform_action.action_type;
19296   mp->conform_dscp = conform_action.dscp;
19297   mp->exceed_action_type = exceed_action.action_type;
19298   mp->exceed_dscp = exceed_action.dscp;
19299   mp->violate_action_type = violate_action.action_type;
19300   mp->violate_dscp = violate_action.dscp;
19301   mp->color_aware = color_aware;
19302
19303   S (mp);
19304   W (ret);
19305   return ret;
19306 }
19307
19308 static int
19309 api_policer_dump (vat_main_t * vam)
19310 {
19311   unformat_input_t *i = vam->input;
19312   vl_api_policer_dump_t *mp;
19313   vl_api_control_ping_t *mp_ping;
19314   u8 *match_name = 0;
19315   u8 match_name_valid = 0;
19316   int ret;
19317
19318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19319     {
19320       if (unformat (i, "name %s", &match_name))
19321         {
19322           vec_add1 (match_name, 0);
19323           match_name_valid = 1;
19324         }
19325       else
19326         break;
19327     }
19328
19329   M (POLICER_DUMP, mp);
19330   mp->match_name_valid = match_name_valid;
19331   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19332   vec_free (match_name);
19333   /* send it... */
19334   S (mp);
19335
19336   /* Use a control ping for synchronization */
19337   MPING (CONTROL_PING, mp_ping);
19338   S (mp_ping);
19339
19340   /* Wait for a reply... */
19341   W (ret);
19342   return ret;
19343 }
19344
19345 static int
19346 api_policer_classify_set_interface (vat_main_t * vam)
19347 {
19348   unformat_input_t *i = vam->input;
19349   vl_api_policer_classify_set_interface_t *mp;
19350   u32 sw_if_index;
19351   int sw_if_index_set;
19352   u32 ip4_table_index = ~0;
19353   u32 ip6_table_index = ~0;
19354   u32 l2_table_index = ~0;
19355   u8 is_add = 1;
19356   int ret;
19357
19358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19359     {
19360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19361         sw_if_index_set = 1;
19362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19363         sw_if_index_set = 1;
19364       else if (unformat (i, "del"))
19365         is_add = 0;
19366       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19367         ;
19368       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19369         ;
19370       else if (unformat (i, "l2-table %d", &l2_table_index))
19371         ;
19372       else
19373         {
19374           clib_warning ("parse error '%U'", format_unformat_error, i);
19375           return -99;
19376         }
19377     }
19378
19379   if (sw_if_index_set == 0)
19380     {
19381       errmsg ("missing interface name or sw_if_index");
19382       return -99;
19383     }
19384
19385   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19386
19387   mp->sw_if_index = ntohl (sw_if_index);
19388   mp->ip4_table_index = ntohl (ip4_table_index);
19389   mp->ip6_table_index = ntohl (ip6_table_index);
19390   mp->l2_table_index = ntohl (l2_table_index);
19391   mp->is_add = is_add;
19392
19393   S (mp);
19394   W (ret);
19395   return ret;
19396 }
19397
19398 static int
19399 api_policer_classify_dump (vat_main_t * vam)
19400 {
19401   unformat_input_t *i = vam->input;
19402   vl_api_policer_classify_dump_t *mp;
19403   vl_api_control_ping_t *mp_ping;
19404   u8 type = POLICER_CLASSIFY_N_TABLES;
19405   int ret;
19406
19407   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19408     ;
19409   else
19410     {
19411       errmsg ("classify table type must be specified");
19412       return -99;
19413     }
19414
19415   if (!vam->json_output)
19416     {
19417       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19418     }
19419
19420   M (POLICER_CLASSIFY_DUMP, mp);
19421   mp->type = type;
19422   /* send it... */
19423   S (mp);
19424
19425   /* Use a control ping for synchronization */
19426   MPING (CONTROL_PING, mp_ping);
19427   S (mp_ping);
19428
19429   /* Wait for a reply... */
19430   W (ret);
19431   return ret;
19432 }
19433
19434 static int
19435 api_netmap_create (vat_main_t * vam)
19436 {
19437   unformat_input_t *i = vam->input;
19438   vl_api_netmap_create_t *mp;
19439   u8 *if_name = 0;
19440   u8 hw_addr[6];
19441   u8 random_hw_addr = 1;
19442   u8 is_pipe = 0;
19443   u8 is_master = 0;
19444   int ret;
19445
19446   memset (hw_addr, 0, sizeof (hw_addr));
19447
19448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19449     {
19450       if (unformat (i, "name %s", &if_name))
19451         vec_add1 (if_name, 0);
19452       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19453         random_hw_addr = 0;
19454       else if (unformat (i, "pipe"))
19455         is_pipe = 1;
19456       else if (unformat (i, "master"))
19457         is_master = 1;
19458       else if (unformat (i, "slave"))
19459         is_master = 0;
19460       else
19461         break;
19462     }
19463
19464   if (!vec_len (if_name))
19465     {
19466       errmsg ("interface name must be specified");
19467       return -99;
19468     }
19469
19470   if (vec_len (if_name) > 64)
19471     {
19472       errmsg ("interface name too long");
19473       return -99;
19474     }
19475
19476   M (NETMAP_CREATE, mp);
19477
19478   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19479   clib_memcpy (mp->hw_addr, hw_addr, 6);
19480   mp->use_random_hw_addr = random_hw_addr;
19481   mp->is_pipe = is_pipe;
19482   mp->is_master = is_master;
19483   vec_free (if_name);
19484
19485   S (mp);
19486   W (ret);
19487   return ret;
19488 }
19489
19490 static int
19491 api_netmap_delete (vat_main_t * vam)
19492 {
19493   unformat_input_t *i = vam->input;
19494   vl_api_netmap_delete_t *mp;
19495   u8 *if_name = 0;
19496   int ret;
19497
19498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19499     {
19500       if (unformat (i, "name %s", &if_name))
19501         vec_add1 (if_name, 0);
19502       else
19503         break;
19504     }
19505
19506   if (!vec_len (if_name))
19507     {
19508       errmsg ("interface name must be specified");
19509       return -99;
19510     }
19511
19512   if (vec_len (if_name) > 64)
19513     {
19514       errmsg ("interface name too long");
19515       return -99;
19516     }
19517
19518   M (NETMAP_DELETE, mp);
19519
19520   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19521   vec_free (if_name);
19522
19523   S (mp);
19524   W (ret);
19525   return ret;
19526 }
19527
19528 static void
19529 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19530 {
19531   if (fp->afi == IP46_TYPE_IP6)
19532     print (vam->ofp,
19533            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19534            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19535            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19536            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19537            format_ip6_address, fp->next_hop);
19538   else if (fp->afi == IP46_TYPE_IP4)
19539     print (vam->ofp,
19540            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19541            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19542            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19543            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19544            format_ip4_address, fp->next_hop);
19545 }
19546
19547 static void
19548 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19549                                  vl_api_fib_path2_t * fp)
19550 {
19551   struct in_addr ip4;
19552   struct in6_addr ip6;
19553
19554   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19555   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19556   vat_json_object_add_uint (node, "is_local", fp->is_local);
19557   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19558   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19559   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19560   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19561   if (fp->afi == IP46_TYPE_IP4)
19562     {
19563       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19564       vat_json_object_add_ip4 (node, "next_hop", ip4);
19565     }
19566   else if (fp->afi == IP46_TYPE_IP6)
19567     {
19568       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19569       vat_json_object_add_ip6 (node, "next_hop", ip6);
19570     }
19571 }
19572
19573 static void
19574 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19575 {
19576   vat_main_t *vam = &vat_main;
19577   int count = ntohl (mp->mt_count);
19578   vl_api_fib_path2_t *fp;
19579   i32 i;
19580
19581   print (vam->ofp, "[%d]: sw_if_index %d via:",
19582          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19583   fp = mp->mt_paths;
19584   for (i = 0; i < count; i++)
19585     {
19586       vl_api_mpls_fib_path_print (vam, fp);
19587       fp++;
19588     }
19589
19590   print (vam->ofp, "");
19591 }
19592
19593 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19594 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19595
19596 static void
19597 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19598 {
19599   vat_main_t *vam = &vat_main;
19600   vat_json_node_t *node = NULL;
19601   int count = ntohl (mp->mt_count);
19602   vl_api_fib_path2_t *fp;
19603   i32 i;
19604
19605   if (VAT_JSON_ARRAY != vam->json_tree.type)
19606     {
19607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19608       vat_json_init_array (&vam->json_tree);
19609     }
19610   node = vat_json_array_add (&vam->json_tree);
19611
19612   vat_json_init_object (node);
19613   vat_json_object_add_uint (node, "tunnel_index",
19614                             ntohl (mp->mt_tunnel_index));
19615   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19616
19617   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19618
19619   fp = mp->mt_paths;
19620   for (i = 0; i < count; i++)
19621     {
19622       vl_api_mpls_fib_path_json_print (node, fp);
19623       fp++;
19624     }
19625 }
19626
19627 static int
19628 api_mpls_tunnel_dump (vat_main_t * vam)
19629 {
19630   vl_api_mpls_tunnel_dump_t *mp;
19631   vl_api_control_ping_t *mp_ping;
19632   i32 index = -1;
19633   int ret;
19634
19635   /* Parse args required to build the message */
19636   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19637     {
19638       if (!unformat (vam->input, "tunnel_index %d", &index))
19639         {
19640           index = -1;
19641           break;
19642         }
19643     }
19644
19645   print (vam->ofp, "  tunnel_index %d", index);
19646
19647   M (MPLS_TUNNEL_DUMP, mp);
19648   mp->tunnel_index = htonl (index);
19649   S (mp);
19650
19651   /* Use a control ping for synchronization */
19652   MPING (CONTROL_PING, mp_ping);
19653   S (mp_ping);
19654
19655   W (ret);
19656   return ret;
19657 }
19658
19659 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19660 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19661
19662
19663 static void
19664 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19665 {
19666   vat_main_t *vam = &vat_main;
19667   int count = ntohl (mp->count);
19668   vl_api_fib_path2_t *fp;
19669   int i;
19670
19671   print (vam->ofp,
19672          "table-id %d, label %u, ess_bit %u",
19673          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19674   fp = mp->path;
19675   for (i = 0; i < count; i++)
19676     {
19677       vl_api_mpls_fib_path_print (vam, fp);
19678       fp++;
19679     }
19680 }
19681
19682 static void vl_api_mpls_fib_details_t_handler_json
19683   (vl_api_mpls_fib_details_t * mp)
19684 {
19685   vat_main_t *vam = &vat_main;
19686   int count = ntohl (mp->count);
19687   vat_json_node_t *node = NULL;
19688   vl_api_fib_path2_t *fp;
19689   int i;
19690
19691   if (VAT_JSON_ARRAY != vam->json_tree.type)
19692     {
19693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19694       vat_json_init_array (&vam->json_tree);
19695     }
19696   node = vat_json_array_add (&vam->json_tree);
19697
19698   vat_json_init_object (node);
19699   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19700   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19701   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19702   vat_json_object_add_uint (node, "path_count", count);
19703   fp = mp->path;
19704   for (i = 0; i < count; i++)
19705     {
19706       vl_api_mpls_fib_path_json_print (node, fp);
19707       fp++;
19708     }
19709 }
19710
19711 static int
19712 api_mpls_fib_dump (vat_main_t * vam)
19713 {
19714   vl_api_mpls_fib_dump_t *mp;
19715   vl_api_control_ping_t *mp_ping;
19716   int ret;
19717
19718   M (MPLS_FIB_DUMP, mp);
19719   S (mp);
19720
19721   /* Use a control ping for synchronization */
19722   MPING (CONTROL_PING, mp_ping);
19723   S (mp_ping);
19724
19725   W (ret);
19726   return ret;
19727 }
19728
19729 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19730 #define vl_api_ip_fib_details_t_print vl_noop_handler
19731
19732 static void
19733 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19734 {
19735   vat_main_t *vam = &vat_main;
19736   int count = ntohl (mp->count);
19737   vl_api_fib_path_t *fp;
19738   int i;
19739
19740   print (vam->ofp,
19741          "table-id %d, prefix %U/%d",
19742          ntohl (mp->table_id), format_ip4_address, mp->address,
19743          mp->address_length);
19744   fp = mp->path;
19745   for (i = 0; i < count; i++)
19746     {
19747       if (fp->afi == IP46_TYPE_IP6)
19748         print (vam->ofp,
19749                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19750                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19751                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19752                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19753                format_ip6_address, fp->next_hop);
19754       else if (fp->afi == IP46_TYPE_IP4)
19755         print (vam->ofp,
19756                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19757                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19758                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19759                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19760                format_ip4_address, fp->next_hop);
19761       fp++;
19762     }
19763 }
19764
19765 static void vl_api_ip_fib_details_t_handler_json
19766   (vl_api_ip_fib_details_t * mp)
19767 {
19768   vat_main_t *vam = &vat_main;
19769   int count = ntohl (mp->count);
19770   vat_json_node_t *node = NULL;
19771   struct in_addr ip4;
19772   struct in6_addr ip6;
19773   vl_api_fib_path_t *fp;
19774   int i;
19775
19776   if (VAT_JSON_ARRAY != vam->json_tree.type)
19777     {
19778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19779       vat_json_init_array (&vam->json_tree);
19780     }
19781   node = vat_json_array_add (&vam->json_tree);
19782
19783   vat_json_init_object (node);
19784   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19785   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19786   vat_json_object_add_ip4 (node, "prefix", ip4);
19787   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19788   vat_json_object_add_uint (node, "path_count", count);
19789   fp = mp->path;
19790   for (i = 0; i < count; i++)
19791     {
19792       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19793       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19794       vat_json_object_add_uint (node, "is_local", fp->is_local);
19795       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19796       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19797       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19798       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19799       if (fp->afi == IP46_TYPE_IP4)
19800         {
19801           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19802           vat_json_object_add_ip4 (node, "next_hop", ip4);
19803         }
19804       else if (fp->afi == IP46_TYPE_IP6)
19805         {
19806           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19807           vat_json_object_add_ip6 (node, "next_hop", ip6);
19808         }
19809     }
19810 }
19811
19812 static int
19813 api_ip_fib_dump (vat_main_t * vam)
19814 {
19815   vl_api_ip_fib_dump_t *mp;
19816   vl_api_control_ping_t *mp_ping;
19817   int ret;
19818
19819   M (IP_FIB_DUMP, mp);
19820   S (mp);
19821
19822   /* Use a control ping for synchronization */
19823   MPING (CONTROL_PING, mp_ping);
19824   S (mp_ping);
19825
19826   W (ret);
19827   return ret;
19828 }
19829
19830 static int
19831 api_ip_mfib_dump (vat_main_t * vam)
19832 {
19833   vl_api_ip_mfib_dump_t *mp;
19834   vl_api_control_ping_t *mp_ping;
19835   int ret;
19836
19837   M (IP_MFIB_DUMP, mp);
19838   S (mp);
19839
19840   /* Use a control ping for synchronization */
19841   MPING (CONTROL_PING, mp_ping);
19842   S (mp_ping);
19843
19844   W (ret);
19845   return ret;
19846 }
19847
19848 static void vl_api_ip_neighbor_details_t_handler
19849   (vl_api_ip_neighbor_details_t * mp)
19850 {
19851   vat_main_t *vam = &vat_main;
19852
19853   print (vam->ofp, "%c %U %U",
19854          (mp->is_static) ? 'S' : 'D',
19855          format_ethernet_address, &mp->mac_address,
19856          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19857          &mp->ip_address);
19858 }
19859
19860 static void vl_api_ip_neighbor_details_t_handler_json
19861   (vl_api_ip_neighbor_details_t * mp)
19862 {
19863
19864   vat_main_t *vam = &vat_main;
19865   vat_json_node_t *node;
19866   struct in_addr ip4;
19867   struct in6_addr ip6;
19868
19869   if (VAT_JSON_ARRAY != vam->json_tree.type)
19870     {
19871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19872       vat_json_init_array (&vam->json_tree);
19873     }
19874   node = vat_json_array_add (&vam->json_tree);
19875
19876   vat_json_init_object (node);
19877   vat_json_object_add_string_copy (node, "flag",
19878                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19879                                    "dynamic");
19880
19881   vat_json_object_add_string_copy (node, "link_layer",
19882                                    format (0, "%U", format_ethernet_address,
19883                                            &mp->mac_address));
19884
19885   if (mp->is_ipv6)
19886     {
19887       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19888       vat_json_object_add_ip6 (node, "ip_address", ip6);
19889     }
19890   else
19891     {
19892       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19893       vat_json_object_add_ip4 (node, "ip_address", ip4);
19894     }
19895 }
19896
19897 static int
19898 api_ip_neighbor_dump (vat_main_t * vam)
19899 {
19900   unformat_input_t *i = vam->input;
19901   vl_api_ip_neighbor_dump_t *mp;
19902   vl_api_control_ping_t *mp_ping;
19903   u8 is_ipv6 = 0;
19904   u32 sw_if_index = ~0;
19905   int ret;
19906
19907   /* Parse args required to build the message */
19908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19909     {
19910       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19911         ;
19912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19913         ;
19914       else if (unformat (i, "ip6"))
19915         is_ipv6 = 1;
19916       else
19917         break;
19918     }
19919
19920   if (sw_if_index == ~0)
19921     {
19922       errmsg ("missing interface name or sw_if_index");
19923       return -99;
19924     }
19925
19926   M (IP_NEIGHBOR_DUMP, mp);
19927   mp->is_ipv6 = (u8) is_ipv6;
19928   mp->sw_if_index = ntohl (sw_if_index);
19929   S (mp);
19930
19931   /* Use a control ping for synchronization */
19932   MPING (CONTROL_PING, mp_ping);
19933   S (mp_ping);
19934
19935   W (ret);
19936   return ret;
19937 }
19938
19939 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19940 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19941
19942 static void
19943 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19944 {
19945   vat_main_t *vam = &vat_main;
19946   int count = ntohl (mp->count);
19947   vl_api_fib_path_t *fp;
19948   int i;
19949
19950   print (vam->ofp,
19951          "table-id %d, prefix %U/%d",
19952          ntohl (mp->table_id), format_ip6_address, mp->address,
19953          mp->address_length);
19954   fp = mp->path;
19955   for (i = 0; i < count; i++)
19956     {
19957       if (fp->afi == IP46_TYPE_IP6)
19958         print (vam->ofp,
19959                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19960                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19961                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19962                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19963                format_ip6_address, fp->next_hop);
19964       else if (fp->afi == IP46_TYPE_IP4)
19965         print (vam->ofp,
19966                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19967                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19968                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19969                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19970                format_ip4_address, fp->next_hop);
19971       fp++;
19972     }
19973 }
19974
19975 static void vl_api_ip6_fib_details_t_handler_json
19976   (vl_api_ip6_fib_details_t * mp)
19977 {
19978   vat_main_t *vam = &vat_main;
19979   int count = ntohl (mp->count);
19980   vat_json_node_t *node = NULL;
19981   struct in_addr ip4;
19982   struct in6_addr ip6;
19983   vl_api_fib_path_t *fp;
19984   int i;
19985
19986   if (VAT_JSON_ARRAY != vam->json_tree.type)
19987     {
19988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19989       vat_json_init_array (&vam->json_tree);
19990     }
19991   node = vat_json_array_add (&vam->json_tree);
19992
19993   vat_json_init_object (node);
19994   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19995   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19996   vat_json_object_add_ip6 (node, "prefix", ip6);
19997   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19998   vat_json_object_add_uint (node, "path_count", count);
19999   fp = mp->path;
20000   for (i = 0; i < count; i++)
20001     {
20002       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20003       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20004       vat_json_object_add_uint (node, "is_local", fp->is_local);
20005       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20006       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20007       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20008       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20009       if (fp->afi == IP46_TYPE_IP4)
20010         {
20011           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20012           vat_json_object_add_ip4 (node, "next_hop", ip4);
20013         }
20014       else if (fp->afi == IP46_TYPE_IP6)
20015         {
20016           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20017           vat_json_object_add_ip6 (node, "next_hop", ip6);
20018         }
20019     }
20020 }
20021
20022 static int
20023 api_ip6_fib_dump (vat_main_t * vam)
20024 {
20025   vl_api_ip6_fib_dump_t *mp;
20026   vl_api_control_ping_t *mp_ping;
20027   int ret;
20028
20029   M (IP6_FIB_DUMP, mp);
20030   S (mp);
20031
20032   /* Use a control ping for synchronization */
20033   MPING (CONTROL_PING, mp_ping);
20034   S (mp_ping);
20035
20036   W (ret);
20037   return ret;
20038 }
20039
20040 static int
20041 api_ip6_mfib_dump (vat_main_t * vam)
20042 {
20043   vl_api_ip6_mfib_dump_t *mp;
20044   vl_api_control_ping_t *mp_ping;
20045   int ret;
20046
20047   M (IP6_MFIB_DUMP, mp);
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   W (ret);
20055   return ret;
20056 }
20057
20058 int
20059 api_classify_table_ids (vat_main_t * vam)
20060 {
20061   vl_api_classify_table_ids_t *mp;
20062   int ret;
20063
20064   /* Construct the API message */
20065   M (CLASSIFY_TABLE_IDS, mp);
20066   mp->context = 0;
20067
20068   S (mp);
20069   W (ret);
20070   return ret;
20071 }
20072
20073 int
20074 api_classify_table_by_interface (vat_main_t * vam)
20075 {
20076   unformat_input_t *input = vam->input;
20077   vl_api_classify_table_by_interface_t *mp;
20078
20079   u32 sw_if_index = ~0;
20080   int ret;
20081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20082     {
20083       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20084         ;
20085       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20086         ;
20087       else
20088         break;
20089     }
20090   if (sw_if_index == ~0)
20091     {
20092       errmsg ("missing interface name or sw_if_index");
20093       return -99;
20094     }
20095
20096   /* Construct the API message */
20097   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20098   mp->context = 0;
20099   mp->sw_if_index = ntohl (sw_if_index);
20100
20101   S (mp);
20102   W (ret);
20103   return ret;
20104 }
20105
20106 int
20107 api_classify_table_info (vat_main_t * vam)
20108 {
20109   unformat_input_t *input = vam->input;
20110   vl_api_classify_table_info_t *mp;
20111
20112   u32 table_id = ~0;
20113   int ret;
20114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20115     {
20116       if (unformat (input, "table_id %d", &table_id))
20117         ;
20118       else
20119         break;
20120     }
20121   if (table_id == ~0)
20122     {
20123       errmsg ("missing table id");
20124       return -99;
20125     }
20126
20127   /* Construct the API message */
20128   M (CLASSIFY_TABLE_INFO, mp);
20129   mp->context = 0;
20130   mp->table_id = ntohl (table_id);
20131
20132   S (mp);
20133   W (ret);
20134   return ret;
20135 }
20136
20137 int
20138 api_classify_session_dump (vat_main_t * vam)
20139 {
20140   unformat_input_t *input = vam->input;
20141   vl_api_classify_session_dump_t *mp;
20142   vl_api_control_ping_t *mp_ping;
20143
20144   u32 table_id = ~0;
20145   int ret;
20146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20147     {
20148       if (unformat (input, "table_id %d", &table_id))
20149         ;
20150       else
20151         break;
20152     }
20153   if (table_id == ~0)
20154     {
20155       errmsg ("missing table id");
20156       return -99;
20157     }
20158
20159   /* Construct the API message */
20160   M (CLASSIFY_SESSION_DUMP, mp);
20161   mp->context = 0;
20162   mp->table_id = ntohl (table_id);
20163   S (mp);
20164
20165   /* Use a control ping for synchronization */
20166   MPING (CONTROL_PING, mp_ping);
20167   S (mp_ping);
20168
20169   W (ret);
20170   return ret;
20171 }
20172
20173 static void
20174 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20175 {
20176   vat_main_t *vam = &vat_main;
20177
20178   print (vam->ofp, "collector_address %U, collector_port %d, "
20179          "src_address %U, vrf_id %d, path_mtu %u, "
20180          "template_interval %u, udp_checksum %d",
20181          format_ip4_address, mp->collector_address,
20182          ntohs (mp->collector_port),
20183          format_ip4_address, mp->src_address,
20184          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20185          ntohl (mp->template_interval), mp->udp_checksum);
20186
20187   vam->retval = 0;
20188   vam->result_ready = 1;
20189 }
20190
20191 static void
20192   vl_api_ipfix_exporter_details_t_handler_json
20193   (vl_api_ipfix_exporter_details_t * mp)
20194 {
20195   vat_main_t *vam = &vat_main;
20196   vat_json_node_t node;
20197   struct in_addr collector_address;
20198   struct in_addr src_address;
20199
20200   vat_json_init_object (&node);
20201   clib_memcpy (&collector_address, &mp->collector_address,
20202                sizeof (collector_address));
20203   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20204   vat_json_object_add_uint (&node, "collector_port",
20205                             ntohs (mp->collector_port));
20206   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20207   vat_json_object_add_ip4 (&node, "src_address", src_address);
20208   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20209   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20210   vat_json_object_add_uint (&node, "template_interval",
20211                             ntohl (mp->template_interval));
20212   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20213
20214   vat_json_print (vam->ofp, &node);
20215   vat_json_free (&node);
20216   vam->retval = 0;
20217   vam->result_ready = 1;
20218 }
20219
20220 int
20221 api_ipfix_exporter_dump (vat_main_t * vam)
20222 {
20223   vl_api_ipfix_exporter_dump_t *mp;
20224   int ret;
20225
20226   /* Construct the API message */
20227   M (IPFIX_EXPORTER_DUMP, mp);
20228   mp->context = 0;
20229
20230   S (mp);
20231   W (ret);
20232   return ret;
20233 }
20234
20235 static int
20236 api_ipfix_classify_stream_dump (vat_main_t * vam)
20237 {
20238   vl_api_ipfix_classify_stream_dump_t *mp;
20239   int ret;
20240
20241   /* Construct the API message */
20242   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20243   mp->context = 0;
20244
20245   S (mp);
20246   W (ret);
20247   return ret;
20248   /* NOTREACHED */
20249   return 0;
20250 }
20251
20252 static void
20253   vl_api_ipfix_classify_stream_details_t_handler
20254   (vl_api_ipfix_classify_stream_details_t * mp)
20255 {
20256   vat_main_t *vam = &vat_main;
20257   print (vam->ofp, "domain_id %d, src_port %d",
20258          ntohl (mp->domain_id), ntohs (mp->src_port));
20259   vam->retval = 0;
20260   vam->result_ready = 1;
20261 }
20262
20263 static void
20264   vl_api_ipfix_classify_stream_details_t_handler_json
20265   (vl_api_ipfix_classify_stream_details_t * mp)
20266 {
20267   vat_main_t *vam = &vat_main;
20268   vat_json_node_t node;
20269
20270   vat_json_init_object (&node);
20271   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20272   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20273
20274   vat_json_print (vam->ofp, &node);
20275   vat_json_free (&node);
20276   vam->retval = 0;
20277   vam->result_ready = 1;
20278 }
20279
20280 static int
20281 api_ipfix_classify_table_dump (vat_main_t * vam)
20282 {
20283   vl_api_ipfix_classify_table_dump_t *mp;
20284   vl_api_control_ping_t *mp_ping;
20285   int ret;
20286
20287   if (!vam->json_output)
20288     {
20289       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20290              "transport_protocol");
20291     }
20292
20293   /* Construct the API message */
20294   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20295
20296   /* send it... */
20297   S (mp);
20298
20299   /* Use a control ping for synchronization */
20300   MPING (CONTROL_PING, mp_ping);
20301   S (mp_ping);
20302
20303   W (ret);
20304   return ret;
20305 }
20306
20307 static void
20308   vl_api_ipfix_classify_table_details_t_handler
20309   (vl_api_ipfix_classify_table_details_t * mp)
20310 {
20311   vat_main_t *vam = &vat_main;
20312   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20313          mp->transport_protocol);
20314 }
20315
20316 static void
20317   vl_api_ipfix_classify_table_details_t_handler_json
20318   (vl_api_ipfix_classify_table_details_t * mp)
20319 {
20320   vat_json_node_t *node = NULL;
20321   vat_main_t *vam = &vat_main;
20322
20323   if (VAT_JSON_ARRAY != vam->json_tree.type)
20324     {
20325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20326       vat_json_init_array (&vam->json_tree);
20327     }
20328
20329   node = vat_json_array_add (&vam->json_tree);
20330   vat_json_init_object (node);
20331
20332   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20333   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20334   vat_json_object_add_uint (node, "transport_protocol",
20335                             mp->transport_protocol);
20336 }
20337
20338 static int
20339 api_sw_interface_span_enable_disable (vat_main_t * vam)
20340 {
20341   unformat_input_t *i = vam->input;
20342   vl_api_sw_interface_span_enable_disable_t *mp;
20343   u32 src_sw_if_index = ~0;
20344   u32 dst_sw_if_index = ~0;
20345   u8 state = 3;
20346   int ret;
20347   u8 is_l2 = 0;
20348
20349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20350     {
20351       if (unformat
20352           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20353         ;
20354       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20355         ;
20356       else
20357         if (unformat
20358             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20359         ;
20360       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20361         ;
20362       else if (unformat (i, "disable"))
20363         state = 0;
20364       else if (unformat (i, "rx"))
20365         state = 1;
20366       else if (unformat (i, "tx"))
20367         state = 2;
20368       else if (unformat (i, "both"))
20369         state = 3;
20370       else if (unformat (i, "l2"))
20371         is_l2 = 1;
20372       else
20373         break;
20374     }
20375
20376   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20377
20378   mp->sw_if_index_from = htonl (src_sw_if_index);
20379   mp->sw_if_index_to = htonl (dst_sw_if_index);
20380   mp->state = state;
20381   mp->is_l2 = is_l2;
20382
20383   S (mp);
20384   W (ret);
20385   return ret;
20386 }
20387
20388 static void
20389 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20390                                             * mp)
20391 {
20392   vat_main_t *vam = &vat_main;
20393   u8 *sw_if_from_name = 0;
20394   u8 *sw_if_to_name = 0;
20395   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20396   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20397   char *states[] = { "none", "rx", "tx", "both" };
20398   hash_pair_t *p;
20399
20400   /* *INDENT-OFF* */
20401   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20402   ({
20403     if ((u32) p->value[0] == sw_if_index_from)
20404       {
20405         sw_if_from_name = (u8 *)(p->key);
20406         if (sw_if_to_name)
20407           break;
20408       }
20409     if ((u32) p->value[0] == sw_if_index_to)
20410       {
20411         sw_if_to_name = (u8 *)(p->key);
20412         if (sw_if_from_name)
20413           break;
20414       }
20415   }));
20416   /* *INDENT-ON* */
20417   print (vam->ofp, "%20s => %20s (%s)",
20418          sw_if_from_name, sw_if_to_name, states[mp->state]);
20419 }
20420
20421 static void
20422   vl_api_sw_interface_span_details_t_handler_json
20423   (vl_api_sw_interface_span_details_t * mp)
20424 {
20425   vat_main_t *vam = &vat_main;
20426   vat_json_node_t *node = NULL;
20427   u8 *sw_if_from_name = 0;
20428   u8 *sw_if_to_name = 0;
20429   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20430   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20431   hash_pair_t *p;
20432
20433   /* *INDENT-OFF* */
20434   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20435   ({
20436     if ((u32) p->value[0] == sw_if_index_from)
20437       {
20438         sw_if_from_name = (u8 *)(p->key);
20439         if (sw_if_to_name)
20440           break;
20441       }
20442     if ((u32) p->value[0] == sw_if_index_to)
20443       {
20444         sw_if_to_name = (u8 *)(p->key);
20445         if (sw_if_from_name)
20446           break;
20447       }
20448   }));
20449   /* *INDENT-ON* */
20450
20451   if (VAT_JSON_ARRAY != vam->json_tree.type)
20452     {
20453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20454       vat_json_init_array (&vam->json_tree);
20455     }
20456   node = vat_json_array_add (&vam->json_tree);
20457
20458   vat_json_init_object (node);
20459   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20460   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20461   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20462   if (0 != sw_if_to_name)
20463     {
20464       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20465     }
20466   vat_json_object_add_uint (node, "state", mp->state);
20467 }
20468
20469 static int
20470 api_sw_interface_span_dump (vat_main_t * vam)
20471 {
20472   unformat_input_t *input = vam->input;
20473   vl_api_sw_interface_span_dump_t *mp;
20474   vl_api_control_ping_t *mp_ping;
20475   u8 is_l2 = 0;
20476   int ret;
20477
20478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20479     {
20480       if (unformat (input, "l2"))
20481         is_l2 = 1;
20482       else
20483         break;
20484     }
20485
20486   M (SW_INTERFACE_SPAN_DUMP, mp);
20487   mp->is_l2 = is_l2;
20488   S (mp);
20489
20490   /* Use a control ping for synchronization */
20491   MPING (CONTROL_PING, mp_ping);
20492   S (mp_ping);
20493
20494   W (ret);
20495   return ret;
20496 }
20497
20498 int
20499 api_pg_create_interface (vat_main_t * vam)
20500 {
20501   unformat_input_t *input = vam->input;
20502   vl_api_pg_create_interface_t *mp;
20503
20504   u32 if_id = ~0;
20505   int ret;
20506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20507     {
20508       if (unformat (input, "if_id %d", &if_id))
20509         ;
20510       else
20511         break;
20512     }
20513   if (if_id == ~0)
20514     {
20515       errmsg ("missing pg interface index");
20516       return -99;
20517     }
20518
20519   /* Construct the API message */
20520   M (PG_CREATE_INTERFACE, mp);
20521   mp->context = 0;
20522   mp->interface_id = ntohl (if_id);
20523
20524   S (mp);
20525   W (ret);
20526   return ret;
20527 }
20528
20529 int
20530 api_pg_capture (vat_main_t * vam)
20531 {
20532   unformat_input_t *input = vam->input;
20533   vl_api_pg_capture_t *mp;
20534
20535   u32 if_id = ~0;
20536   u8 enable = 1;
20537   u32 count = 1;
20538   u8 pcap_file_set = 0;
20539   u8 *pcap_file = 0;
20540   int ret;
20541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20542     {
20543       if (unformat (input, "if_id %d", &if_id))
20544         ;
20545       else if (unformat (input, "pcap %s", &pcap_file))
20546         pcap_file_set = 1;
20547       else if (unformat (input, "count %d", &count))
20548         ;
20549       else if (unformat (input, "disable"))
20550         enable = 0;
20551       else
20552         break;
20553     }
20554   if (if_id == ~0)
20555     {
20556       errmsg ("missing pg interface index");
20557       return -99;
20558     }
20559   if (pcap_file_set > 0)
20560     {
20561       if (vec_len (pcap_file) > 255)
20562         {
20563           errmsg ("pcap file name is too long");
20564           return -99;
20565         }
20566     }
20567
20568   u32 name_len = vec_len (pcap_file);
20569   /* Construct the API message */
20570   M (PG_CAPTURE, mp);
20571   mp->context = 0;
20572   mp->interface_id = ntohl (if_id);
20573   mp->is_enabled = enable;
20574   mp->count = ntohl (count);
20575   mp->pcap_name_length = ntohl (name_len);
20576   if (pcap_file_set != 0)
20577     {
20578       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20579     }
20580   vec_free (pcap_file);
20581
20582   S (mp);
20583   W (ret);
20584   return ret;
20585 }
20586
20587 int
20588 api_pg_enable_disable (vat_main_t * vam)
20589 {
20590   unformat_input_t *input = vam->input;
20591   vl_api_pg_enable_disable_t *mp;
20592
20593   u8 enable = 1;
20594   u8 stream_name_set = 0;
20595   u8 *stream_name = 0;
20596   int ret;
20597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20598     {
20599       if (unformat (input, "stream %s", &stream_name))
20600         stream_name_set = 1;
20601       else if (unformat (input, "disable"))
20602         enable = 0;
20603       else
20604         break;
20605     }
20606
20607   if (stream_name_set > 0)
20608     {
20609       if (vec_len (stream_name) > 255)
20610         {
20611           errmsg ("stream name too long");
20612           return -99;
20613         }
20614     }
20615
20616   u32 name_len = vec_len (stream_name);
20617   /* Construct the API message */
20618   M (PG_ENABLE_DISABLE, mp);
20619   mp->context = 0;
20620   mp->is_enabled = enable;
20621   if (stream_name_set != 0)
20622     {
20623       mp->stream_name_length = ntohl (name_len);
20624       clib_memcpy (mp->stream_name, stream_name, name_len);
20625     }
20626   vec_free (stream_name);
20627
20628   S (mp);
20629   W (ret);
20630   return ret;
20631 }
20632
20633 int
20634 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20635 {
20636   unformat_input_t *input = vam->input;
20637   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20638
20639   u16 *low_ports = 0;
20640   u16 *high_ports = 0;
20641   u16 this_low;
20642   u16 this_hi;
20643   ip4_address_t ip4_addr;
20644   ip6_address_t ip6_addr;
20645   u32 length;
20646   u32 tmp, tmp2;
20647   u8 prefix_set = 0;
20648   u32 vrf_id = ~0;
20649   u8 is_add = 1;
20650   u8 is_ipv6 = 0;
20651   int ret;
20652
20653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20654     {
20655       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20656         {
20657           prefix_set = 1;
20658         }
20659       else
20660         if (unformat
20661             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20662         {
20663           prefix_set = 1;
20664           is_ipv6 = 1;
20665         }
20666       else if (unformat (input, "vrf %d", &vrf_id))
20667         ;
20668       else if (unformat (input, "del"))
20669         is_add = 0;
20670       else if (unformat (input, "port %d", &tmp))
20671         {
20672           if (tmp == 0 || tmp > 65535)
20673             {
20674               errmsg ("port %d out of range", tmp);
20675               return -99;
20676             }
20677           this_low = tmp;
20678           this_hi = this_low + 1;
20679           vec_add1 (low_ports, this_low);
20680           vec_add1 (high_ports, this_hi);
20681         }
20682       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20683         {
20684           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20685             {
20686               errmsg ("incorrect range parameters");
20687               return -99;
20688             }
20689           this_low = tmp;
20690           /* Note: in debug CLI +1 is added to high before
20691              passing to real fn that does "the work"
20692              (ip_source_and_port_range_check_add_del).
20693              This fn is a wrapper around the binary API fn a
20694              control plane will call, which expects this increment
20695              to have occurred. Hence letting the binary API control
20696              plane fn do the increment for consistency between VAT
20697              and other control planes.
20698            */
20699           this_hi = tmp2;
20700           vec_add1 (low_ports, this_low);
20701           vec_add1 (high_ports, this_hi);
20702         }
20703       else
20704         break;
20705     }
20706
20707   if (prefix_set == 0)
20708     {
20709       errmsg ("<address>/<mask> not specified");
20710       return -99;
20711     }
20712
20713   if (vrf_id == ~0)
20714     {
20715       errmsg ("VRF ID required, not specified");
20716       return -99;
20717     }
20718
20719   if (vrf_id == 0)
20720     {
20721       errmsg
20722         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20723       return -99;
20724     }
20725
20726   if (vec_len (low_ports) == 0)
20727     {
20728       errmsg ("At least one port or port range required");
20729       return -99;
20730     }
20731
20732   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20733
20734   mp->is_add = is_add;
20735
20736   if (is_ipv6)
20737     {
20738       mp->is_ipv6 = 1;
20739       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20740     }
20741   else
20742     {
20743       mp->is_ipv6 = 0;
20744       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20745     }
20746
20747   mp->mask_length = length;
20748   mp->number_of_ranges = vec_len (low_ports);
20749
20750   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20751   vec_free (low_ports);
20752
20753   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20754   vec_free (high_ports);
20755
20756   mp->vrf_id = ntohl (vrf_id);
20757
20758   S (mp);
20759   W (ret);
20760   return ret;
20761 }
20762
20763 int
20764 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20765 {
20766   unformat_input_t *input = vam->input;
20767   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20768   u32 sw_if_index = ~0;
20769   int vrf_set = 0;
20770   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20771   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20772   u8 is_add = 1;
20773   int ret;
20774
20775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20776     {
20777       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20778         ;
20779       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20780         ;
20781       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20782         vrf_set = 1;
20783       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20784         vrf_set = 1;
20785       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20786         vrf_set = 1;
20787       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20788         vrf_set = 1;
20789       else if (unformat (input, "del"))
20790         is_add = 0;
20791       else
20792         break;
20793     }
20794
20795   if (sw_if_index == ~0)
20796     {
20797       errmsg ("Interface required but not specified");
20798       return -99;
20799     }
20800
20801   if (vrf_set == 0)
20802     {
20803       errmsg ("VRF ID required but not specified");
20804       return -99;
20805     }
20806
20807   if (tcp_out_vrf_id == 0
20808       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20809     {
20810       errmsg
20811         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20812       return -99;
20813     }
20814
20815   /* Construct the API message */
20816   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20817
20818   mp->sw_if_index = ntohl (sw_if_index);
20819   mp->is_add = is_add;
20820   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20821   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20822   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20823   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20824
20825   /* send it... */
20826   S (mp);
20827
20828   /* Wait for a reply... */
20829   W (ret);
20830   return ret;
20831 }
20832
20833 static int
20834 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20835 {
20836   unformat_input_t *i = vam->input;
20837   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20838   u32 local_sa_id = 0;
20839   u32 remote_sa_id = 0;
20840   ip4_address_t src_address;
20841   ip4_address_t dst_address;
20842   u8 is_add = 1;
20843   int ret;
20844
20845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20846     {
20847       if (unformat (i, "local_sa %d", &local_sa_id))
20848         ;
20849       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20850         ;
20851       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20852         ;
20853       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20854         ;
20855       else if (unformat (i, "del"))
20856         is_add = 0;
20857       else
20858         {
20859           clib_warning ("parse error '%U'", format_unformat_error, i);
20860           return -99;
20861         }
20862     }
20863
20864   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20865
20866   mp->local_sa_id = ntohl (local_sa_id);
20867   mp->remote_sa_id = ntohl (remote_sa_id);
20868   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20869   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20870   mp->is_add = is_add;
20871
20872   S (mp);
20873   W (ret);
20874   return ret;
20875 }
20876
20877 static int
20878 api_punt (vat_main_t * vam)
20879 {
20880   unformat_input_t *i = vam->input;
20881   vl_api_punt_t *mp;
20882   u32 ipv = ~0;
20883   u32 protocol = ~0;
20884   u32 port = ~0;
20885   int is_add = 1;
20886   int ret;
20887
20888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20889     {
20890       if (unformat (i, "ip %d", &ipv))
20891         ;
20892       else if (unformat (i, "protocol %d", &protocol))
20893         ;
20894       else if (unformat (i, "port %d", &port))
20895         ;
20896       else if (unformat (i, "del"))
20897         is_add = 0;
20898       else
20899         {
20900           clib_warning ("parse error '%U'", format_unformat_error, i);
20901           return -99;
20902         }
20903     }
20904
20905   M (PUNT, mp);
20906
20907   mp->is_add = (u8) is_add;
20908   mp->ipv = (u8) ipv;
20909   mp->l4_protocol = (u8) protocol;
20910   mp->l4_port = htons ((u16) port);
20911
20912   S (mp);
20913   W (ret);
20914   return ret;
20915 }
20916
20917 static void vl_api_ipsec_gre_tunnel_details_t_handler
20918   (vl_api_ipsec_gre_tunnel_details_t * mp)
20919 {
20920   vat_main_t *vam = &vat_main;
20921
20922   print (vam->ofp, "%11d%15U%15U%14d%14d",
20923          ntohl (mp->sw_if_index),
20924          format_ip4_address, &mp->src_address,
20925          format_ip4_address, &mp->dst_address,
20926          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20927 }
20928
20929 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20930   (vl_api_ipsec_gre_tunnel_details_t * mp)
20931 {
20932   vat_main_t *vam = &vat_main;
20933   vat_json_node_t *node = NULL;
20934   struct in_addr ip4;
20935
20936   if (VAT_JSON_ARRAY != vam->json_tree.type)
20937     {
20938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20939       vat_json_init_array (&vam->json_tree);
20940     }
20941   node = vat_json_array_add (&vam->json_tree);
20942
20943   vat_json_init_object (node);
20944   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20945   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20946   vat_json_object_add_ip4 (node, "src_address", ip4);
20947   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20948   vat_json_object_add_ip4 (node, "dst_address", ip4);
20949   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20950   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20951 }
20952
20953 static int
20954 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20955 {
20956   unformat_input_t *i = vam->input;
20957   vl_api_ipsec_gre_tunnel_dump_t *mp;
20958   vl_api_control_ping_t *mp_ping;
20959   u32 sw_if_index;
20960   u8 sw_if_index_set = 0;
20961   int ret;
20962
20963   /* Parse args required to build the message */
20964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20965     {
20966       if (unformat (i, "sw_if_index %d", &sw_if_index))
20967         sw_if_index_set = 1;
20968       else
20969         break;
20970     }
20971
20972   if (sw_if_index_set == 0)
20973     {
20974       sw_if_index = ~0;
20975     }
20976
20977   if (!vam->json_output)
20978     {
20979       print (vam->ofp, "%11s%15s%15s%14s%14s",
20980              "sw_if_index", "src_address", "dst_address",
20981              "local_sa_id", "remote_sa_id");
20982     }
20983
20984   /* Get list of gre-tunnel interfaces */
20985   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20986
20987   mp->sw_if_index = htonl (sw_if_index);
20988
20989   S (mp);
20990
20991   /* Use a control ping for synchronization */
20992   MPING (CONTROL_PING, mp_ping);
20993   S (mp_ping);
20994
20995   W (ret);
20996   return ret;
20997 }
20998
20999 static int
21000 api_delete_subif (vat_main_t * vam)
21001 {
21002   unformat_input_t *i = vam->input;
21003   vl_api_delete_subif_t *mp;
21004   u32 sw_if_index = ~0;
21005   int ret;
21006
21007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21008     {
21009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21010         ;
21011       if (unformat (i, "sw_if_index %d", &sw_if_index))
21012         ;
21013       else
21014         break;
21015     }
21016
21017   if (sw_if_index == ~0)
21018     {
21019       errmsg ("missing sw_if_index");
21020       return -99;
21021     }
21022
21023   /* Construct the API message */
21024   M (DELETE_SUBIF, mp);
21025   mp->sw_if_index = ntohl (sw_if_index);
21026
21027   S (mp);
21028   W (ret);
21029   return ret;
21030 }
21031
21032 #define foreach_pbb_vtr_op      \
21033 _("disable",  L2_VTR_DISABLED)  \
21034 _("pop",  L2_VTR_POP_2)         \
21035 _("push",  L2_VTR_PUSH_2)
21036
21037 static int
21038 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21039 {
21040   unformat_input_t *i = vam->input;
21041   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21042   u32 sw_if_index = ~0, vtr_op = ~0;
21043   u16 outer_tag = ~0;
21044   u8 dmac[6], smac[6];
21045   u8 dmac_set = 0, smac_set = 0;
21046   u16 vlanid = 0;
21047   u32 sid = ~0;
21048   u32 tmp;
21049   int ret;
21050
21051   /* Shut up coverity */
21052   memset (dmac, 0, sizeof (dmac));
21053   memset (smac, 0, sizeof (smac));
21054
21055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21056     {
21057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21058         ;
21059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21060         ;
21061       else if (unformat (i, "vtr_op %d", &vtr_op))
21062         ;
21063 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21064       foreach_pbb_vtr_op
21065 #undef _
21066         else if (unformat (i, "translate_pbb_stag"))
21067         {
21068           if (unformat (i, "%d", &tmp))
21069             {
21070               vtr_op = L2_VTR_TRANSLATE_2_1;
21071               outer_tag = tmp;
21072             }
21073           else
21074             {
21075               errmsg
21076                 ("translate_pbb_stag operation requires outer tag definition");
21077               return -99;
21078             }
21079         }
21080       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21081         dmac_set++;
21082       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21083         smac_set++;
21084       else if (unformat (i, "sid %d", &sid))
21085         ;
21086       else if (unformat (i, "vlanid %d", &tmp))
21087         vlanid = tmp;
21088       else
21089         {
21090           clib_warning ("parse error '%U'", format_unformat_error, i);
21091           return -99;
21092         }
21093     }
21094
21095   if ((sw_if_index == ~0) || (vtr_op == ~0))
21096     {
21097       errmsg ("missing sw_if_index or vtr operation");
21098       return -99;
21099     }
21100   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21101       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21102     {
21103       errmsg
21104         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21105       return -99;
21106     }
21107
21108   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21109   mp->sw_if_index = ntohl (sw_if_index);
21110   mp->vtr_op = ntohl (vtr_op);
21111   mp->outer_tag = ntohs (outer_tag);
21112   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21113   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21114   mp->b_vlanid = ntohs (vlanid);
21115   mp->i_sid = ntohl (sid);
21116
21117   S (mp);
21118   W (ret);
21119   return ret;
21120 }
21121
21122 static int
21123 api_flow_classify_set_interface (vat_main_t * vam)
21124 {
21125   unformat_input_t *i = vam->input;
21126   vl_api_flow_classify_set_interface_t *mp;
21127   u32 sw_if_index;
21128   int sw_if_index_set;
21129   u32 ip4_table_index = ~0;
21130   u32 ip6_table_index = ~0;
21131   u8 is_add = 1;
21132   int ret;
21133
21134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21135     {
21136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21137         sw_if_index_set = 1;
21138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21139         sw_if_index_set = 1;
21140       else if (unformat (i, "del"))
21141         is_add = 0;
21142       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21143         ;
21144       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21145         ;
21146       else
21147         {
21148           clib_warning ("parse error '%U'", format_unformat_error, i);
21149           return -99;
21150         }
21151     }
21152
21153   if (sw_if_index_set == 0)
21154     {
21155       errmsg ("missing interface name or sw_if_index");
21156       return -99;
21157     }
21158
21159   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21160
21161   mp->sw_if_index = ntohl (sw_if_index);
21162   mp->ip4_table_index = ntohl (ip4_table_index);
21163   mp->ip6_table_index = ntohl (ip6_table_index);
21164   mp->is_add = is_add;
21165
21166   S (mp);
21167   W (ret);
21168   return ret;
21169 }
21170
21171 static int
21172 api_flow_classify_dump (vat_main_t * vam)
21173 {
21174   unformat_input_t *i = vam->input;
21175   vl_api_flow_classify_dump_t *mp;
21176   vl_api_control_ping_t *mp_ping;
21177   u8 type = FLOW_CLASSIFY_N_TABLES;
21178   int ret;
21179
21180   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21181     ;
21182   else
21183     {
21184       errmsg ("classify table type must be specified");
21185       return -99;
21186     }
21187
21188   if (!vam->json_output)
21189     {
21190       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21191     }
21192
21193   M (FLOW_CLASSIFY_DUMP, mp);
21194   mp->type = type;
21195   /* send it... */
21196   S (mp);
21197
21198   /* Use a control ping for synchronization */
21199   MPING (CONTROL_PING, mp_ping);
21200   S (mp_ping);
21201
21202   /* Wait for a reply... */
21203   W (ret);
21204   return ret;
21205 }
21206
21207 static int
21208 api_feature_enable_disable (vat_main_t * vam)
21209 {
21210   unformat_input_t *i = vam->input;
21211   vl_api_feature_enable_disable_t *mp;
21212   u8 *arc_name = 0;
21213   u8 *feature_name = 0;
21214   u32 sw_if_index = ~0;
21215   u8 enable = 1;
21216   int ret;
21217
21218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21219     {
21220       if (unformat (i, "arc_name %s", &arc_name))
21221         ;
21222       else if (unformat (i, "feature_name %s", &feature_name))
21223         ;
21224       else
21225         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21226         ;
21227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21228         ;
21229       else if (unformat (i, "disable"))
21230         enable = 0;
21231       else
21232         break;
21233     }
21234
21235   if (arc_name == 0)
21236     {
21237       errmsg ("missing arc name");
21238       return -99;
21239     }
21240   if (vec_len (arc_name) > 63)
21241     {
21242       errmsg ("arc name too long");
21243     }
21244
21245   if (feature_name == 0)
21246     {
21247       errmsg ("missing feature name");
21248       return -99;
21249     }
21250   if (vec_len (feature_name) > 63)
21251     {
21252       errmsg ("feature name too long");
21253     }
21254
21255   if (sw_if_index == ~0)
21256     {
21257       errmsg ("missing interface name or sw_if_index");
21258       return -99;
21259     }
21260
21261   /* Construct the API message */
21262   M (FEATURE_ENABLE_DISABLE, mp);
21263   mp->sw_if_index = ntohl (sw_if_index);
21264   mp->enable = enable;
21265   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21266   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21267   vec_free (arc_name);
21268   vec_free (feature_name);
21269
21270   S (mp);
21271   W (ret);
21272   return ret;
21273 }
21274
21275 static int
21276 api_sw_interface_tag_add_del (vat_main_t * vam)
21277 {
21278   unformat_input_t *i = vam->input;
21279   vl_api_sw_interface_tag_add_del_t *mp;
21280   u32 sw_if_index = ~0;
21281   u8 *tag = 0;
21282   u8 enable = 1;
21283   int ret;
21284
21285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21286     {
21287       if (unformat (i, "tag %s", &tag))
21288         ;
21289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21290         ;
21291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21292         ;
21293       else if (unformat (i, "del"))
21294         enable = 0;
21295       else
21296         break;
21297     }
21298
21299   if (sw_if_index == ~0)
21300     {
21301       errmsg ("missing interface name or sw_if_index");
21302       return -99;
21303     }
21304
21305   if (enable && (tag == 0))
21306     {
21307       errmsg ("no tag specified");
21308       return -99;
21309     }
21310
21311   /* Construct the API message */
21312   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21313   mp->sw_if_index = ntohl (sw_if_index);
21314   mp->is_add = enable;
21315   if (enable)
21316     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21317   vec_free (tag);
21318
21319   S (mp);
21320   W (ret);
21321   return ret;
21322 }
21323
21324 static void vl_api_l2_xconnect_details_t_handler
21325   (vl_api_l2_xconnect_details_t * mp)
21326 {
21327   vat_main_t *vam = &vat_main;
21328
21329   print (vam->ofp, "%15d%15d",
21330          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21331 }
21332
21333 static void vl_api_l2_xconnect_details_t_handler_json
21334   (vl_api_l2_xconnect_details_t * mp)
21335 {
21336   vat_main_t *vam = &vat_main;
21337   vat_json_node_t *node = NULL;
21338
21339   if (VAT_JSON_ARRAY != vam->json_tree.type)
21340     {
21341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21342       vat_json_init_array (&vam->json_tree);
21343     }
21344   node = vat_json_array_add (&vam->json_tree);
21345
21346   vat_json_init_object (node);
21347   vat_json_object_add_uint (node, "rx_sw_if_index",
21348                             ntohl (mp->rx_sw_if_index));
21349   vat_json_object_add_uint (node, "tx_sw_if_index",
21350                             ntohl (mp->tx_sw_if_index));
21351 }
21352
21353 static int
21354 api_l2_xconnect_dump (vat_main_t * vam)
21355 {
21356   vl_api_l2_xconnect_dump_t *mp;
21357   vl_api_control_ping_t *mp_ping;
21358   int ret;
21359
21360   if (!vam->json_output)
21361     {
21362       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21363     }
21364
21365   M (L2_XCONNECT_DUMP, mp);
21366
21367   S (mp);
21368
21369   /* Use a control ping for synchronization */
21370   MPING (CONTROL_PING, mp_ping);
21371   S (mp_ping);
21372
21373   W (ret);
21374   return ret;
21375 }
21376
21377 static int
21378 api_sw_interface_set_mtu (vat_main_t * vam)
21379 {
21380   unformat_input_t *i = vam->input;
21381   vl_api_sw_interface_set_mtu_t *mp;
21382   u32 sw_if_index = ~0;
21383   u32 mtu = 0;
21384   int ret;
21385
21386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21387     {
21388       if (unformat (i, "mtu %d", &mtu))
21389         ;
21390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21391         ;
21392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21393         ;
21394       else
21395         break;
21396     }
21397
21398   if (sw_if_index == ~0)
21399     {
21400       errmsg ("missing interface name or sw_if_index");
21401       return -99;
21402     }
21403
21404   if (mtu == 0)
21405     {
21406       errmsg ("no mtu specified");
21407       return -99;
21408     }
21409
21410   /* Construct the API message */
21411   M (SW_INTERFACE_SET_MTU, mp);
21412   mp->sw_if_index = ntohl (sw_if_index);
21413   mp->mtu = ntohs ((u16) mtu);
21414
21415   S (mp);
21416   W (ret);
21417   return ret;
21418 }
21419
21420 static int
21421 api_p2p_ethernet_add (vat_main_t * vam)
21422 {
21423   unformat_input_t *i = vam->input;
21424   vl_api_p2p_ethernet_add_t *mp;
21425   u32 parent_if_index = ~0;
21426   u32 sub_id = ~0;
21427   u8 remote_mac[6];
21428   u8 mac_set = 0;
21429   int ret;
21430
21431   memset (remote_mac, 0, sizeof (remote_mac));
21432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21433     {
21434       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21435         ;
21436       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21437         ;
21438       else
21439         if (unformat
21440             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21441         mac_set++;
21442       else if (unformat (i, "sub_id %d", &sub_id))
21443         ;
21444       else
21445         {
21446           clib_warning ("parse error '%U'", format_unformat_error, i);
21447           return -99;
21448         }
21449     }
21450
21451   if (parent_if_index == ~0)
21452     {
21453       errmsg ("missing interface name or sw_if_index");
21454       return -99;
21455     }
21456   if (mac_set == 0)
21457     {
21458       errmsg ("missing remote mac address");
21459       return -99;
21460     }
21461   if (sub_id == ~0)
21462     {
21463       errmsg ("missing sub-interface id");
21464       return -99;
21465     }
21466
21467   M (P2P_ETHERNET_ADD, mp);
21468   mp->parent_if_index = ntohl (parent_if_index);
21469   mp->subif_id = ntohl (sub_id);
21470   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21471
21472   S (mp);
21473   W (ret);
21474   return ret;
21475 }
21476
21477 static int
21478 api_p2p_ethernet_del (vat_main_t * vam)
21479 {
21480   unformat_input_t *i = vam->input;
21481   vl_api_p2p_ethernet_del_t *mp;
21482   u32 parent_if_index = ~0;
21483   u8 remote_mac[6];
21484   u8 mac_set = 0;
21485   int ret;
21486
21487   memset (remote_mac, 0, sizeof (remote_mac));
21488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21489     {
21490       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21491         ;
21492       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21493         ;
21494       else
21495         if (unformat
21496             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21497         mac_set++;
21498       else
21499         {
21500           clib_warning ("parse error '%U'", format_unformat_error, i);
21501           return -99;
21502         }
21503     }
21504
21505   if (parent_if_index == ~0)
21506     {
21507       errmsg ("missing interface name or sw_if_index");
21508       return -99;
21509     }
21510   if (mac_set == 0)
21511     {
21512       errmsg ("missing remote mac address");
21513       return -99;
21514     }
21515
21516   M (P2P_ETHERNET_DEL, mp);
21517   mp->parent_if_index = ntohl (parent_if_index);
21518   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21519
21520   S (mp);
21521   W (ret);
21522   return ret;
21523 }
21524
21525 static int
21526 api_lldp_config (vat_main_t * vam)
21527 {
21528   unformat_input_t *i = vam->input;
21529   vl_api_lldp_config_t *mp;
21530   int tx_hold = 0;
21531   int tx_interval = 0;
21532   u8 *sys_name = NULL;
21533   int ret;
21534
21535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21536     {
21537       if (unformat (i, "system-name %s", &sys_name))
21538         ;
21539       else if (unformat (i, "tx-hold %d", &tx_hold))
21540         ;
21541       else if (unformat (i, "tx-interval %d", &tx_interval))
21542         ;
21543       else
21544         {
21545           clib_warning ("parse error '%U'", format_unformat_error, i);
21546           return -99;
21547         }
21548     }
21549
21550   vec_add1 (sys_name, 0);
21551
21552   M (LLDP_CONFIG, mp);
21553   mp->tx_hold = htonl (tx_hold);
21554   mp->tx_interval = htonl (tx_interval);
21555   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21556   vec_free (sys_name);
21557
21558   S (mp);
21559   W (ret);
21560   return ret;
21561 }
21562
21563 static int
21564 api_sw_interface_set_lldp (vat_main_t * vam)
21565 {
21566   unformat_input_t *i = vam->input;
21567   vl_api_sw_interface_set_lldp_t *mp;
21568   u32 sw_if_index = ~0;
21569   u32 enable = 1;
21570   u8 *port_desc = NULL, *mgmt_oid = NULL;
21571   ip4_address_t ip4_addr;
21572   ip6_address_t ip6_addr;
21573   int ret;
21574
21575   memset (&ip4_addr, 0, sizeof (ip4_addr));
21576   memset (&ip6_addr, 0, sizeof (ip6_addr));
21577
21578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21579     {
21580       if (unformat (i, "disable"))
21581         enable = 0;
21582       else
21583         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21584         ;
21585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21586         ;
21587       else if (unformat (i, "port-desc %s", &port_desc))
21588         ;
21589       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21590         ;
21591       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21592         ;
21593       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21594         ;
21595       else
21596         break;
21597     }
21598
21599   if (sw_if_index == ~0)
21600     {
21601       errmsg ("missing interface name or sw_if_index");
21602       return -99;
21603     }
21604
21605   /* Construct the API message */
21606   vec_add1 (port_desc, 0);
21607   vec_add1 (mgmt_oid, 0);
21608   M (SW_INTERFACE_SET_LLDP, mp);
21609   mp->sw_if_index = ntohl (sw_if_index);
21610   mp->enable = enable;
21611   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21612   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21613   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21614   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21615   vec_free (port_desc);
21616   vec_free (mgmt_oid);
21617
21618   S (mp);
21619   W (ret);
21620   return ret;
21621 }
21622
21623 static int
21624 api_tcp_configure_src_addresses (vat_main_t * vam)
21625 {
21626   vl_api_tcp_configure_src_addresses_t *mp;
21627   unformat_input_t *i = vam->input;
21628   ip4_address_t v4first, v4last;
21629   ip6_address_t v6first, v6last;
21630   u8 range_set = 0;
21631   u32 vrf_id = 0;
21632   int ret;
21633
21634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21635     {
21636       if (unformat (i, "%U - %U",
21637                     unformat_ip4_address, &v4first,
21638                     unformat_ip4_address, &v4last))
21639         {
21640           if (range_set)
21641             {
21642               errmsg ("one range per message (range already set)");
21643               return -99;
21644             }
21645           range_set = 1;
21646         }
21647       else if (unformat (i, "%U - %U",
21648                          unformat_ip6_address, &v6first,
21649                          unformat_ip6_address, &v6last))
21650         {
21651           if (range_set)
21652             {
21653               errmsg ("one range per message (range already set)");
21654               return -99;
21655             }
21656           range_set = 2;
21657         }
21658       else if (unformat (i, "vrf %d", &vrf_id))
21659         ;
21660       else
21661         break;
21662     }
21663
21664   if (range_set == 0)
21665     {
21666       errmsg ("address range not set");
21667       return -99;
21668     }
21669
21670   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21671   mp->vrf_id = ntohl (vrf_id);
21672   /* ipv6? */
21673   if (range_set == 2)
21674     {
21675       mp->is_ipv6 = 1;
21676       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21677       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21678     }
21679   else
21680     {
21681       mp->is_ipv6 = 0;
21682       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21683       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21684     }
21685   S (mp);
21686   W (ret);
21687   return ret;
21688 }
21689
21690 static void vl_api_app_namespace_add_del_reply_t_handler
21691   (vl_api_app_namespace_add_del_reply_t * mp)
21692 {
21693   vat_main_t *vam = &vat_main;
21694   i32 retval = ntohl (mp->retval);
21695   if (vam->async_mode)
21696     {
21697       vam->async_errors += (retval < 0);
21698     }
21699   else
21700     {
21701       vam->retval = retval;
21702       if (retval == 0)
21703         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21704       vam->result_ready = 1;
21705     }
21706 }
21707
21708 static void vl_api_app_namespace_add_del_reply_t_handler_json
21709   (vl_api_app_namespace_add_del_reply_t * mp)
21710 {
21711   vat_main_t *vam = &vat_main;
21712   vat_json_node_t node;
21713
21714   vat_json_init_object (&node);
21715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21716   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21717
21718   vat_json_print (vam->ofp, &node);
21719   vat_json_free (&node);
21720
21721   vam->retval = ntohl (mp->retval);
21722   vam->result_ready = 1;
21723 }
21724
21725 static int
21726 api_app_namespace_add_del (vat_main_t * vam)
21727 {
21728   vl_api_app_namespace_add_del_t *mp;
21729   unformat_input_t *i = vam->input;
21730   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21731   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21732   u64 secret;
21733   int ret;
21734
21735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21736     {
21737       if (unformat (i, "id %_%v%_", &ns_id))
21738         ;
21739       else if (unformat (i, "secret %lu", &secret))
21740         secret_set = 1;
21741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21742         sw_if_index_set = 1;
21743       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21744         ;
21745       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21746         ;
21747       else
21748         break;
21749     }
21750   if (!ns_id || !secret_set || !sw_if_index_set)
21751     {
21752       errmsg ("namespace id, secret and sw_if_index must be set");
21753       return -99;
21754     }
21755   if (vec_len (ns_id) > 64)
21756     {
21757       errmsg ("namespace id too long");
21758       return -99;
21759     }
21760   M (APP_NAMESPACE_ADD_DEL, mp);
21761
21762   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21763   mp->namespace_id_len = vec_len (ns_id);
21764   mp->secret = clib_host_to_net_u64 (secret);
21765   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21766   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21767   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21768   vec_free (ns_id);
21769   S (mp);
21770   W (ret);
21771   return ret;
21772 }
21773
21774 static int
21775 api_memfd_segment_create (vat_main_t * vam)
21776 {
21777 #if VPP_API_TEST_BUILTIN == 0
21778   unformat_input_t *i = vam->input;
21779   vl_api_memfd_segment_create_t *mp;
21780   u64 size = 64 << 20;
21781   int ret;
21782
21783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21784     {
21785       if (unformat (i, "size %U", unformat_memory_size, &size))
21786         ;
21787       else
21788         break;
21789     }
21790
21791   M (MEMFD_SEGMENT_CREATE, mp);
21792   mp->requested_size = size;
21793   S (mp);
21794   W (ret);
21795   return ret;
21796
21797 #else
21798   errmsg ("memfd_segment_create (builtin) not supported");
21799   return -99;
21800 #endif
21801 }
21802
21803 static int
21804 api_dns_enable_disable (vat_main_t * vam)
21805 {
21806   unformat_input_t *line_input = vam->input;
21807   vl_api_dns_enable_disable_t *mp;
21808   u8 enable_disable = 1;
21809   int ret;
21810
21811   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21812     {
21813       if (unformat (line_input, "disable"))
21814         enable_disable = 0;
21815       if (unformat (line_input, "enable"))
21816         enable_disable = 1;
21817       else
21818         break;
21819     }
21820
21821   /* Construct the API message */
21822   M (DNS_ENABLE_DISABLE, mp);
21823   mp->enable = enable_disable;
21824
21825   /* send it... */
21826   S (mp);
21827   /* Wait for the reply */
21828   W (ret);
21829   return ret;
21830 }
21831
21832 static int
21833 api_dns_resolve_name (vat_main_t * vam)
21834 {
21835   unformat_input_t *line_input = vam->input;
21836   vl_api_dns_resolve_name_t *mp;
21837   u8 *name = 0;
21838   int ret;
21839
21840   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21841     {
21842       if (unformat (line_input, "%s", &name))
21843         ;
21844       else
21845         break;
21846     }
21847
21848   if (vec_len (name) > 127)
21849     {
21850       errmsg ("name too long");
21851       return -99;
21852     }
21853
21854   /* Construct the API message */
21855   M (DNS_RESOLVE_NAME, mp);
21856   memcpy (mp->name, name, vec_len (name));
21857   vec_free (name);
21858
21859   /* send it... */
21860   S (mp);
21861   /* Wait for the reply */
21862   W (ret);
21863   return ret;
21864 }
21865
21866 static int
21867 api_dns_resolve_ip (vat_main_t * vam)
21868 {
21869   unformat_input_t *line_input = vam->input;
21870   vl_api_dns_resolve_ip_t *mp;
21871   int is_ip6 = -1;
21872   ip4_address_t addr4;
21873   ip6_address_t addr6;
21874   int ret;
21875
21876   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21877     {
21878       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21879         is_ip6 = 1;
21880       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21881         is_ip6 = 0;
21882       else
21883         break;
21884     }
21885
21886   if (is_ip6 == -1)
21887     {
21888       errmsg ("missing address");
21889       return -99;
21890     }
21891
21892   /* Construct the API message */
21893   M (DNS_RESOLVE_IP, mp);
21894   mp->is_ip6 = is_ip6;
21895   if (is_ip6)
21896     memcpy (mp->address, &addr6, sizeof (addr6));
21897   else
21898     memcpy (mp->address, &addr4, sizeof (addr4));
21899
21900   /* send it... */
21901   S (mp);
21902   /* Wait for the reply */
21903   W (ret);
21904   return ret;
21905 }
21906
21907 static int
21908 api_dns_name_server_add_del (vat_main_t * vam)
21909 {
21910   unformat_input_t *i = vam->input;
21911   vl_api_dns_name_server_add_del_t *mp;
21912   u8 is_add = 1;
21913   ip6_address_t ip6_server;
21914   ip4_address_t ip4_server;
21915   int ip6_set = 0;
21916   int ip4_set = 0;
21917   int ret = 0;
21918
21919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21920     {
21921       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21922         ip6_set = 1;
21923       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21924         ip4_set = 1;
21925       else if (unformat (i, "del"))
21926         is_add = 0;
21927       else
21928         {
21929           clib_warning ("parse error '%U'", format_unformat_error, i);
21930           return -99;
21931         }
21932     }
21933
21934   if (ip4_set && ip6_set)
21935     {
21936       errmsg ("Only one server address allowed per message");
21937       return -99;
21938     }
21939   if ((ip4_set + ip6_set) == 0)
21940     {
21941       errmsg ("Server address required");
21942       return -99;
21943     }
21944
21945   /* Construct the API message */
21946   M (DNS_NAME_SERVER_ADD_DEL, mp);
21947
21948   if (ip6_set)
21949     {
21950       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21951       mp->is_ip6 = 1;
21952     }
21953   else
21954     {
21955       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21956       mp->is_ip6 = 0;
21957     }
21958
21959   mp->is_add = is_add;
21960
21961   /* send it... */
21962   S (mp);
21963
21964   /* Wait for a reply, return good/bad news  */
21965   W (ret);
21966   return ret;
21967 }
21968
21969 static void
21970 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21971 {
21972   vat_main_t *vam = &vat_main;
21973
21974   if (mp->is_ip4)
21975     {
21976       print (vam->ofp,
21977              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21978              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21979              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21980              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21981              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21982              clib_net_to_host_u32 (mp->action_index), mp->tag);
21983     }
21984   else
21985     {
21986       print (vam->ofp,
21987              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21988              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21989              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21990              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21991              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21992              clib_net_to_host_u32 (mp->action_index), mp->tag);
21993     }
21994 }
21995
21996 static void
21997 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21998                                              mp)
21999 {
22000   vat_main_t *vam = &vat_main;
22001   vat_json_node_t *node = NULL;
22002   struct in6_addr ip6;
22003   struct in_addr ip4;
22004
22005   if (VAT_JSON_ARRAY != vam->json_tree.type)
22006     {
22007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22008       vat_json_init_array (&vam->json_tree);
22009     }
22010   node = vat_json_array_add (&vam->json_tree);
22011   vat_json_init_object (node);
22012
22013   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22014   vat_json_object_add_uint (node, "appns_index",
22015                             clib_net_to_host_u32 (mp->appns_index));
22016   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22017   vat_json_object_add_uint (node, "scope", mp->scope);
22018   vat_json_object_add_uint (node, "action_index",
22019                             clib_net_to_host_u32 (mp->action_index));
22020   vat_json_object_add_uint (node, "lcl_port",
22021                             clib_net_to_host_u16 (mp->lcl_port));
22022   vat_json_object_add_uint (node, "rmt_port",
22023                             clib_net_to_host_u16 (mp->rmt_port));
22024   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22025   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22026   vat_json_object_add_string_copy (node, "tag", mp->tag);
22027   if (mp->is_ip4)
22028     {
22029       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22030       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22031       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22032       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22033     }
22034   else
22035     {
22036       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22037       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22038       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22039       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22040     }
22041 }
22042
22043 static int
22044 api_session_rule_add_del (vat_main_t * vam)
22045 {
22046   vl_api_session_rule_add_del_t *mp;
22047   unformat_input_t *i = vam->input;
22048   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22049   u32 appns_index = 0, scope = 0;
22050   ip4_address_t lcl_ip4, rmt_ip4;
22051   ip6_address_t lcl_ip6, rmt_ip6;
22052   u8 is_ip4 = 1, conn_set = 0;
22053   u8 is_add = 1, *tag = 0;
22054   int ret;
22055
22056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22057     {
22058       if (unformat (i, "del"))
22059         is_add = 0;
22060       else if (unformat (i, "add"))
22061         ;
22062       else if (unformat (i, "proto tcp"))
22063         proto = 0;
22064       else if (unformat (i, "proto udp"))
22065         proto = 1;
22066       else if (unformat (i, "appns %d", &appns_index))
22067         ;
22068       else if (unformat (i, "scope %d", &scope))
22069         ;
22070       else if (unformat (i, "tag %_%v%_", &tag))
22071         ;
22072       else
22073         if (unformat
22074             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22075              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22076              &rmt_port))
22077         {
22078           is_ip4 = 1;
22079           conn_set = 1;
22080         }
22081       else
22082         if (unformat
22083             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22084              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22085              &rmt_port))
22086         {
22087           is_ip4 = 0;
22088           conn_set = 1;
22089         }
22090       else if (unformat (i, "action %d", &action))
22091         ;
22092       else
22093         break;
22094     }
22095   if (proto == ~0 || !conn_set || action == ~0)
22096     {
22097       errmsg ("transport proto, connection and action must be set");
22098       return -99;
22099     }
22100
22101   if (scope > 3)
22102     {
22103       errmsg ("scope should be 0-3");
22104       return -99;
22105     }
22106
22107   M (SESSION_RULE_ADD_DEL, mp);
22108
22109   mp->is_ip4 = is_ip4;
22110   mp->transport_proto = proto;
22111   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22112   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22113   mp->lcl_plen = lcl_plen;
22114   mp->rmt_plen = rmt_plen;
22115   mp->action_index = clib_host_to_net_u32 (action);
22116   mp->appns_index = clib_host_to_net_u32 (appns_index);
22117   mp->scope = scope;
22118   mp->is_add = is_add;
22119   if (is_ip4)
22120     {
22121       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22122       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22123     }
22124   else
22125     {
22126       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22127       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22128     }
22129   if (tag)
22130     {
22131       clib_memcpy (mp->tag, tag, vec_len (tag));
22132       vec_free (tag);
22133     }
22134
22135   S (mp);
22136   W (ret);
22137   return ret;
22138 }
22139
22140 static int
22141 api_session_rules_dump (vat_main_t * vam)
22142 {
22143   vl_api_session_rules_dump_t *mp;
22144   vl_api_control_ping_t *mp_ping;
22145   int ret;
22146
22147   if (!vam->json_output)
22148     {
22149       print (vam->ofp, "%=20s", "Session Rules");
22150     }
22151
22152   M (SESSION_RULES_DUMP, mp);
22153   /* send it... */
22154   S (mp);
22155
22156   /* Use a control ping for synchronization */
22157   MPING (CONTROL_PING, mp_ping);
22158   S (mp_ping);
22159
22160   /* Wait for a reply... */
22161   W (ret);
22162   return ret;
22163 }
22164
22165 static int
22166 api_ip_container_proxy_add_del (vat_main_t * vam)
22167 {
22168   vl_api_ip_container_proxy_add_del_t *mp;
22169   unformat_input_t *i = vam->input;
22170   u32 plen = ~0, sw_if_index = ~0;
22171   ip4_address_t ip4;
22172   ip6_address_t ip6;
22173   u8 is_ip4 = 1;
22174   u8 is_add = 1;
22175   int ret;
22176
22177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22178     {
22179       if (unformat (i, "del"))
22180         is_add = 0;
22181       else if (unformat (i, "add"))
22182         ;
22183       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22184         {
22185           is_ip4 = 1;
22186           plen = 32;
22187         }
22188       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22189         {
22190           is_ip4 = 0;
22191           plen = 128;
22192         }
22193       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22194         ;
22195       else
22196         break;
22197     }
22198   if (sw_if_index == ~0 || plen == ~0)
22199     {
22200       errmsg ("address and sw_if_index must be set");
22201       return -99;
22202     }
22203
22204   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22205
22206   mp->is_ip4 = is_ip4;
22207   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22208   mp->plen = plen;
22209   mp->is_add = is_add;
22210   if (is_ip4)
22211     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22212   else
22213     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22214
22215   S (mp);
22216   W (ret);
22217   return ret;
22218 }
22219
22220 static int
22221 q_or_quit (vat_main_t * vam)
22222 {
22223 #if VPP_API_TEST_BUILTIN == 0
22224   longjmp (vam->jump_buf, 1);
22225 #endif
22226   return 0;                     /* not so much */
22227 }
22228
22229 static int
22230 q (vat_main_t * vam)
22231 {
22232   return q_or_quit (vam);
22233 }
22234
22235 static int
22236 quit (vat_main_t * vam)
22237 {
22238   return q_or_quit (vam);
22239 }
22240
22241 static int
22242 comment (vat_main_t * vam)
22243 {
22244   return 0;
22245 }
22246
22247 static int
22248 cmd_cmp (void *a1, void *a2)
22249 {
22250   u8 **c1 = a1;
22251   u8 **c2 = a2;
22252
22253   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22254 }
22255
22256 static int
22257 help (vat_main_t * vam)
22258 {
22259   u8 **cmds = 0;
22260   u8 *name = 0;
22261   hash_pair_t *p;
22262   unformat_input_t *i = vam->input;
22263   int j;
22264
22265   if (unformat (i, "%s", &name))
22266     {
22267       uword *hs;
22268
22269       vec_add1 (name, 0);
22270
22271       hs = hash_get_mem (vam->help_by_name, name);
22272       if (hs)
22273         print (vam->ofp, "usage: %s %s", name, hs[0]);
22274       else
22275         print (vam->ofp, "No such msg / command '%s'", name);
22276       vec_free (name);
22277       return 0;
22278     }
22279
22280   print (vam->ofp, "Help is available for the following:");
22281
22282     /* *INDENT-OFF* */
22283     hash_foreach_pair (p, vam->function_by_name,
22284     ({
22285       vec_add1 (cmds, (u8 *)(p->key));
22286     }));
22287     /* *INDENT-ON* */
22288
22289   vec_sort_with_function (cmds, cmd_cmp);
22290
22291   for (j = 0; j < vec_len (cmds); j++)
22292     print (vam->ofp, "%s", cmds[j]);
22293
22294   vec_free (cmds);
22295   return 0;
22296 }
22297
22298 static int
22299 set (vat_main_t * vam)
22300 {
22301   u8 *name = 0, *value = 0;
22302   unformat_input_t *i = vam->input;
22303
22304   if (unformat (i, "%s", &name))
22305     {
22306       /* The input buffer is a vector, not a string. */
22307       value = vec_dup (i->buffer);
22308       vec_delete (value, i->index, 0);
22309       /* Almost certainly has a trailing newline */
22310       if (value[vec_len (value) - 1] == '\n')
22311         value[vec_len (value) - 1] = 0;
22312       /* Make sure it's a proper string, one way or the other */
22313       vec_add1 (value, 0);
22314       (void) clib_macro_set_value (&vam->macro_main,
22315                                    (char *) name, (char *) value);
22316     }
22317   else
22318     errmsg ("usage: set <name> <value>");
22319
22320   vec_free (name);
22321   vec_free (value);
22322   return 0;
22323 }
22324
22325 static int
22326 unset (vat_main_t * vam)
22327 {
22328   u8 *name = 0;
22329
22330   if (unformat (vam->input, "%s", &name))
22331     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22332       errmsg ("unset: %s wasn't set", name);
22333   vec_free (name);
22334   return 0;
22335 }
22336
22337 typedef struct
22338 {
22339   u8 *name;
22340   u8 *value;
22341 } macro_sort_t;
22342
22343
22344 static int
22345 macro_sort_cmp (void *a1, void *a2)
22346 {
22347   macro_sort_t *s1 = a1;
22348   macro_sort_t *s2 = a2;
22349
22350   return strcmp ((char *) (s1->name), (char *) (s2->name));
22351 }
22352
22353 static int
22354 dump_macro_table (vat_main_t * vam)
22355 {
22356   macro_sort_t *sort_me = 0, *sm;
22357   int i;
22358   hash_pair_t *p;
22359
22360     /* *INDENT-OFF* */
22361     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22362     ({
22363       vec_add2 (sort_me, sm, 1);
22364       sm->name = (u8 *)(p->key);
22365       sm->value = (u8 *) (p->value[0]);
22366     }));
22367     /* *INDENT-ON* */
22368
22369   vec_sort_with_function (sort_me, macro_sort_cmp);
22370
22371   if (vec_len (sort_me))
22372     print (vam->ofp, "%-15s%s", "Name", "Value");
22373   else
22374     print (vam->ofp, "The macro table is empty...");
22375
22376   for (i = 0; i < vec_len (sort_me); i++)
22377     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22378   return 0;
22379 }
22380
22381 static int
22382 dump_node_table (vat_main_t * vam)
22383 {
22384   int i, j;
22385   vlib_node_t *node, *next_node;
22386
22387   if (vec_len (vam->graph_nodes) == 0)
22388     {
22389       print (vam->ofp, "Node table empty, issue get_node_graph...");
22390       return 0;
22391     }
22392
22393   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22394     {
22395       node = vam->graph_nodes[i];
22396       print (vam->ofp, "[%d] %s", i, node->name);
22397       for (j = 0; j < vec_len (node->next_nodes); j++)
22398         {
22399           if (node->next_nodes[j] != ~0)
22400             {
22401               next_node = vam->graph_nodes[node->next_nodes[j]];
22402               print (vam->ofp, "  [%d] %s", j, next_node->name);
22403             }
22404         }
22405     }
22406   return 0;
22407 }
22408
22409 static int
22410 value_sort_cmp (void *a1, void *a2)
22411 {
22412   name_sort_t *n1 = a1;
22413   name_sort_t *n2 = a2;
22414
22415   if (n1->value < n2->value)
22416     return -1;
22417   if (n1->value > n2->value)
22418     return 1;
22419   return 0;
22420 }
22421
22422
22423 static int
22424 dump_msg_api_table (vat_main_t * vam)
22425 {
22426   api_main_t *am = &api_main;
22427   name_sort_t *nses = 0, *ns;
22428   hash_pair_t *hp;
22429   int i;
22430
22431   /* *INDENT-OFF* */
22432   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22433   ({
22434     vec_add2 (nses, ns, 1);
22435     ns->name = (u8 *)(hp->key);
22436     ns->value = (u32) hp->value[0];
22437   }));
22438   /* *INDENT-ON* */
22439
22440   vec_sort_with_function (nses, value_sort_cmp);
22441
22442   for (i = 0; i < vec_len (nses); i++)
22443     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22444   vec_free (nses);
22445   return 0;
22446 }
22447
22448 static int
22449 get_msg_id (vat_main_t * vam)
22450 {
22451   u8 *name_and_crc;
22452   u32 message_index;
22453
22454   if (unformat (vam->input, "%s", &name_and_crc))
22455     {
22456       message_index = vl_api_get_msg_index (name_and_crc);
22457       if (message_index == ~0)
22458         {
22459           print (vam->ofp, " '%s' not found", name_and_crc);
22460           return 0;
22461         }
22462       print (vam->ofp, " '%s' has message index %d",
22463              name_and_crc, message_index);
22464       return 0;
22465     }
22466   errmsg ("name_and_crc required...");
22467   return 0;
22468 }
22469
22470 static int
22471 search_node_table (vat_main_t * vam)
22472 {
22473   unformat_input_t *line_input = vam->input;
22474   u8 *node_to_find;
22475   int j;
22476   vlib_node_t *node, *next_node;
22477   uword *p;
22478
22479   if (vam->graph_node_index_by_name == 0)
22480     {
22481       print (vam->ofp, "Node table empty, issue get_node_graph...");
22482       return 0;
22483     }
22484
22485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22486     {
22487       if (unformat (line_input, "%s", &node_to_find))
22488         {
22489           vec_add1 (node_to_find, 0);
22490           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22491           if (p == 0)
22492             {
22493               print (vam->ofp, "%s not found...", node_to_find);
22494               goto out;
22495             }
22496           node = vam->graph_nodes[p[0]];
22497           print (vam->ofp, "[%d] %s", p[0], node->name);
22498           for (j = 0; j < vec_len (node->next_nodes); j++)
22499             {
22500               if (node->next_nodes[j] != ~0)
22501                 {
22502                   next_node = vam->graph_nodes[node->next_nodes[j]];
22503                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22504                 }
22505             }
22506         }
22507
22508       else
22509         {
22510           clib_warning ("parse error '%U'", format_unformat_error,
22511                         line_input);
22512           return -99;
22513         }
22514
22515     out:
22516       vec_free (node_to_find);
22517
22518     }
22519
22520   return 0;
22521 }
22522
22523
22524 static int
22525 script (vat_main_t * vam)
22526 {
22527 #if (VPP_API_TEST_BUILTIN==0)
22528   u8 *s = 0;
22529   char *save_current_file;
22530   unformat_input_t save_input;
22531   jmp_buf save_jump_buf;
22532   u32 save_line_number;
22533
22534   FILE *new_fp, *save_ifp;
22535
22536   if (unformat (vam->input, "%s", &s))
22537     {
22538       new_fp = fopen ((char *) s, "r");
22539       if (new_fp == 0)
22540         {
22541           errmsg ("Couldn't open script file %s", s);
22542           vec_free (s);
22543           return -99;
22544         }
22545     }
22546   else
22547     {
22548       errmsg ("Missing script name");
22549       return -99;
22550     }
22551
22552   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22553   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22554   save_ifp = vam->ifp;
22555   save_line_number = vam->input_line_number;
22556   save_current_file = (char *) vam->current_file;
22557
22558   vam->input_line_number = 0;
22559   vam->ifp = new_fp;
22560   vam->current_file = s;
22561   do_one_file (vam);
22562
22563   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22564   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22565   vam->ifp = save_ifp;
22566   vam->input_line_number = save_line_number;
22567   vam->current_file = (u8 *) save_current_file;
22568   vec_free (s);
22569
22570   return 0;
22571 #else
22572   clib_warning ("use the exec command...");
22573   return -99;
22574 #endif
22575 }
22576
22577 static int
22578 echo (vat_main_t * vam)
22579 {
22580   print (vam->ofp, "%v", vam->input->buffer);
22581   return 0;
22582 }
22583
22584 /* List of API message constructors, CLI names map to api_xxx */
22585 #define foreach_vpe_api_msg                                             \
22586 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22587 _(sw_interface_dump,"")                                                 \
22588 _(sw_interface_set_flags,                                               \
22589   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22590 _(sw_interface_add_del_address,                                         \
22591   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22592 _(sw_interface_set_rx_mode,                                             \
22593   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22594 _(sw_interface_set_table,                                               \
22595   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22596 _(sw_interface_set_mpls_enable,                                         \
22597   "<intfc> | sw_if_index [disable | dis]")                              \
22598 _(sw_interface_set_vpath,                                               \
22599   "<intfc> | sw_if_index <id> enable | disable")                        \
22600 _(sw_interface_set_vxlan_bypass,                                        \
22601   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22602 _(sw_interface_set_geneve_bypass,                                       \
22603   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22604 _(sw_interface_set_l2_xconnect,                                         \
22605   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22606   "enable | disable")                                                   \
22607 _(sw_interface_set_l2_bridge,                                           \
22608   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22609   "[shg <split-horizon-group>] [bvi]\n"                                 \
22610   "enable | disable")                                                   \
22611 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22612 _(bridge_domain_add_del,                                                \
22613   "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") \
22614 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22615 _(l2fib_add_del,                                                        \
22616   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22617 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22618 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22619 _(l2_flags,                                                             \
22620   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22621 _(bridge_flags,                                                         \
22622   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22623 _(tap_connect,                                                          \
22624   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22625 _(tap_modify,                                                           \
22626   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22627 _(tap_delete,                                                           \
22628   "<vpp-if-name> | sw_if_index <id>")                                   \
22629 _(sw_interface_tap_dump, "")                                            \
22630 _(tap_create_v2,                                                        \
22631   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22632 _(tap_delete_v2,                                                        \
22633   "<vpp-if-name> | sw_if_index <id>")                                   \
22634 _(sw_interface_tap_v2_dump, "")                                         \
22635 _(ip_table_add_del,                                                     \
22636   "table-id <n> [ipv6]\n")                                              \
22637 _(ip_add_del_route,                                                     \
22638   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22639   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22640   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22641   "[multipath] [count <n>]")                                            \
22642 _(ip_mroute_add_del,                                                    \
22643   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22644   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22645 _(mpls_table_add_del,                                                   \
22646   "table-id <n>\n")                                                     \
22647 _(mpls_route_add_del,                                                   \
22648   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22649   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22650   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22651   "[multipath] [count <n>]")                                            \
22652 _(mpls_ip_bind_unbind,                                                  \
22653   "<label> <addr/len>")                                                 \
22654 _(mpls_tunnel_add_del,                                                  \
22655   " via <addr> [table-id <n>]\n"                                        \
22656   "sw_if_index <id>] [l2]  [del]")                                      \
22657 _(bier_table_add_del,                                                   \
22658   "<label> <sub-domain> <set> <bsl> [del]")                             \
22659 _(bier_route_add_del,                                                   \
22660   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22661   "[<intfc> | sw_if_index <id>]"                                        \
22662   "[weight <n>] [del] [multipath]")                                     \
22663 _(proxy_arp_add_del,                                                    \
22664   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22665 _(proxy_arp_intfc_enable_disable,                                       \
22666   "<intfc> | sw_if_index <id> enable | disable")                        \
22667 _(sw_interface_set_unnumbered,                                          \
22668   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22669 _(ip_neighbor_add_del,                                                  \
22670   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22671   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22672 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22673 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22674   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22675   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22676   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22677 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22678 _(reset_fib, "vrf <n> [ipv6]")                                          \
22679 _(dhcp_proxy_config,                                                    \
22680   "svr <v46-address> src <v46-address>\n"                               \
22681    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22682 _(dhcp_proxy_set_vss,                                                   \
22683   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22684 _(dhcp_proxy_dump, "ip6")                                               \
22685 _(dhcp_client_config,                                                   \
22686   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22687 _(set_ip_flow_hash,                                                     \
22688   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22689 _(sw_interface_ip6_enable_disable,                                      \
22690   "<intfc> | sw_if_index <id> enable | disable")                        \
22691 _(sw_interface_ip6_set_link_local_address,                              \
22692   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22693 _(ip6nd_proxy_add_del,                                                  \
22694   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22695 _(ip6nd_proxy_dump, "")                                                 \
22696 _(sw_interface_ip6nd_ra_prefix,                                         \
22697   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22698   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22699   "[nolink] [isno]")                                                    \
22700 _(sw_interface_ip6nd_ra_config,                                         \
22701   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22702   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22703   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22704 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22705 _(l2_patch_add_del,                                                     \
22706   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22707   "enable | disable")                                                   \
22708 _(sr_localsid_add_del,                                                  \
22709   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22710   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22711 _(classify_add_del_table,                                               \
22712   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22713   " [del] [del-chain] mask <mask-value>\n"                              \
22714   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22715   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22716 _(classify_add_del_session,                                             \
22717   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22718   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22719   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22720   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22721 _(classify_set_interface_ip_table,                                      \
22722   "<intfc> | sw_if_index <nn> table <nn>")                              \
22723 _(classify_set_interface_l2_tables,                                     \
22724   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22725   "  [other-table <nn>]")                                               \
22726 _(get_node_index, "node <node-name")                                    \
22727 _(add_node_next, "node <node-name> next <next-node-name>")              \
22728 _(l2tpv3_create_tunnel,                                                 \
22729   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22730   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22731   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22732 _(l2tpv3_set_tunnel_cookies,                                            \
22733   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22734   "[new_remote_cookie <nn>]\n")                                         \
22735 _(l2tpv3_interface_enable_disable,                                      \
22736   "<intfc> | sw_if_index <nn> enable | disable")                        \
22737 _(l2tpv3_set_lookup_key,                                                \
22738   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22739 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22740 _(vxlan_add_del_tunnel,                                                 \
22741   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22742   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22743   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22744 _(geneve_add_del_tunnel,                                                \
22745   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22746   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22747   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22748 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22749 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22750 _(gre_add_del_tunnel,                                                   \
22751   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22752 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22753 _(l2_fib_clear_table, "")                                               \
22754 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22755 _(l2_interface_vlan_tag_rewrite,                                        \
22756   "<intfc> | sw_if_index <nn> \n"                                       \
22757   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22758   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22759 _(create_vhost_user_if,                                                 \
22760         "socket <filename> [server] [renumber <dev_instance>] "         \
22761         "[mac <mac_address>]")                                          \
22762 _(modify_vhost_user_if,                                                 \
22763         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22764         "[server] [renumber <dev_instance>]")                           \
22765 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22766 _(sw_interface_vhost_user_dump, "")                                     \
22767 _(show_version, "")                                                     \
22768 _(vxlan_gpe_add_del_tunnel,                                             \
22769   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22770   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22771   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22772   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22773 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22774 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22775 _(interface_name_renumber,                                              \
22776   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22777 _(input_acl_set_interface,                                              \
22778   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22779   "  [l2-table <nn>] [del]")                                            \
22780 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22781 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22782 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22783 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22784 _(ip_dump, "ipv4 | ipv6")                                               \
22785 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22786 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22787   "  spid_id <n> ")                                                     \
22788 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22789   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22790   "  integ_alg <alg> integ_key <hex>")                                  \
22791 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22792   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22793   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22794   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22795 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22796 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22797   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22798   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22799   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22800 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22801 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22802   "  <alg> <hex>\n")                                                    \
22803 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22804 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22805 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22806   "(auth_data 0x<data> | auth_data <data>)")                            \
22807 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22808   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22809 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22810   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22811   "(local|remote)")                                                     \
22812 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22813 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22814 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22815 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22816 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22817 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22818 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22819 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22820 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22821 _(delete_loopback,"sw_if_index <nn>")                                   \
22822 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22823 _(map_add_domain,                                                       \
22824   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22825   "ip6-src <ip6addr> "                                                  \
22826   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22827 _(map_del_domain, "index <n>")                                          \
22828 _(map_add_del_rule,                                                     \
22829   "index <n> psid <n> dst <ip6addr> [del]")                             \
22830 _(map_domain_dump, "")                                                  \
22831 _(map_rule_dump, "index <map-domain>")                                  \
22832 _(want_interface_events,  "enable|disable")                             \
22833 _(want_stats,"enable|disable")                                          \
22834 _(get_first_msg_id, "client <name>")                                    \
22835 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22836 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22837   "fib-id <nn> [ip4][ip6][default]")                                    \
22838 _(get_node_graph, " ")                                                  \
22839 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22840 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22841 _(ioam_disable, "")                                                     \
22842 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22843                             " sw_if_index <sw_if_index> p <priority> "  \
22844                             "w <weight>] [del]")                        \
22845 _(one_add_del_locator, "locator-set <locator_name> "                    \
22846                         "iface <intf> | sw_if_index <sw_if_index> "     \
22847                         "p <priority> w <weight> [del]")                \
22848 _(one_add_del_local_eid,"vni <vni> eid "                                \
22849                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22850                          "locator-set <locator_name> [del]"             \
22851                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22852 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22853 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22854 _(one_enable_disable, "enable|disable")                                 \
22855 _(one_map_register_enable_disable, "enable|disable")                    \
22856 _(one_map_register_fallback_threshold, "<value>")                       \
22857 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22858 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22859                                "[seid <seid>] "                         \
22860                                "rloc <locator> p <prio> "               \
22861                                "w <weight> [rloc <loc> ... ] "          \
22862                                "action <action> [del-all]")             \
22863 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22864                           "<local-eid>")                                \
22865 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22866 _(one_use_petr, "ip-address> | disable")                                \
22867 _(one_map_request_mode, "src-dst|dst-only")                             \
22868 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22869 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22870 _(one_locator_set_dump, "[local | remote]")                             \
22871 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22872 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22873                        "[local] | [remote]")                            \
22874 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22875 _(one_ndp_bd_get, "")                                                   \
22876 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22877 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22878 _(one_l2_arp_bd_get, "")                                                \
22879 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22880 _(one_stats_enable_disable, "enable|disalbe")                           \
22881 _(show_one_stats_enable_disable, "")                                    \
22882 _(one_eid_table_vni_dump, "")                                           \
22883 _(one_eid_table_map_dump, "l2|l3")                                      \
22884 _(one_map_resolver_dump, "")                                            \
22885 _(one_map_server_dump, "")                                              \
22886 _(one_adjacencies_get, "vni <vni>")                                     \
22887 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22888 _(show_one_rloc_probe_state, "")                                        \
22889 _(show_one_map_register_state, "")                                      \
22890 _(show_one_status, "")                                                  \
22891 _(one_stats_dump, "")                                                   \
22892 _(one_stats_flush, "")                                                  \
22893 _(one_get_map_request_itr_rlocs, "")                                    \
22894 _(one_map_register_set_ttl, "<ttl>")                                    \
22895 _(one_set_transport_protocol, "udp|api")                                \
22896 _(one_get_transport_protocol, "")                                       \
22897 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22898 _(one_show_xtr_mode, "")                                                \
22899 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22900 _(one_show_pitr_mode, "")                                               \
22901 _(one_enable_disable_petr_mode, "enable|disable")                       \
22902 _(one_show_petr_mode, "")                                               \
22903 _(show_one_nsh_mapping, "")                                             \
22904 _(show_one_pitr, "")                                                    \
22905 _(show_one_use_petr, "")                                                \
22906 _(show_one_map_request_mode, "")                                        \
22907 _(show_one_map_register_ttl, "")                                        \
22908 _(show_one_map_register_fallback_threshold, "")                         \
22909 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22910                             " sw_if_index <sw_if_index> p <priority> "  \
22911                             "w <weight>] [del]")                        \
22912 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22913                         "iface <intf> | sw_if_index <sw_if_index> "     \
22914                         "p <priority> w <weight> [del]")                \
22915 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22916                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22917                          "locator-set <locator_name> [del]"             \
22918                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22919 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22920 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22921 _(lisp_enable_disable, "enable|disable")                                \
22922 _(lisp_map_register_enable_disable, "enable|disable")                   \
22923 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22924 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22925                                "[seid <seid>] "                         \
22926                                "rloc <locator> p <prio> "               \
22927                                "w <weight> [rloc <loc> ... ] "          \
22928                                "action <action> [del-all]")             \
22929 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22930                           "<local-eid>")                                \
22931 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22932 _(lisp_use_petr, "<ip-address> | disable")                              \
22933 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22934 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22935 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22936 _(lisp_locator_set_dump, "[local | remote]")                            \
22937 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22938 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22939                        "[local] | [remote]")                            \
22940 _(lisp_eid_table_vni_dump, "")                                          \
22941 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22942 _(lisp_map_resolver_dump, "")                                           \
22943 _(lisp_map_server_dump, "")                                             \
22944 _(lisp_adjacencies_get, "vni <vni>")                                    \
22945 _(gpe_fwd_entry_vnis_get, "")                                           \
22946 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22947 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22948                                 "[table <table-id>]")                   \
22949 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22950 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22951 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22952 _(gpe_get_encap_mode, "")                                               \
22953 _(lisp_gpe_add_del_iface, "up|down")                                    \
22954 _(lisp_gpe_enable_disable, "enable|disable")                            \
22955 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22956   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22957 _(show_lisp_rloc_probe_state, "")                                       \
22958 _(show_lisp_map_register_state, "")                                     \
22959 _(show_lisp_status, "")                                                 \
22960 _(lisp_get_map_request_itr_rlocs, "")                                   \
22961 _(show_lisp_pitr, "")                                                   \
22962 _(show_lisp_use_petr, "")                                               \
22963 _(show_lisp_map_request_mode, "")                                       \
22964 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22965 _(af_packet_delete, "name <host interface name>")                       \
22966 _(policer_add_del, "name <policer name> <params> [del]")                \
22967 _(policer_dump, "[name <policer name>]")                                \
22968 _(policer_classify_set_interface,                                       \
22969   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22970   "  [l2-table <nn>] [del]")                                            \
22971 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22972 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22973     "[master|slave]")                                                   \
22974 _(netmap_delete, "name <interface name>")                               \
22975 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22976 _(mpls_fib_dump, "")                                                    \
22977 _(classify_table_ids, "")                                               \
22978 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22979 _(classify_table_info, "table_id <nn>")                                 \
22980 _(classify_session_dump, "table_id <nn>")                               \
22981 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22982     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22983     "[template_interval <nn>] [udp_checksum]")                          \
22984 _(ipfix_exporter_dump, "")                                              \
22985 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22986 _(ipfix_classify_stream_dump, "")                                       \
22987 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22988 _(ipfix_classify_table_dump, "")                                        \
22989 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22990 _(sw_interface_span_dump, "[l2]")                                           \
22991 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22992 _(pg_create_interface, "if_id <nn>")                                    \
22993 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22994 _(pg_enable_disable, "[stream <id>] disable")                           \
22995 _(ip_source_and_port_range_check_add_del,                               \
22996   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22997 _(ip_source_and_port_range_check_interface_add_del,                     \
22998   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22999   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23000 _(ipsec_gre_add_del_tunnel,                                             \
23001   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23002 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23003 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23004 _(l2_interface_pbb_tag_rewrite,                                         \
23005   "<intfc> | sw_if_index <nn> \n"                                       \
23006   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23007   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23008 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23009 _(flow_classify_set_interface,                                          \
23010   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23011 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23012 _(ip_fib_dump, "")                                                      \
23013 _(ip_mfib_dump, "")                                                     \
23014 _(ip6_fib_dump, "")                                                     \
23015 _(ip6_mfib_dump, "")                                                    \
23016 _(feature_enable_disable, "arc_name <arc_name> "                        \
23017   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23018 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23019 "[disable]")                                                            \
23020 _(l2_xconnect_dump, "")                                                 \
23021 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23022 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23023 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23024 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23025 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23026 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23027 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23028   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23029 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23030 _(memfd_segment_create,"size <nnn>")                                    \
23031 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23032 _(dns_enable_disable, "[enable][disable]")                              \
23033 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23034 _(dns_resolve_name, "<hostname>")                                       \
23035 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23036 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23037 _(dns_resolve_name, "<hostname>")                                       \
23038 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23039   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23040 _(session_rules_dump, "")                                               \
23041 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23042
23043 /* List of command functions, CLI names map directly to functions */
23044 #define foreach_cli_function                                    \
23045 _(comment, "usage: comment <ignore-rest-of-line>")              \
23046 _(dump_interface_table, "usage: dump_interface_table")          \
23047 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23048 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23049 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23050 _(dump_stats_table, "usage: dump_stats_table")                  \
23051 _(dump_macro_table, "usage: dump_macro_table ")                 \
23052 _(dump_node_table, "usage: dump_node_table")                    \
23053 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23054 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23055 _(echo, "usage: echo <message>")                                \
23056 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23057 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23058 _(help, "usage: help")                                          \
23059 _(q, "usage: quit")                                             \
23060 _(quit, "usage: quit")                                          \
23061 _(search_node_table, "usage: search_node_table <name>...")      \
23062 _(set, "usage: set <variable-name> <value>")                    \
23063 _(script, "usage: script <file-name>")                          \
23064 _(unset, "usage: unset <variable-name>")
23065 #define _(N,n)                                  \
23066     static void vl_api_##n##_t_handler_uni      \
23067     (vl_api_##n##_t * mp)                       \
23068     {                                           \
23069         vat_main_t * vam = &vat_main;           \
23070         if (vam->json_output) {                 \
23071             vl_api_##n##_t_handler_json(mp);    \
23072         } else {                                \
23073             vl_api_##n##_t_handler(mp);         \
23074         }                                       \
23075     }
23076 foreach_vpe_api_reply_msg;
23077 #if VPP_API_TEST_BUILTIN == 0
23078 foreach_standalone_reply_msg;
23079 #endif
23080 #undef _
23081
23082 void
23083 vat_api_hookup (vat_main_t * vam)
23084 {
23085 #define _(N,n)                                                  \
23086     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23087                            vl_api_##n##_t_handler_uni,          \
23088                            vl_noop_handler,                     \
23089                            vl_api_##n##_t_endian,               \
23090                            vl_api_##n##_t_print,                \
23091                            sizeof(vl_api_##n##_t), 1);
23092   foreach_vpe_api_reply_msg;
23093 #if VPP_API_TEST_BUILTIN == 0
23094   foreach_standalone_reply_msg;
23095 #endif
23096 #undef _
23097
23098 #if (VPP_API_TEST_BUILTIN==0)
23099   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23100
23101   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23102
23103   vam->function_by_name = hash_create_string (0, sizeof (uword));
23104
23105   vam->help_by_name = hash_create_string (0, sizeof (uword));
23106 #endif
23107
23108   /* API messages we can send */
23109 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23110   foreach_vpe_api_msg;
23111 #undef _
23112
23113   /* Help strings */
23114 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23115   foreach_vpe_api_msg;
23116 #undef _
23117
23118   /* CLI functions */
23119 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23120   foreach_cli_function;
23121 #undef _
23122
23123   /* Help strings */
23124 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23125   foreach_cli_function;
23126 #undef _
23127 }
23128
23129 #if VPP_API_TEST_BUILTIN
23130 static clib_error_t *
23131 vat_api_hookup_shim (vlib_main_t * vm)
23132 {
23133   vat_api_hookup (&vat_main);
23134   return 0;
23135 }
23136
23137 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23138 #endif
23139
23140 /*
23141  * fd.io coding-style-patch-verification: ON
23142  *
23143  * Local Variables:
23144  * eval: (c-set-style "gnu")
23145  * End:
23146  */